You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2015/09/18 18:28:54 UTC

[1/2] cassandra git commit: Properly extract whether a legacy slice queries static columns

Repository: cassandra
Updated Branches:
  refs/heads/trunk 95ba0e21d -> 418ecb59a


Properly extract whether a legacy slice queries static columns

Pre-3.0 nodes were using the slices to query or not static columns. 3.0
handles this though the ColumnFilter (by explicitly asking for
static columns or not) and has no real way to do so through its slices.

The backward compatibility code was not handling this correctly: it was
generating the 3.0 slices from the pre-3.0 one somewhat blindly, and
then checking if said slices were including Clustering.STATIC. This
work most of the time because most query selecting static simply
started at Slice.Bound.BOTTOM which ended up selecting
Clustering.STATIC, but wasn't fully correct.

The patch makes sure we detect if static are selected when
deserializing the old slices.

The patch also fix a case of incorrect thrift limit in pagedRangeCommand

patch by slebresne & bdeggleston; reviewed by slebresne & bdeggleston for CASSANDRA-10267


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/762b48f2
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/762b48f2
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/762b48f2

Branch: refs/heads/trunk
Commit: 762b48f2de02497e97a31210b285eb6d39f236c1
Parents: 6e805ca
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Fri Sep 18 16:26:49 2015 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Fri Sep 18 18:27:25 2015 +0200

----------------------------------------------------------------------
 .../org/apache/cassandra/db/ReadCommand.java    | 80 +++++++++++++-------
 1 file changed, 53 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/762b48f2/src/java/org/apache/cassandra/db/ReadCommand.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ReadCommand.java b/src/java/org/apache/cassandra/db/ReadCommand.java
index d2e4bbc..3d08f17 100644
--- a/src/java/org/apache/cassandra/db/ReadCommand.java
+++ b/src/java/org/apache/cassandra/db/ReadCommand.java
@@ -791,10 +791,11 @@ public abstract class ReadCommand implements ReadQuery
             }
             else
             {
-                filter = LegacyReadCommandSerializer.deserializeSlicePartitionFilter(in, metadata);
+                Pair<ClusteringIndexSliceFilter, Boolean> p = LegacyReadCommandSerializer.deserializeSlicePartitionFilter(in, metadata);
+                filter = p.left;
                 perPartitionLimit = in.readInt();
                 compositesToGroup = in.readInt();
-                selection = getColumnSelectionForSlice((ClusteringIndexSliceFilter) filter, compositesToGroup, metadata);
+                selection = getColumnSelectionForSlice(p.right, compositesToGroup, metadata);
             }
 
             RowFilter rowFilter = deserializeRowFilter(in, metadata);
@@ -929,14 +930,14 @@ public abstract class ReadCommand implements ReadQuery
                     command.columnFilter(), command.rowFilter(), command.limits(), newRange, Optional.empty());
         }
 
