Merge branch 'cassandra-2.0' into trunk

Conflicts:
        src/java/org/apache/cassandra/cql3/statements/SelectStatement.java


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

Branch: refs/heads/trunk
Commit: c36656c06bc10bccace324d40adc7d038de2f74f
Parents: 5b0eb01 44f9c86
Author: Sylvain Lebresne <sylv...@datastax.com>
Authored: Fri Feb 14 13:52:57 2014 +0100
Committer: Sylvain Lebresne <sylv...@datastax.com>
Committed: Fri Feb 14 13:52:57 2014 +0100

----------------------------------------------------------------------
 CHANGES.txt                                                  | 1 +
 .../apache/cassandra/cql3/statements/SelectStatement.java    | 8 +++++---
 2 files changed, 6 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/c36656c0/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 42c8bd9,57eefac..d08cb93
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -56,8 -21,8 +56,9 @@@ Merged from 1.2
   * Log USING TTL/TIMESTAMP in a counter update warning (CASSANDRA-6649)
   * Don't exchange schema between nodes with different versions 
(CASSANDRA-6695)
   * Use real node messaging versions for schema exchange decisions 
(CASSANDRA-6700)
+  * IN on the last clustering columns + ORDER BY DESC yield no results 
(CASSANDRA-6701)
  
 +
  2.0.5
   * Reduce garbage generated by bloom filter lookups (CASSANDRA-6609)
   * Add ks.cf names to tombstone logging (CASSANDRA-6597)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c36656c0/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index 3bf5906,307e668..60d13f4
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@@ -694,12 -706,12 +694,12 @@@ public class SelectStatement implement
                      for (ByteBuffer val : values)
                      {
                          if (val == null)
 -                            throw new 
InvalidRequestException(String.format("Invalid null clustering key part %s", 
name));
 -                        ColumnNameBuilder copy = builder.copy().add(val);
 +                            throw new 
InvalidRequestException(String.format("Invalid null clustering key part %s", 
def.name));
 +                        Composite prefix = builder.buildWith(val);
                          // See below for why this
-                         s.add((bound == Bound.END && builder.remainingCount() 
> 0) ? prefix.end() : prefix);
 -                        s.add((b == Bound.END && copy.remainingCount() > 0) ? 
copy.buildAsEndOfRange() : copy.build());
++                        s.add((b == Bound.END && builder.remainingCount() > 
0) ? prefix.end() : prefix);
                      }
 -                    return new ArrayList<ByteBuffer>(s);
 +                    return new ArrayList<Composite>(s);
                  }
  
                  ByteBuffer val = values.get(0);
@@@ -947,64 -986,70 +947,66 @@@
  
          assert orderingIndexes != null;
  
 -        // optimization when only *one* order condition was given
 -        // because there is no point of using composite comparator if there 
is only one order condition
 -        if (parameters.orderings.size() == 1)
 +        List<Integer> idToSort = new ArrayList<Integer>();
 +        List<Comparator<ByteBuffer>> sorters = new 
ArrayList<Comparator<ByteBuffer>>();
 +
 +        // If the restriction for the last clustering key is an IN, respect 
requested order
 +        if (lastClusteringIsIn)
          {
 -            CFDefinition.Name ordering = 
cfDef.get(parameters.orderings.keySet().iterator().next());
 -            Collections.sort(cqlRows.rows, new 
SingleColumnComparator(orderingIndexes.get(ordering), ordering.type));
 -            return;
 +            List<ColumnDefinition> cc = cfm.clusteringColumns();
 +            idToSort.add(orderingIndexes.get(cc.get(cc.size() - 1).name));
 +            Restriction last = columnRestrictions[columnRestrictions.length - 
1];
-             sorters.add(makeComparatorFor(last.values(variables)));
++            sorters.add(makeComparatorFor(last.values(variables), 
isReversed));
          }
  
 -        // builds a 'composite' type for multi-column comparison from the 
comparators of the ordering components
 -        // and passes collected position information and built composite 
