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 2015/03/23 17:14:21 UTC

cassandra git commit: Fix AssertionError when binding nested collections in DELETE

Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.1 ff14d7ab8 -> bcf0ec681


Fix AssertionError when binding nested collections in DELETE

patch by Stefania Alborghetti; reviewed by Benjamin Lerer for
CASSANDRA-8900


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

Branch: refs/heads/cassandra-2.1
Commit: bcf0ec681912e891d66a7b0ba28ff3d41ab3e304
Parents: ff14d7a
Author: Stefania Alborghetti <st...@datastax.com>
Authored: Wed Mar 11 15:09:21 2015 +0800
Committer: Aleksey Yeschenko <al...@apache.org>
Committed: Mon Mar 23 18:54:11 2015 +0300

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 src/java/org/apache/cassandra/cql3/Lists.java   |   4 +-
 src/java/org/apache/cassandra/cql3/Maps.java    |   3 +-
 .../org/apache/cassandra/cql3/Operation.java    |   2 +-
 src/java/org/apache/cassandra/cql3/Sets.java    |  25 +-
 .../cassandra/cql3/FrozenCollectionsTest.java   | 260 +++++++++++++++++++
 6 files changed, 286 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/bcf0ec68/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 924bdcf..0e75973 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.1.4
+ * Fix AssertionError when binding nested collections in DELETE (CASSANDRA-8900)
  * Check for overlap with non-early sstables in LCS (CASSANDRA-8739)
  * Only calculate max purgable timestamp if we have to (CASSANDRA-8914)
  * (cqlsh) Greatly improve performance of COPY FROM (CASSANDRA-8225)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/bcf0ec68/src/java/org/apache/cassandra/cql3/Lists.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Lists.java b/src/java/org/apache/cassandra/cql3/Lists.java
index 26d5de2..fc81900 100644
--- a/src/java/org/apache/cassandra/cql3/Lists.java
+++ b/src/java/org/apache/cassandra/cql3/Lists.java
@@ -494,10 +494,8 @@ public abstract class Lists
             if (index == null)
                 throw new InvalidRequestException("Invalid null value for list index");
 
-            assert index instanceof Constants.Value;
-
             List<Cell> existingList = params.getPrefetchedList(rowKey, column.name);
-            int idx = ByteBufferUtil.toInt(((Constants.Value)index).bytes);
+            int idx = ByteBufferUtil.toInt(index.get(params.options));
             if (idx < 0 || idx >= existingList.size())
                 throw new InvalidRequestException(String.format("List index %d out of bound, list has size %d", idx, existingList.size()));
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/bcf0ec68/src/java/org/apache/cassandra/cql3/Maps.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Maps.java b/src/java/org/apache/cassandra/cql3/Maps.java
index 5b58833..8a64663 100644
--- a/src/java/org/apache/cassandra/cql3/Maps.java
+++ b/src/java/org/apache/cassandra/cql3/Maps.java
@@ -378,9 +378,8 @@ public abstract class Maps
             Term.Terminal key = t.bind(params.options);
             if (key == null)
                 throw new InvalidRequestException("Invalid null map key");
-            assert key instanceof Constants.Value;
 
-            CellName cellName = cf.getComparator().create(prefix, column, ((Constants.Value)key).bytes);
+            CellName cellName = cf.getComparator().create(prefix, column, key.get(params.options));
             cf.addColumn(params.makeTombstone(cellName));
         }
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/bcf0ec68/src/java/org/apache/cassandra/cql3/Operation.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Operation.java b/src/java/org/apache/cassandra/cql3/Operation.java
index 816acb2..ac25e29 100644
--- a/src/java/org/apache/cassandra/cql3/Operation.java
+++ b/src/java/org/apache/cassandra/cql3/Operation.java
@@ -414,7 +414,7 @@ public abstract class Operation
                     return new Lists.DiscarderByIndex(receiver, idx);
                 case SET:
                     Term elt = element.prepare(keyspace, Sets.valueSpecOf(receiver));
-                    return new Sets.Discarder(receiver, elt);
+                    return new Sets.ElementDiscarder(receiver, elt);
                 case MAP:
                     Term key = element.prepare(keyspace, Maps.keySpecOf(receiver));
                     return new Maps.DiscarderByKey(receiver, key);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/bcf0ec68/src/java/org/apache/cassandra/cql3/Sets.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Sets.java b/src/java/org/apache/cassandra/cql3/Sets.java
index c5a8e05..a7e146f 100644
--- a/src/java/org/apache/cassandra/cql3/Sets.java
+++ b/src/java/org/apache/cassandra/cql3/Sets.java
@@ -315,9 +315,9 @@ public abstract class Sets
                 return;
 
             // This can be either a set or a single element
