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 2014/04/02 20:32:55 UTC

[1/4] git commit: Fix unintended update with conditional statement

Repository: cassandra
Updated Branches:
  refs/heads/trunk 500503d6d -> 5b85be04c


Fix unintended update with conditional statement

patch by slebresne; reviewed by iamaleksey for CASSANDRA-6893


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

Branch: refs/heads/trunk
Commit: 167380fb0d7fa3fc6dc9879c839419babaea2a16
Parents: b218536
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Wed Apr 2 19:49:16 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Wed Apr 2 19:49:16 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../apache/cassandra/cql3/ColumnCondition.java  | 198 ++++++++++---------
 .../cql3/statements/CQL3CasConditions.java      |  11 +-
 3 files changed, 114 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/167380fb/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 3cc9937..66196d0 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -41,6 +41,7 @@
  * Fix clash with CQL column name in thrift validation (CASSANDRA-6892)
  * Fix error with super columns in mixed 1.2-2.0 clusters (CASSANDRA-6966)
  * Fix bad skip of sstables on slice query with composite start/finish (CASSANDRA-6825)
+ * Fix unintended update with conditional statement (CASSANDRA-6893)
 Merged from 1.2:
  * Add UNLOGGED, COUNTER options to BATCH documentation (CASSANDRA-6816)
  * add extra SSL cipher suites (CASSANDRA-6613)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/167380fb/src/java/org/apache/cassandra/cql3/ColumnCondition.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/ColumnCondition.java b/src/java/org/apache/cassandra/cql3/ColumnCondition.java
index ce44c3b..0ebd4af 100644
--- a/src/java/org/apache/cassandra/cql3/ColumnCondition.java
+++ b/src/java/org/apache/cassandra/cql3/ColumnCondition.java
@@ -39,8 +39,6 @@ public class ColumnCondition
     public final CFDefinition.Name column;
     private final Term value;
 
-    private List<ByteBuffer> variables;
-
     private ColumnCondition(CFDefinition.Name column, Term value)
     {
         this.column = column;
@@ -53,13 +51,6 @@ public class ColumnCondition
         return new ColumnCondition(column, value);
     }
 
-    // See CQL3CasConditions for why it's convenient to have this
-    public ColumnCondition attach(List<ByteBuffer> variables)
-    {
-        this.variables = variables;
-        return this;
-    }
-
     /**
      * Collects the column specification for the bind variables of this operation.
      *
@@ -71,109 +62,134 @@ public class ColumnCondition
         value.collectMarkerSpecification(boundNames);
     }
 
-    // Not overriding equals() because we need the variables to have been attached when this is
-    // called and so having a non standard method name might help avoid mistakes
-    public boolean equalsTo(ColumnCondition other) throws InvalidRequestException
+    public ColumnCondition.WithVariables with(List<ByteBuffer> variables)
     {
-        return column.equals(other.column)
-            && value.bindAndGet(variables).equals(other.value.bindAndGet(other.variables));
+        return new WithVariables(variables);
     }
 
-    private ColumnNameBuilder copyOrUpdatePrefix(CFMetaData cfm, ColumnNameBuilder rowPrefix)
+    public class WithVariables
     {
-        return column.kind == CFDefinition.Name.Kind.STATIC ? cfm.getStaticColumnNameBuilder() : rowPrefix.copy();
-    }
+        private final List<ByteBuffer> variables;
 
-    /**
-     * Validates whether this condition applies to {@code current}.
-     */
-    public boolean appliesTo(ColumnNameBuilder rowPrefix, ColumnFamily current, long now) throws InvalidRequestException
-    {
-        if (column.type instanceof CollectionType)
-            return collectionAppliesTo((CollectionType)column.type, rowPrefix, current, now);
-
-        ColumnNameBuilder prefix = copyOrUpdatePrefix(current.metadata(), rowPrefix);
-        ByteBuffer columnName = column.kind == CFDefinition.Name.Kind.VALUE_ALIAS
-                              ? prefix.build()
-                              : prefix.add(column.name.key).build();
-
-        Column c = current.getColumn(columnName);
-        ByteBuffer v = value.bindAndGet(variables);
-        return v == null
-             ? c == null || !c.isLive(now)
-             : c != null && c.isLive(now) && c.value().equals(v);
-    }
+        private WithVariables(List<ByteBuffer> variables)
+        {
+            this.variables = variables;
+        }
 