comparator to CompositeComparator to do
 -        // an actual comparison of the CQL rows.
 -        List<AbstractType<?>> types = new 
ArrayList<AbstractType<?>>(parameters.orderings.size());
 -        int[] positions = new int[parameters.orderings.size()];
 -
 -        int idx = 0;
 +        // Then add the order by
          for (ColumnIdentifier identifier : parameters.orderings.keySet())
          {
 -            CFDefinition.Name orderingColumn = cfDef.get(identifier);
 -            types.add(orderingColumn.type);
 -            positions[idx++] = orderingIndexes.get(orderingColumn);
 +            ColumnDefinition orderingColumn = 
cfm.getColumnDefinition(identifier);
 +            idToSort.add(orderingIndexes.get(orderingColumn.name));
 +            sorters.add(orderingColumn.type);
          }
  
 -        Collections.sort(cqlRows.rows, new CompositeComparator(types, 
positions));
 +        Comparator<List<ByteBuffer>> comparator = idToSort.size() == 1
 +                                                ? new 
SingleColumnComparator(idToSort.get(0), sorters.get(0))
 +                                                : new 
CompositeComparator(sorters, idToSort);
 +        Collections.sort(cqlRows.rows, comparator);
      }
  
 -    private void handleGroup(Selection selection, Selection.ResultSetBuilder 
result, ByteBuffer[] keyComponents, ColumnGroupMap columns) throws 
InvalidRequestException
 +    // Comparator used when the last clustering key is an IN, to sort result
 +    // rows in the order of the values provided for the IN.
-     private Comparator<ByteBuffer> makeComparatorFor(final List<ByteBuffer> 
values)
++    private Comparator<ByteBuffer> makeComparatorFor(final List<ByteBuffer> 
vals, final boolean isReversed)
      {
 -        // Respect requested order
 -        result.newRow();
 -        for (CFDefinition.Name name : selection.getColumnsList())
 +        // This may not always be the most efficient, but it probably is if
 +        // values is small, which is likely to be the most common case.
 +        return new Comparator<ByteBuffer>()
          {
 -            switch (name.kind)
++            private final List<ByteBuffer> values = isReversed ? 
com.google.common.collect.Lists.reverse(vals) : vals;
++
 +            public int compare(ByteBuffer b1, ByteBuffer b2)
              {
 -                case KEY_ALIAS:
 -                    result.add(keyComponents[name.position]);
 -                    break;
 -                case COLUMN_ALIAS:
 -                    result.add(columns.getKeyComponent(name.position));
 -                    break;
 -                case VALUE_ALIAS:
 -                    // This should not happen for SPARSE
 -                    throw new AssertionError();
 -                case COLUMN_METADATA:
 -                    if (name.type.isCollection())
 -                    {
 -                        List<Pair<ByteBuffer, Column>> collection = 
columns.getCollection(name.name.key);
 -                        ByteBuffer value = collection == null
 -                                         ? null
 -                                         : 
((CollectionType)name.type).serialize(collection);
 -                        result.add(value);
 -                    }
 -                    else
 -                    {
 -                        result.add(columns.getSimple(name.name.key));
 -                    }
 -                    break;
 +                int idx1 = -1;
 +                int idx2 = -1;
 +                for (int i = 0; i < values.size(); i++)
 +                {
 +                    ByteBuffer bb = values.get(i);
 +                    if (bb.equals(b1))
 +                        idx1 = i;
 +                    if (bb.equals(b2))
 +                        idx2 = i;
 +
 +                    if (idx1 >= 0 && idx2 >= 0)
 +                        break;
 +                }
 +                assert idx1 >= 0 && idx2 >= 0 : "Got CQL3 row that was not 
queried in resultset";
 +                return idx1 - idx2;
              }
 -        }
 +        };
      }
  
 -    private static boolean isReversedType(CFDefinition.Name name)
 +    private static boolean isReversedType(ColumnDefinition def)
      {
 -        return name.type instanceof ReversedType;
 +        return def.type instanceof ReversedType;
      }
  
      private boolean columnFilterIsIdentity()

Reply via email to