You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by al...@apache.org on 2017/09/30 09:36:47 UTC
[2/2] cassandra git commit: Fix ISE thrown by
UPI.Serializer.hasNext() for some SELECT queries
Fix ISE thrown by UPI.Serializer.hasNext() for some SELECT queries
patch by Aleksey Yeschenko; reviewed by Sam Tunnicliffe for
CASSANDRA-13911
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/1efdf330
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/1efdf330
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/1efdf330
Branch: refs/heads/cassandra-3.0
Commit: 1efdf330e291a41cd8051e0c1195f75b5d352370
Parents: 95839aa
Author: Aleksey Yeschenko <al...@yeschenko.com>
Authored: Thu Sep 28 17:41:00 2017 +0100
Committer: Aleksey Yeschenko <al...@yeschenko.com>
Committed: Sat Sep 30 10:33:30 2017 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../partitions/UnfilteredPartitionIterators.java | 19 +++++++++++++++----
.../apache/cassandra/service/DataResolver.java | 9 +++++++--
3 files changed, 23 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1efdf330/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 7ff61d3..1c53aa5 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
3.0.15
+ * Fix ISE thrown by UPI.Serializer.hasNext() for some SELECT queries (CASSANDRA-13911)
* Filter header only commit logs before recovery (CASSANDRA-13918)
* AssertionError prepending to a list (CASSANDRA-13149)
* Fix support for SuperColumn tables (CASSANDRA-12373)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1efdf330/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java b/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java
index 4e0ac1b..efe3ff8 100644
--- a/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java
+++ b/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java
@@ -324,10 +324,21 @@ public abstract class UnfilteredPartitionIterators
if (!nextReturned)
return hasNext;
- // We can't answer this until the previously returned iterator has been fully consumed,
- // so complain if that's not the case.
- if (next != null && next.hasNext())
- throw new IllegalStateException("Cannot call hasNext() until the previous iterator has been fully consumed");
+ /*
+ * We must consume the previous iterator before we start deserializing the next partition, so
+ * that we start from the right position in the byte stream.
+ *
+ * It's possible however that it hasn't been fully consumed by upstream consumers - for example,
+ * if a per partition limit caused merge iterator to stop early (see CASSANDRA-13911).
+ *
+ * In that case we must drain the unconsumed iterator fully ourselves, here.
+ *
+ * NOTE: transformations of the upstream BaseRows won't be applied for these consumed elements,
+ * so, for exmaple, they won't be counted.
+ */
+ if (null != next)
+ while (next.hasNext())
+ next.next();
try
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1efdf330/src/java/org/apache/cassandra/service/DataResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/DataResolver.java b/src/java/org/apache/cassandra/service/DataResolver.java
index 61bffe5..7d8ffc5 100644
--- a/src/java/org/apache/cassandra/service/DataResolver.java
+++ b/src/java/org/apache/cassandra/service/DataResolver.java
@@ -550,8 +550,13 @@ public class DataResolver extends ResponseResolver
// we do not apply short read protection when we have no limits at all
assert !command.limits().isUnlimited();
- // if the returned partition doesn't have enough rows to satisfy even the original limit, don't ask for more
- if (!singleResultCounter.isDoneForPartition())
+ /*
+ * If the returned partition doesn't have enough rows to satisfy even the original limit, don't ask for more.
+ *
+ * Can only take the short cut if there is no per partition limit set. Otherwise it's possible to hit false
+ * positives due to some rows being uncounted for in certain scenarios (see CASSANDRA-13911).
+ */
+ if (!singleResultCounter.isDoneForPartition() && command.limits().perPartitionCount() == DataLimits.NO_LIMIT)
return null;
/*
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org