-    private boolean collectionAppliesTo(CollectionType type, ColumnNameBuilder rowPrefix, ColumnFamily current, final long now) throws InvalidRequestException
-    {
-        ColumnNameBuilder collectionPrefix = copyOrUpdatePrefix(current.metadata(), rowPrefix).add(column.name.key);
-        // We are testing for collection equality, so we need to have the expected values *and* only those.
-        ColumnSlice[] collectionSlice = new ColumnSlice[]{ new ColumnSlice(collectionPrefix.build(), collectionPrefix.buildAsEndOfRange()) };
-        // Filter live columns, this makes things simpler afterwards
-        Iterator<Column> iter = Iterators.filter(current.iterator(collectionSlice), new Predicate<Column>()
+        // Not overriding equals() because we need the variables to have been attached when this is
+        // called and so having a non standard method name might help avoid mistakes
+        public boolean equalsTo(WithVariables other) throws InvalidRequestException
         {
-            public boolean apply(Column c)
-            {
-                // we only care about live columns
-                return c.isLive(now);
-            }
-        });
+            return column.equals(other.column())
+                && value.bindAndGet(variables).equals(other.value().bindAndGet(other.variables));
+        }
 
-        Term.Terminal v = value.bind(variables);
-        if (v == null)
-            return !iter.hasNext();
+        private CFDefinition.Name column()
+        {
+            return column;
+        }
 
-        switch (type.kind)
+        private Term value()
         {
-            case LIST: return listAppliesTo(current.metadata(), iter, ((Lists.Value)v).elements);
-            case SET: return setAppliesTo(current.metadata(), iter, ((Sets.Value)v).elements);
-            case MAP: return mapAppliesTo(current.metadata(), iter, ((Maps.Value)v).map);
+            return value;
         }
-        throw new AssertionError();
-    }
 
-    private static ByteBuffer collectionKey(CFMetaData cfm, Column c)
-    {
-        ByteBuffer[] bbs = ((CompositeType)cfm.comparator).split(c.name());
-        return bbs[bbs.length - 1];
-    }
+        private ColumnNameBuilder copyOrUpdatePrefix(CFMetaData cfm, ColumnNameBuilder rowPrefix)
+        {
+            return column.kind == CFDefinition.Name.Kind.STATIC ? cfm.getStaticColumnNameBuilder() : rowPrefix.copy();
+        }
 
-    private boolean listAppliesTo(CFMetaData cfm, Iterator<Column> iter, List<ByteBuffer> elements)
-    {
-        for (ByteBuffer e : elements)
-            if (!iter.hasNext() || iter.next().value().equals(e))
-                return false;
-        // We must not have more elements than expected
-        return !iter.hasNext();
-    }
+        /**
+         * Validates whether this condition applies to {@code current}.
+         */
+        public boolean appliesTo(ColumnNameBuilder rowPrefix, ColumnFamily current, long now) throws InvalidRequestException
+        {
+            if (column.type instanceof CollectionType)
+                return collectionAppliesTo((CollectionType)column.type, rowPrefix, current, now);
+
+            ColumnNameBuilder prefix = copyOrUpdatePrefix(current.metadata(), rowPrefix);
+            ByteBuffer columnName = column.kind == CFDefinition.Name.Kind.VALUE_ALIAS
+                                  ? prefix.build()
+                                  : prefix.add(column.name.key).build();
+
+            Column c = current.getColumn(columnName);
+            ByteBuffer v = value.bindAndGet(variables);
+            return v == null
+                 ? c == null || !c.isLive(now)
+                 : c != null && c.isLive(now) && column.type.compare(c.value(), v) == 0;
+        }
 