-        static ColumnFilter getColumnSelectionForSlice(ClusteringIndexSliceFilter filter, int compositesToGroup, CFMetaData metadata)
+        static ColumnFilter getColumnSelectionForSlice(boolean selectsStatics, int compositesToGroup, CFMetaData metadata)
         {
             // A value of -2 indicates this is a DISTINCT query that doesn't select static columns, only partition keys.
             if (compositesToGroup == -2)
                 return ColumnFilter.selection(PartitionColumns.NONE);
 
             // if a slice query from a pre-3.0 node doesn't cover statics, we shouldn't select them at all
-            PartitionColumns columns = filter.selects(Clustering.STATIC_CLUSTERING)
+            PartitionColumns columns = selectsStatics
                                      ? metadata.partitionColumns()
                                      : metadata.partitionColumns().withoutStatics();
             return ColumnFilter.selectionBuilder().addAll(columns).build();
@@ -1039,27 +1040,28 @@ public abstract class ReadCommand implements ReadQuery
             int nowInSec = (int) (in.readLong() / 1000);  // convert from millis to seconds
             AbstractBounds<PartitionPosition> keyRange = AbstractBounds.rowPositionSerializer.deserialize(in, metadata.partitioner, version);
 
-            ClusteringIndexSliceFilter filter = LegacyReadCommandSerializer.deserializeSlicePartitionFilter(in, metadata);
+            Pair<ClusteringIndexSliceFilter, Boolean> p = LegacyReadCommandSerializer.deserializeSlicePartitionFilter(in, metadata);
+            ClusteringIndexSliceFilter filter = p.left;
+            boolean selectsStatics = p.right;
+
             int perPartitionLimit = in.readInt();
             int compositesToGroup = in.readInt();
 
             // command-level Composite "start" and "stop"
             LegacyLayout.LegacyBound startBound = LegacyLayout.decodeBound(metadata, ByteBufferUtil.readWithShortLength(in), true);
+
             ByteBufferUtil.readWithShortLength(in);  // the composite "stop", which isn't actually needed
 
-            ColumnFilter selection = LegacyRangeSliceCommandSerializer.getColumnSelectionForSlice(filter, compositesToGroup, metadata);
+            ColumnFilter selection = LegacyRangeSliceCommandSerializer.getColumnSelectionForSlice(selectsStatics, compositesToGroup, metadata);
 
             RowFilter rowFilter = LegacyRangeSliceCommandSerializer.deserializeRowFilter(in, metadata);
             int maxResults = in.readInt();
             in.readBoolean(); // countCQL3Rows
 
-            boolean selectsStatics = (!selection.fetchedColumns().statics.isEmpty() || filter.selects(Clustering.STATIC_CLUSTERING));
             boolean isDistinct = compositesToGroup == -2 || (perPartitionLimit == 1 && selectsStatics);
             DataLimits limits;
             if (isDistinct)
                 limits = DataLimits.distinctLimits(maxResults);
-            else if (compositesToGroup == -1)
-                limits = DataLimits.thriftLimits(1, perPartitionLimit); // we only use paging w/ thrift for get_count(), so partition limit must be 1
             else
                 limits = DataLimits.cqlLimits(maxResults);
 
@@ -1354,16 +1356,14 @@ public abstract class ReadCommand implements ReadQuery
 
         private SinglePartitionSliceCommand deserializeSliceCommand(DataInputPlus in, boolean isDigest, CFMetaData metadata, DecoratedKey key, int nowInSeconds, int version) throws IOException
         {
-            ClusteringIndexSliceFilter filter = deserializeSlicePartitionFilter(in, metadata);
+            Pair<ClusteringIndexSliceFilter, Boolean> p = deserializeSlicePartitionFilter(in, metadata);
+            ClusteringIndexSliceFilter filter = p.left;
+            boolean selectsStatics = p.right;
             int count = in.readInt();
             int compositesToGroup = in.readInt();
 
             // if a slice query from a pre-3.0 node doesn't cover statics, we shouldn't select them at all
-            boolean selectsStatics = filter.selects(Clustering.STATIC_CLUSTERING);
-            PartitionColumns columns = selectsStatics
-                                     ? metadata.partitionColumns()
-                                     : metadata.partitionColumns().withoutStatics();
-            ColumnFilter columnFilter = ColumnFilter.selectionBuilder().addAll(columns).build();
+            ColumnFilter columnFilter = LegacyRangeSliceCommandSerializer.getColumnSelectionForSlice(selectsStatics, compositesToGroup, metadata);
 
             boolean isDistinct = compositesToGroup == -2 || (count == 1 && selectsStatics);
             DataLimits limits;
@@ -1484,7 +1484,9 @@ public abstract class ReadCommand implements ReadQuery
             }
         }
 