-            Set<ByteBuffer> toDiscard = value instanceof Constants.Value
-                                      ? Collections.singleton(((Constants.Value)value).bytes)
-                                      : ((Sets.Value)value).elements;
+            Set<ByteBuffer> toDiscard = value instanceof Sets.Value
+                                      ? ((Sets.Value)value).elements
+                                      : Collections.singleton(value.get(params.options));
 
             for (ByteBuffer bb : toDiscard)
             {
@@ -325,4 +325,23 @@ public abstract class Sets
             }
         }
     }
+
+    public static class ElementDiscarder extends Operation
+    {
+        public ElementDiscarder(ColumnDefinition column, Term k)
+        {
+            super(column, k);
+        }
+
+        public void execute(ByteBuffer rowKey, ColumnFamily cf, Composite prefix, UpdateParameters params) throws InvalidRequestException
+        {
+            assert column.type.isMultiCell() : "Attempted to delete a single element in a frozen set";
+            Term.Terminal elt = t.bind(params.options);
+            if (elt == null)
+                throw new InvalidRequestException("Invalid null set element");
+
+            CellName cellName = cf.getComparator().create(prefix, column, elt.get(params.options));
+            cf.addColumn(params.makeTombstone(cellName));
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/bcf0ec68/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java b/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java
index bf7ccfd..bf347f0 100644
--- a/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java
+++ b/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java
@@ -794,6 +794,266 @@ public class FrozenCollectionsTest extends CQLTester
     }
 
     @Test
+    public void testFrozenListInMap() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, m map<frozen<list<int>>, int>)");
+
+        execute("INSERT INTO %s (k, m) VALUES (1, {[1, 2, 3] : 1})");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(list(1, 2, 3), 1)));
+
+        execute("UPDATE %s SET m[[1, 2, 3]]=2 WHERE k=1");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(list(1, 2, 3), 2)));
+
+        execute("UPDATE %s SET m = m + ? WHERE k=1", map(list(4, 5, 6), 3));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1,
+                    map(list(1, 2, 3), 2,
+                        list(4, 5, 6), 3)));
+
+        execute("DELETE m[[1, 2, 3]] FROM %s WHERE k = 1");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(list(4, 5, 6), 3)));
+    }
+
+    @Test
+    public void testFrozenListInSet() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, s set<frozen<list<int>>>)");
+
+        execute("INSERT INTO %s (k, s) VALUES (1, {[1, 2, 3]})");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(list(1, 2, 3)))
+        );
+
+        execute("UPDATE %s SET s = s + ? WHERE k=1", set(list(4, 5, 6)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(list(1, 2, 3), list(4, 5, 6)))
+        );
+
+        execute("UPDATE %s SET s = s - ? WHERE k=1", set(list(4, 5, 6)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(list(1, 2, 3)))
+        );
+
+        execute("DELETE s[[1, 2, 3]] FROM %s WHERE k = 1");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, null)
+        );
+    }
+
+    @Test
+    public void testFrozenListInList() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, l list<frozen<list<int>>>)");
+
+        execute("INSERT INTO %s (k, l) VALUES (1, [[1, 2, 3]])");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(list(1, 2, 3)))
+        );
+
+        execute("UPDATE %s SET l[?]=? WHERE k=1", 0, list(4, 5, 6));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(list(4, 5, 6)))
+        );
+
+        execute("UPDATE %s SET l = ? + l WHERE k=1", list(list(1, 2, 3)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(list(1, 2, 3), list(4, 5, 6)))
+        );
+
+        execute("UPDATE %s SET l = l + ? WHERE k=1", list(list(7, 8, 9)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(list(1, 2, 3), list(4, 5, 6), list(7, 8, 9)))
+        );
+
+        execute("UPDATE %s SET l = l - ? WHERE k=1", list(list(4, 5, 6)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(list(1, 2, 3), list(7, 8, 9)))
+        );
+
+        execute("DELETE l[0] FROM %s WHERE k = 1");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(list(7, 8, 9)))
+        );
+    }
+
+    @Test
+    public void testFrozenMapInMap() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, m map<frozen<map<int, int>>, int>)");
+
+        execute("INSERT INTO %s (k, m) VALUES (1, {{1 : 1, 2 : 2} : 1})");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(map(1, 1, 2, 2), 1)));
+
+        execute("UPDATE %s SET m[?]=2 WHERE k=1", map(1, 1, 2, 2));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(map(1, 1, 2, 2), 2)));
+
+        execute("UPDATE %s SET m = m + ? WHERE k=1", map(map(3, 3, 4, 4), 3));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1,
+                    map(map(1, 1, 2, 2), 2,
+                        map(3, 3, 4, 4), 3)));
+
+        execute("DELETE m[?] FROM %s WHERE k = 1", map(1, 1, 2, 2));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(map(3, 3, 4, 4), 3)));
+    }
+
+    @Test
+    public void testFrozenMapInSet() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, s set<frozen<map<int, int>>>)");
+
+        execute("INSERT INTO %s (k, s) VALUES (1, {{1 : 1, 2 : 2}})");
+
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(map(1, 1, 2, 2)))
+        );
+
+        execute("UPDATE %s SET s = s + ? WHERE k=1", set(map(3, 3, 4, 4)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(map(1, 1, 2, 2), map(3, 3, 4, 4)))
+        );
+
+        execute("UPDATE %s SET s = s - ? WHERE k=1", set(map(3, 3, 4, 4)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(map(1, 1, 2, 2)))
+        );
+
+        execute("DELETE s[?] FROM %s WHERE k = 1", map(1, 1, 2, 2));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, null)
+        );
+    }
+
+    @Test
+    public void testFrozenMapInList() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, l list<frozen<map<int, int>>>)");
+
+        execute("INSERT INTO %s (k, l) VALUES (1, [{1 : 1, 2 : 2}])");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(map(1, 1, 2, 2)))
+        );
+
+        execute("UPDATE %s SET l[?]=? WHERE k=1", 0, map(3, 3, 4, 4));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(map(3, 3, 4, 4)))
+        );
+
+        execute("UPDATE %s SET l = ? + l WHERE k=1", list(map(1, 1, 2, 2)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(map(1, 1, 2, 2), map(3, 3, 4, 4)))
+        );
+
+        execute("UPDATE %s SET l = l + ? WHERE k=1", list(map(5, 5, 6, 6)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(map(1, 1, 2, 2), map(3, 3, 4, 4), map(5, 5, 6, 6)))
+        );
+
+        execute("UPDATE %s SET l = l - ? WHERE k=1", list(map(3, 3, 4, 4)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(map(1, 1, 2, 2), map(5, 5, 6, 6)))
+        );
+
+        execute("DELETE l[0] FROM %s WHERE k = 1");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(map(5, 5, 6, 6)))
+        );
+    }
+
+    @Test
+    public void testFrozenSetInMap() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, m map<frozen<set<int>>, int>)");
+
+        execute("INSERT INTO %s (k, m) VALUES (1, {{1, 2, 3} : 1})");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(set(1, 2, 3), 1)));
+
+        execute("UPDATE %s SET m[?]=2 WHERE k=1", set(1, 2, 3));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(set(1, 2, 3), 2)));
+
+        execute("UPDATE %s SET m = m + ? WHERE k=1", map(set(4, 5, 6), 3));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1,
+                    map(set(1, 2, 3), 2,
+                        set(4, 5, 6), 3)));
+
+        execute("DELETE m[?] FROM %s WHERE k = 1", set(1, 2, 3));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, map(set(4, 5, 6), 3)));
+    }
+
+    @Test
+    public void testFrozenSetInSet() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, s set<frozen<set<int>>>)");
+
+        execute("INSERT INTO %s (k, s) VALUES (1, {{1, 2, 3}})");
+
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(set(1, 2, 3)))
+        );
+
+        execute("UPDATE %s SET s = s + ? WHERE k=1", set(set(4, 5, 6)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(set(1, 2, 3), set(4, 5, 6)))
+        );
+
+        execute("UPDATE %s SET s = s - ? WHERE k=1", set(set(4, 5, 6)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, set(set(1, 2, 3)))
+        );
+
+        execute("DELETE s[?] FROM %s WHERE k = 1", set(1, 2, 3));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, null)
+        );
+    }
+
+    @Test
+    public void testFrozenSetInList() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int primary key, l list<frozen<set<int>>>)");
+
+        execute("INSERT INTO %s (k, l) VALUES (1, [{1, 2, 3}])");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(set(1, 2, 3)))
+        );
+
+        execute("UPDATE %s SET l[?]=? WHERE k=1", 0, set(4, 5, 6));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(set(4, 5, 6)))
+        );
+
+        execute("UPDATE %s SET l = ? + l WHERE k=1", list(set(1, 2, 3)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(set(1, 2, 3), set(4, 5, 6)))
+        );
+
+        execute("UPDATE %s SET l = l + ? WHERE k=1", list(set(7, 8, 9)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(set(1, 2, 3), set(4, 5, 6), set(7, 8, 9)))
+        );
+
+        execute("UPDATE %s SET l = l - ? WHERE k=1", list(set(4, 5, 6)));
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(set(1, 2, 3), set(7, 8, 9)))
+        );
+
+        execute("DELETE l[0] FROM %s WHERE k = 1");
+        assertRows(execute("SELECT * FROM %s WHERE k = 1"),
+                row(1, list(set(7, 8, 9)))
+        );
+    }
+
+    @Test
     public void testUserDefinedTypes() throws Throwable
     {
         String myType = createType("CREATE TYPE %s (a set<int>, b tuple<list<int>>)");