-    private boolean setAppliesTo(CFMetaData cfm, Iterator<Column> iter, Set<ByteBuffer> elements)
-    {
-        Set<ByteBuffer> remaining = new HashSet<>(elements);
-        while (iter.hasNext())
+        private boolean collectionAppliesTo(CollectionType type, ColumnNameBuilder rowPrefix, ColumnFamily current, final long now) throws InvalidRequestException
         {
-            if (remaining.isEmpty())
-                return false;
+            ColumnNameBuilder collectionPrefix = copyOrUpdatePrefix(current.metadata(), rowPrefix).add(column.name.key);
+            // We are testing for collection equality, so we need to have the expected values *and* only those.
+            ColumnSlice[] collectionSlice = new ColumnSlice[]{ new ColumnSlice(collectionPrefix.build(), collectionPrefix.buildAsEndOfRange()) };
+            // Filter live columns, this makes things simpler afterwards
+            Iterator<Column> iter = Iterators.filter(current.iterator(collectionSlice), new Predicate<Column>()
+            {
+                public boolean apply(Column c)
+                {
+                    // we only care about live columns
+                    return c.isLive(now);
+                }
+            });
+
+            Term.Terminal v = value.bind(variables);
+            if (v == null)
+                return !iter.hasNext();
+
+            switch (type.kind)
+            {
+                case LIST: return listAppliesTo(current.metadata(), iter, ((Lists.Value)v).elements);
+                case SET: return setAppliesTo(current.metadata(), iter, ((Sets.Value)v).elements);
+                case MAP: return mapAppliesTo(current.metadata(), iter, ((Maps.Value)v).map);
+            }
+            throw new AssertionError();
+        }
 
-            if (!remaining.remove(collectionKey(cfm, iter.next())))
-                return false;
+        private ByteBuffer collectionKey(CFMetaData cfm, Column c)
+        {
+            ByteBuffer[] bbs = ((CompositeType)cfm.comparator).split(c.name());
+            return bbs[bbs.length - 1];
         }
-        return remaining.isEmpty();
-    }
 
-    private boolean mapAppliesTo(CFMetaData cfm, Iterator<Column> iter, Map<ByteBuffer, ByteBuffer> elements)
-    {
-        Map<ByteBuffer, ByteBuffer> remaining = new HashMap<>(elements);
-        while (iter.hasNext())
+        private boolean listAppliesTo(CFMetaData cfm, Iterator<Column> iter, List<ByteBuffer> elements)
         {
-            if (remaining.isEmpty())
-                return false;
+            for (ByteBuffer e : elements)
+                if (!iter.hasNext() || !iter.next().value().equals(e))
+                    return false;
+            // We must not have more elements than expected
+            return !iter.hasNext();
+        }
+
+        private boolean setAppliesTo(CFMetaData cfm, Iterator<Column> iter, Set<ByteBuffer> elements)
+        {
+            Set<ByteBuffer> remaining = new HashSet<>(elements);
+            while (iter.hasNext())
+            {
+                if (remaining.isEmpty())
+                    return false;
 
-            Column c = iter.next();
-            if (!remaining.remove(collectionKey(cfm, c)).equals(c.value()))
-                return false;
+                if (!remaining.remove(collectionKey(cfm, iter.next())))
+                    return false;
+            }
+            return remaining.isEmpty();
+        }
+
+        private boolean mapAppliesTo(CFMetaData cfm, Iterator<Column> iter, Map<ByteBuffer, ByteBuffer> elements)
+        {
+            Map<ByteBuffer, ByteBuffer> remaining = new HashMap<>(elements);
+            while (iter.hasNext())
+            {
+                if (remaining.isEmpty())
+                    return false;
+
+                Column c = iter.next();
+                if (!remaining.remove(collectionKey(cfm, c)).equals(c.value()))
+                    return false;
+            }
+            return remaining.isEmpty();
         }
-        return remaining.isEmpty();
     }
 
     public static class Raw