-        static ClusteringIndexSliceFilter deserializeSlicePartitionFilter(DataInputPlus in, CFMetaData metadata) throws IOException
+        // Returns the deserialized filter, and whether static columns are queried (in pre-3.0, both info are determined by the slices,
+        // but in 3.0 they are separated: whether static columns are queried or not depends on the ColumnFilter).
+        static Pair<ClusteringIndexSliceFilter, Boolean> deserializeSlicePartitionFilter(DataInputPlus in, CFMetaData metadata) throws IOException
         {
             int numSlices = in.readInt();
             ByteBuffer[] startBuffers = new ByteBuffer[numSlices];
@@ -1495,28 +1497,52 @@ public abstract class ReadCommand implements ReadQuery
                 finishBuffers[i] = ByteBufferUtil.readWithShortLength(in);
             }
 
-            // we have to know if the query is reversed before we can correctly build the slices
             boolean reversed = in.readBoolean();
 
+            if (reversed)
+            {
+                // pre-3.0, reversed query slices put the greater element at the start of the slice
+                ByteBuffer[] tmp = finishBuffers;
+                finishBuffers = startBuffers;
+                startBuffers = tmp;
+            }
+
+            boolean selectsStatics = false;
             Slices.Builder slicesBuilder = new Slices.Builder(metadata.comparator);
             for (int i = 0; i < numSlices; i++)
             {
-                Slice.Bound start, finish;
-                if (!reversed)
+                LegacyLayout.LegacyBound start = LegacyLayout.decodeBound(metadata, startBuffers[i], true);
+                LegacyLayout.LegacyBound finish = LegacyLayout.decodeBound(metadata, finishBuffers[i], false);
+
+                if (start.isStatic)
                 {
-                    start = LegacyLayout.decodeBound(metadata, startBuffers[i], true).bound;
-                    finish = LegacyLayout.decodeBound(metadata, finishBuffers[i], false).bound;
+                    // If we start at the static block, this means we start at the beginning of the partition in 3.0
+                    // terms (since 3.0 handles static outside of the slice).
+                    start = LegacyLayout.LegacyBound.BOTTOM;
+
+                    // Then if we include the static, records it
+                    if (start.bound.isInclusive())
+                        selectsStatics = true;
                 }
-                else
+                else if (start == LegacyLayout.LegacyBound.BOTTOM)
                 {
-                    // pre-3.0, reversed query slices put the greater element at the start of the slice
-                    finish = LegacyLayout.decodeBound(metadata, startBuffers[i], false).bound;
-                    start = LegacyLayout.decodeBound(metadata, finishBuffers[i], true).bound;
+                    selectsStatics = true;
                 }
-                slicesBuilder.add(Slice.make(start, finish));
+
+                // If the end of the slice is the end of the statics, then that mean this slice was just selecting static
+                // columns. We have already recorded that in selectsStatics, so we can ignore the slice (which doesn't make
+                // sense for 3.0).
+                if (finish.isStatic)
+                {
+                    assert finish.bound.isInclusive(); // it would make no sense for a pre-3.0 node to have a slice that stops
+                                                     // before the static columns (since there is nothing before that)
+                    continue;
+                }
+
+                slicesBuilder.add(Slice.make(start.bound, finish.bound));
             }
 
-            return new ClusteringIndexSliceFilter(slicesBuilder.build(), reversed);
+            return Pair.create(new ClusteringIndexSliceFilter(slicesBuilder.build(), reversed), selectsStatics);
         }
 
         private static SinglePartitionReadCommand maybeConvertNamesToSlice(SinglePartitionReadCommand command)


[2/2] cassandra git commit: Merge branch 'cassandra-3.0' into trunk

Posted by sl...@apache.org.
Merge branch 'cassandra-3.0' into trunk


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/418ecb59
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/418ecb59
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/418ecb59

Branch: refs/heads/trunk
Commit: 418ecb59ae8cf159c00c2d15c10b5aece03119dc
Parents: 95ba0e2 762b48f
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Fri Sep 18 18:28:40 2015 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Fri Sep 18 18:28:40 2015 +0200

----------------------------------------------------------------------
 .../org/apache/cassandra/db/ReadCommand.java    | 80 +++++++++++++-------
 1 file changed, 53 insertions(+), 27 deletions(-)
----------------------------------------------------------------------