http://git-wip-us.apache.org/repos/asf/cassandra/blob/167380fb/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java b/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
index a7ec8d4..7d3c0f7 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
@@ -166,7 +166,7 @@ public class CQL3CasConditions implements CASConditions
 
     private static class ColumnsConditions extends RowCondition
     {
-        private final Map<ColumnIdentifier, ColumnCondition> conditions = new HashMap<>();
+        private final Map<ColumnIdentifier, ColumnCondition.WithVariables> conditions = new HashMap<>();
 
         private ColumnsConditions(ColumnNameBuilder rowPrefix, long now)
         {
@@ -178,10 +178,11 @@ public class CQL3CasConditions implements CASConditions
             for (ColumnCondition condition : conds)
             {
                 // We will need the variables in appliesTo but with protocol batches, each condition in this object can have a
-                // different list of variables. So attach them to the condition directly, it's not particulary elegant but its simpler
-                ColumnCondition previous = conditions.put(condition.column.name, condition.attach(variables));
+                // different list of variables.
+                ColumnCondition.WithVariables current = condition.with(variables);
+                ColumnCondition.WithVariables previous = conditions.put(condition.column.name, current);
                 // If 2 conditions are actually equal, let it slide
-                if (previous != null && !previous.equalsTo(condition))
+                if (previous != null && !previous.equalsTo(current))
                     throw new InvalidRequestException("Duplicate and incompatible conditions for column " + condition.column.name);
             }
         }
@@ -191,7 +192,7 @@ public class CQL3CasConditions implements CASConditions
             if (current == null)
                 return conditions.isEmpty();
 
-            for (ColumnCondition condition : conditions.values())
+            for (ColumnCondition.WithVariables condition : conditions.values())
                 if (!condition.appliesTo(rowPrefix, current, now))
                     return false;
             return true;


[4/4] git commit: Merge branch 'cassandra-2.1' into trunk

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


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

Branch: refs/heads/trunk
Commit: 5b85be04cbf49e306cd43563ee85652484179812
Parents: 500503d f7e690d
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Wed Apr 2 20:32:49 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Wed Apr 2 20:32:49 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../apache/cassandra/cql3/ColumnCondition.java  | 176 ++++++++++---------
 .../cql3/statements/CQL3CasConditions.java      |  11 +-
 3 files changed, 104 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/5b85be04/CHANGES.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5b85be04/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
----------------------------------------------------------------------


[3/4] git commit: Merge branch 'cassandra-2.0' into cassandra-2.1

Posted by sl...@apache.org.
Merge branch 'cassandra-2.0' into cassandra-2.1

Conflicts:
	src/java/org/apache/cassandra/cql3/ColumnCondition.java


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

Branch: refs/heads/trunk
Commit: f7e690d7f0298c7fb47036f2ec6051df733cd145
Parents: ab1a02c 17278b3
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Wed Apr 2 20:32:26 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Wed Apr 2 20:32:26 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../apache/cassandra/cql3/ColumnCondition.java  | 176 ++++++++++---------
 .../cql3/statements/CQL3CasConditions.java      |  11 +-
 3 files changed, 104 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f7e690d7/CHANGES.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f7e690d7/src/java/org/apache/cassandra/cql3/ColumnCondition.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/ColumnCondition.java
index 520858f,e6cdf43..64c2032
--- a/src/java/org/apache/cassandra/cql3/ColumnCondition.java
+++ b/src/java/org/apache/cassandra/cql3/ColumnCondition.java
@@@ -23,13 -23,10 +23,12 @@@ import java.util.*
  import com.google.common.base.Predicate;
  import com.google.common.collect.Iterators;
  
 -import org.apache.cassandra.config.CFMetaData;
 +import org.apache.cassandra.config.ColumnDefinition;
  import org.apache.cassandra.db.*;
 +import org.apache.cassandra.db.composites.CellName;
 +import org.apache.cassandra.db.composites.Composite;
  import org.apache.cassandra.db.filter.ColumnSlice;
- import org.apache.cassandra.db.marshal.CollectionType;
- import org.apache.cassandra.db.marshal.CounterColumnType;
+ import org.apache.cassandra.db.marshal.*;
  import org.apache.cassandra.exceptions.InvalidRequestException;
  
  /**
@@@ -37,12 -34,10 +36,10 @@@
   */
  public class ColumnCondition
  {
 -    public final CFDefinition.Name column;
 +    public final ColumnDefinition column;
      private final Term value;
  
-     private List<ByteBuffer> variables;
- 
 -    private ColumnCondition(CFDefinition.Name column, Term value)
 +    private ColumnCondition(ColumnDefinition column, Term value)
      {
          this.column = column;
          this.value = value;
@@@ -72,93 -60,137 +62,121 @@@
          value.collectMarkerSpecification(boundNames);
      }
  
-     // Not overriding equals() because we need the variables to have been attached when this is
-     // called and so having a non standard method name might help avoid mistakes
-     public boolean equalsTo(ColumnCondition other) throws InvalidRequestException
+     public ColumnCondition.WithVariables with(List<ByteBuffer> variables)
      {
-         return column.equals(other.column)
-             && value.bindAndGet(variables).equals(other.value.bindAndGet(other.variables));
+         return new WithVariables(variables);
      }
  
-     /**
-      * Validates whether this condition applies to {@code current}.
-      */
-     public boolean appliesTo(Composite rowPrefix, ColumnFamily current, long now) throws InvalidRequestException
+     public class WithVariables
      {
-         if (column.type instanceof CollectionType)
-             return collectionAppliesTo((CollectionType)column.type, rowPrefix, current, now);
- 
-         Cell c = current.getColumn(current.metadata().comparator.create(rowPrefix, column));
-         ByteBuffer v = value.bindAndGet(variables);
-         return v == null
-              ? c == null || !c.isLive(now)
-              : c != null && c.isLive(now) && c.value().equals(v);
-     }
+         private final List<ByteBuffer> variables;
  
-     private boolean collectionAppliesTo(CollectionType type, Composite rowPrefix, ColumnFamily current, final long now) throws InvalidRequestException
-     {
-         CellName name = current.metadata().comparator.create(rowPrefix, column);
-         // We are testing for collection equality, so we need to have the expected values *and* only those.
-         ColumnSlice[] collectionSlice = new ColumnSlice[]{ name.slice() };
-         // Filter live columns, this makes things simpler afterwards
-         Iterator<Cell> iter = Iterators.filter(current.iterator(collectionSlice), new Predicate<Cell>()
+         private WithVariables(List<ByteBuffer> variables)
          {
-             public boolean apply(Cell c)
-             {
-                 // we only care about live columns
-                 return c.isLive(now);
-             }
-         });
+             this.variables = variables;
+         }
  
-         Term.Terminal v = value.bind(variables);
-         if (v == null)
-             return !iter.hasNext();
+         // Not overriding equals() because we need the variables to have been attached when this is
+         // called and so having a non standard method name might help avoid mistakes
+         public boolean equalsTo(WithVariables other) throws InvalidRequestException
+         {
+             return column.equals(other.column())
+                 && value.bindAndGet(variables).equals(other.value().bindAndGet(other.variables));
+         }
  
-         switch (type.kind)
 -        private CFDefinition.Name column()
++        private ColumnDefinition column()
          {
-             case LIST: return listAppliesTo(iter, ((Lists.Value)v).elements);
-             case SET: return setAppliesTo(iter, ((Sets.Value)v).elements);
-             case MAP: return mapAppliesTo(iter, ((Maps.Value)v).map);
+             return column;
          }
-         throw new AssertionError();
-     }
  
-     private boolean listAppliesTo(Iterator<Cell> iter, List<ByteBuffer> elements)
-     {
-         for (ByteBuffer e : elements)
-             if (!iter.hasNext() || iter.next().value().equals(e))
-                 return false;
-         // We must not have more elements than expected
-         return !iter.hasNext();
-     }
+         private Term value()
+         {
+             return value;
+         }
  
-     private boolean setAppliesTo(Iterator<Cell> iter, Set<ByteBuffer> elements)
-     {
-         Set<ByteBuffer> remaining = new HashSet<>(elements);
-         while (iter.hasNext())
 -        private ColumnNameBuilder copyOrUpdatePrefix(CFMetaData cfm, ColumnNameBuilder rowPrefix)
 -        {
 -            return column.kind == CFDefinition.Name.Kind.STATIC ? cfm.getStaticColumnNameBuilder() : rowPrefix.copy();
 -        }
 -
+         /**
+          * Validates whether this condition applies to {@code current}.
+          */
 -        public boolean appliesTo(ColumnNameBuilder rowPrefix, ColumnFamily current, long now) throws InvalidRequestException
++        public boolean appliesTo(Composite rowPrefix, ColumnFamily current, long now) throws InvalidRequestException
          {
-             if (remaining.isEmpty())
-                 return false;
+             if (column.type instanceof CollectionType)
+                 return collectionAppliesTo((CollectionType)column.type, rowPrefix, current, now);
+ 
 -            ColumnNameBuilder prefix = copyOrUpdatePrefix(current.metadata(), rowPrefix);
 -            ByteBuffer columnName = column.kind == CFDefinition.Name.Kind.VALUE_ALIAS
 -                                  ? prefix.build()
 -                                  : prefix.add(column.name.key).build();
 -
 -            Column c = current.getColumn(columnName);
++            Cell c = current.getColumn(current.metadata().comparator.create(rowPrefix, column));
+             ByteBuffer v = value.bindAndGet(variables);
+             return v == null
+                  ? c == null || !c.isLive(now)
 -                 : c != null && c.isLive(now) && column.type.compare(c.value(), v) == 0;
++                 : c != null && c.isLive(now) && c.value().equals(v);
+         }
  
-             if (!remaining.remove(iter.next().name().collectionElement()))
-                 return false;
 -        private boolean collectionAppliesTo(CollectionType type, ColumnNameBuilder rowPrefix, ColumnFamily current, final long now) throws InvalidRequestException
++        private boolean collectionAppliesTo(CollectionType type, Composite rowPrefix, ColumnFamily current, final long now) throws InvalidRequestException
+         {
 -            ColumnNameBuilder collectionPrefix = copyOrUpdatePrefix(current.metadata(), rowPrefix).add(column.name.key);
++            CellName name = current.metadata().comparator.create(rowPrefix, column);
+             // We are testing for collection equality, so we need to have the expected values *and* only those.
 -            ColumnSlice[] collectionSlice = new ColumnSlice[]{ new ColumnSlice(collectionPrefix.build(), collectionPrefix.buildAsEndOfRange()) };
++            ColumnSlice[] collectionSlice = new ColumnSlice[]{ name.slice() };
+             // Filter live columns, this makes things simpler afterwards
 -            Iterator<Column> iter = Iterators.filter(current.iterator(collectionSlice), new Predicate<Column>()
++            Iterator<Cell> iter = Iterators.filter(current.iterator(collectionSlice), new Predicate<Cell>()
+             {
 -                public boolean apply(Column c)
++                public boolean apply(Cell c)
+                 {
+                     // we only care about live columns
+                     return c.isLive(now);
+                 }
+             });
+ 
+             Term.Terminal v = value.bind(variables);
+             if (v == null)
+                 return !iter.hasNext();
+ 
+             switch (type.kind)
+             {
 -                case LIST: return listAppliesTo((ListType)type, current.metadata(), iter, ((Lists.Value)v).elements);
 -                case SET: return setAppliesTo((SetType)type, current.metadata(), iter, ((Sets.Value)v).elements);
 -                case MAP: return mapAppliesTo((MapType)type, current.metadata(), iter, ((Maps.Value)v).map);
++                case LIST: return listAppliesTo((ListType)type, iter, ((Lists.Value)v).elements);
++                case SET: return setAppliesTo((SetType)type, iter, ((Sets.Value)v).elements);
++                case MAP: return mapAppliesTo((MapType)type, iter, ((Maps.Value)v).map);
+             }
+             throw new AssertionError();
          }
-         return remaining.isEmpty();
-     }
  
-     private boolean mapAppliesTo(Iterator<Cell> iter, Map<ByteBuffer, ByteBuffer> elements)
-     {
-         Map<ByteBuffer, ByteBuffer> remaining = new HashMap<>(elements);
-         while (iter.hasNext())
 -        private ByteBuffer collectionKey(CFMetaData cfm, Column c)
 -        {
 -            ByteBuffer[] bbs = ((CompositeType)cfm.comparator).split(c.name());
 -            return bbs[bbs.length - 1];
 -        }
 -
 -        private boolean listAppliesTo(ListType type, CFMetaData cfm, Iterator<Column> iter, List<ByteBuffer> elements)
++        private boolean listAppliesTo(ListType type, Iterator<Cell> iter, List<ByteBuffer> elements)
          {
-             if (remaining.isEmpty())
-                 return false;
+             for (ByteBuffer e : elements)
+                 if (!iter.hasNext() || type.elements.compare(iter.next().value(), e) != 0)
+                     return false;
+             // We must not have more elements than expected
+             return !iter.hasNext();
+         }
  
-             Cell c = iter.next();
-             if (!remaining.remove(c.name().collectionElement()).equals(c.value()))
-                 return false;
 -        private boolean setAppliesTo(SetType type, CFMetaData cfm, Iterator<Column> iter, Set<ByteBuffer> elements)
++        private boolean setAppliesTo(SetType type, Iterator<Cell> iter, Set<ByteBuffer> elements)
+         {
+             Set<ByteBuffer> remaining = new TreeSet<>(type.elements);
+             remaining.addAll(elements);
+             while (iter.hasNext())
+             {
+                 if (remaining.isEmpty())
+                     return false;
+ 
 -                if (!remaining.remove(collectionKey(cfm, iter.next())))
++                if (!remaining.remove(iter.next().name().collectionElement()))
+                     return false;
+             }
+             return remaining.isEmpty();
+         }
+ 
 -        private boolean mapAppliesTo(MapType type, CFMetaData cfm, Iterator<Column> iter, Map<ByteBuffer, ByteBuffer> elements)
++        private boolean mapAppliesTo(MapType type, Iterator<Cell> iter, Map<ByteBuffer, ByteBuffer> elements)
+         {
+             Map<ByteBuffer, ByteBuffer> remaining = new TreeMap<>(type.keys);
+             remaining.putAll(elements);
+             while (iter.hasNext())
+             {
+                 if (remaining.isEmpty())
+                     return false;
+ 
 -                Column c = iter.next();
 -                ByteBuffer previous = remaining.remove(collectionKey(cfm, c));
++                Cell c = iter.next();
++                ByteBuffer previous = remaining.remove(c.name().collectionElement());
+                 if (previous == null || type.values.compare(previous, c.value()) != 0)
+                     return false;
+             }
+             return remaining.isEmpty();
          }
-         return remaining.isEmpty();
      }
  
      public static class Raw

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f7e690d7/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
index 9451ce9,7d3c0f7..fb842a2
--- a/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CQL3CasConditions.java
@@@ -166,9 -166,9 +166,9 @@@ public class CQL3CasConditions implemen
  
      private static class ColumnsConditions extends RowCondition
      {
-         private final Map<ColumnIdentifier, ColumnCondition> conditions = new HashMap<>();
+         private final Map<ColumnIdentifier, ColumnCondition.WithVariables> conditions = new HashMap<>();
  
 -        private ColumnsConditions(ColumnNameBuilder rowPrefix, long now)
 +        private ColumnsConditions(Composite rowPrefix, long now)
          {
              super(rowPrefix, now);
          }


[2/4] git commit: Replace equals by type compare

Posted by sl...@apache.org.
Replace equals by type compare


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

Branch: refs/heads/trunk
Commit: 17278b3a343575f4c32414cfffb52cdc2e7c7d00
Parents: 167380f
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Wed Apr 2 20:14:42 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Wed Apr 2 20:14:42 2014 +0200

----------------------------------------------------------------------
 .../apache/cassandra/cql3/ColumnCondition.java  | 27 ++++++++++----------
 1 file changed, 14 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/17278b3a/src/java/org/apache/cassandra/cql3/ColumnCondition.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/ColumnCondition.java b/src/java/org/apache/cassandra/cql3/ColumnCondition.java
index 0ebd4af..e6cdf43 100644
--- a/src/java/org/apache/cassandra/cql3/ColumnCondition.java
+++ b/src/java/org/apache/cassandra/cql3/ColumnCondition.java
@@ -26,9 +26,7 @@ import com.google.common.collect.Iterators;
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.filter.ColumnSlice;
-import org.apache.cassandra.db.marshal.CollectionType;
-import org.apache.cassandra.db.marshal.CounterColumnType;
-import org.apache.cassandra.db.marshal.CompositeType;
+import org.apache.cassandra.db.marshal.*;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
 /**
@@ -140,9 +138,9 @@ public class ColumnCondition
 
             switch (type.kind)
             {
-                case LIST: return listAppliesTo(current.metadata(), iter, ((Lists.Value)v).elements);
-                case SET: return setAppliesTo(current.metadata(), iter, ((Sets.Value)v).elements);
-                case MAP: return mapAppliesTo(current.metadata(), iter, ((Maps.Value)v).map);
+                case LIST: return listAppliesTo((ListType)type, current.metadata(), iter, ((Lists.Value)v).elements);
+                case SET: return setAppliesTo((SetType)type, current.metadata(), iter, ((Sets.Value)v).elements);
+                case MAP: return mapAppliesTo((MapType)type, current.metadata(), iter, ((Maps.Value)v).map);
             }
             throw new AssertionError();
         }
@@ -153,18 +151,19 @@ public class ColumnCondition
             return bbs[bbs.length - 1];
         }
 
-        private boolean listAppliesTo(CFMetaData cfm, Iterator<Column> iter, List<ByteBuffer> elements)
+        private boolean listAppliesTo(ListType type, CFMetaData cfm, Iterator<Column> iter, List<ByteBuffer> elements)
         {
             for (ByteBuffer e : elements)
-                if (!iter.hasNext() || !iter.next().value().equals(e))
+                if (!iter.hasNext() || type.elements.compare(iter.next().value(), e) != 0)
                     return false;
             // We must not have more elements than expected
             return !iter.hasNext();
         }
 
-        private boolean setAppliesTo(CFMetaData cfm, Iterator<Column> iter, Set<ByteBuffer> elements)
+        private boolean setAppliesTo(SetType type, CFMetaData cfm, Iterator<Column> iter, Set<ByteBuffer> elements)
         {
-            Set<ByteBuffer> remaining = new HashSet<>(elements);
+            Set<ByteBuffer> remaining = new TreeSet<>(type.elements);
+            remaining.addAll(elements);
             while (iter.hasNext())
             {
                 if (remaining.isEmpty())
@@ -176,16 +175,18 @@ public class ColumnCondition
             return remaining.isEmpty();
         }
 
-        private boolean mapAppliesTo(CFMetaData cfm, Iterator<Column> iter, Map<ByteBuffer, ByteBuffer> elements)
+        private boolean mapAppliesTo(MapType type, CFMetaData cfm, Iterator<Column> iter, Map<ByteBuffer, ByteBuffer> elements)
         {
-            Map<ByteBuffer, ByteBuffer> remaining = new HashMap<>(elements);
+            Map<ByteBuffer, ByteBuffer> remaining = new TreeMap<>(type.keys);
+            remaining.putAll(elements);
             while (iter.hasNext())
             {
                 if (remaining.isEmpty())
                     return false;
 
                 Column c = iter.next();
-                if (!remaining.remove(collectionKey(cfm, c)).equals(c.value()))
+                ByteBuffer previous = remaining.remove(collectionKey(cfm, c));
+                if (previous == null || type.values.compare(previous, c.value()) != 0)
                     return false;
             }
             return remaining.isEmpty();