You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2016/12/15 17:11:55 UTC

[1/3] cassandra git commit: Fix DELETE and UPDATE queries with empty IN restrictions

Repository: cassandra
Updated Branches:
  refs/heads/cassandra-3.X de84f264f -> e5a77cfea


Fix DELETE and UPDATE queries with empty IN restrictions

patch by Alex Petrov; reviewed by Benjamin Lerer for CASSANDRA-12829


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

Branch: refs/heads/cassandra-3.X
Commit: 9fc1ffb631a5a44bc11b55061288758e39a9d20a
Parents: 0fe82be
Author: Alex Petrov <ol...@gmail.com>
Authored: Thu Dec 15 17:56:41 2016 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Thu Dec 15 18:01:32 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../restrictions/StatementRestrictions.java     | 11 ++++
 .../cql3/statements/BatchStatement.java         | 11 ++--
 .../cql3/statements/ModificationStatement.java  | 15 +++--
 .../org/apache/cassandra/cql3/CQLTester.java    |  7 ++
 .../cql3/validation/operations/BatchTest.java   | 40 ++++++++++++
 .../cql3/validation/operations/DeleteTest.java  | 63 ++++++++++++++++--
 .../cql3/validation/operations/InsertTest.java  |  6 --
 .../operations/InsertUpdateIfConditionTest.java |  6 ++
 .../cql3/validation/operations/UpdateTest.java  | 69 +++++++++++++++++++-
 10 files changed, 202 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 145afb9..e69bf08 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0.11
+ * Fix DELETE and UPDATE queries with empty IN restrictions (CASSANDRA-12829)
  * Mark MVs as built after successful bootstrap (CASSANDRA-12984)
  * Estimated TS drop-time histogram updated with Cell.NO_DELETION_TIME (CASSANDRA-13040)
  * Nodetool compactionstats fails with NullPointerException (CASSANDRA-13021)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
index 647d22f..542dec9 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
@@ -430,6 +430,17 @@ public final class StatementRestrictions
     }
 
     /**
+     * Checks if restrictions on the clustering key have IN restrictions.
+     *
+     * @return <code>true</code> if the restrictions on the clustering key have IN restrictions,
+     * <code>false</code> otherwise.
+     */
+    public boolean clusteringKeyRestrictionsHasIN()
+    {
+        return clusteringColumnsRestrictions.isIN();
+    }
+
+    /**
      * Processes the clustering column restrictions.
      *
      * @param hasQueriableIndex <code>true</code> if some of the queried data are indexed, <code>false</code> otherwise

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
index f0aa835..76a6460 100644
--- a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
@@ -401,7 +401,7 @@ public class BatchStatement implements CQLStatement
             QueryOptions statementOptions = options.forStatement(i);
             long timestamp = attrs.getTimestamp(now, statementOptions);
             List<ByteBuffer> pks = statement.buildPartitionKeyNames(statementOptions);
-            if (pks.size() > 1)
+            if (statement.getRestrictions().keyIsInRelation())
                 throw new IllegalArgumentException("Batch with conditions cannot span multiple partitions (you cannot use IN on the partition key)");
             if (key == null)
             {
@@ -413,12 +413,11 @@ public class BatchStatement implements CQLStatement
                 throw new InvalidRequestException("Batch with conditions cannot span multiple partitions");
             }
 
-            SortedSet<Clustering> clusterings = statement.createClustering(statementOptions);
+            checkFalse(statement.getRestrictions().clusteringKeyRestrictionsHasIN(),
+                       "IN on the clustering key columns is not supported with conditional %s",
+                       statement.type.isUpdate()? "updates" : "deletions");
 
-            checkFalse(clusterings.size() > 1,
-                       "IN on the clustering key columns is not supported with conditional updates");
-
-            Clustering clustering = Iterables.getOnlyElement(clusterings);
+            Clustering clustering = Iterables.getOnlyElement(statement.createClustering(statementOptions));
 
             if (statement.hasConditions())
             {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
index 01c2ad1..acfa16b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@ -139,6 +139,11 @@ public abstract class ModificationStatement implements CQLStatement
         this.requiresRead = requiresReadBuilder.build();
     }
 
+    public StatementRestrictions getRestrictions()
+    {
+        return restrictions;
+    }
+
     public Iterable<Function> getFunctions()
     {
         List<Function> functions = new ArrayList<>();
@@ -445,20 +450,18 @@ public abstract class ModificationStatement implements CQLStatement
     {
         List<ByteBuffer> keys = buildPartitionKeyNames(options);
         // We don't support IN for CAS operation so far
-        checkFalse(keys.size() > 1,
+        checkFalse(restrictions.keyIsInRelation(),
                    "IN on the partition key is not supported with conditional %s",
                    type.isUpdate()? "updates" : "deletions");
 
         DecoratedKey key = cfm.decorateKey(keys.get(0));
         long now = options.getTimestamp(queryState);
-        SortedSet<Clustering> clusterings = createClustering(options);
 
-        checkFalse(clusterings.size() > 1,
+        checkFalse(restrictions.clusteringKeyRestrictionsHasIN(),
                    "IN on the clustering key columns is not supported with conditional %s",
                     type.isUpdate()? "updates" : "deletions");
 
-        Clustering clustering = Iterables.getOnlyElement(clusterings);
-
+        Clustering clustering = Iterables.getOnlyElement(createClustering(options));
         CQL3CasRequest request = new CQL3CasRequest(cfm, key, false, conditionColumns(), updatesRegularRows(), updatesStaticRow());
 
         addConditions(clustering, request, options);
@@ -663,7 +666,7 @@ public abstract class ModificationStatement implements CQLStatement
 
                 PartitionUpdate upd = collector.getPartitionUpdate(cfm, dk, options.getConsistency());
 
-                if (clusterings.isEmpty())
+                if (!restrictions.hasClusteringColumnsRestriction())
                 {
                     addUpdateForKey(upd, Clustering.EMPTY, params);
                 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/test/unit/org/apache/cassandra/cql3/CQLTester.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java
index 3d8d03b..4732ed3 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -382,6 +382,13 @@ public abstract class CQLTester
             store.forceBlockingFlush();
     }
 
+
+    public void flush(boolean forceFlush)
+    {
+        if (forceFlush)
+            flush();
+    }
+
     @FunctionalInterface
     public interface CheckedFunction {
         void apply() throws Throwable;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
index 66226eb..e8f169d 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
@@ -199,4 +199,44 @@ public class BatchTest extends CQLTester
         assertRows(execute(String.format("SELECT * FROM %s", tbl1)), row(0, 1, 2));
         assertRows(execute(String.format("SELECT * FROM %s", tbl2)), row(0, 3, 4));
     }
+
+    @Test
+    public void testBatchWithInRestriction() throws Throwable
+    {
+        createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))");
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,1,1);
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,2,2);
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,3,3);
+
+        for (String inClause : new String[] { "()", "(1, 2)"})
+        {
+            assertInvalidMessage("IN on the clustering key columns is not supported with conditional updates",
+                                 "BEGIN BATCH " +
+                                 "UPDATE %1$s SET c = 100 WHERE a = 1 AND b = 1 IF c = 1;" +
+                                 "UPDATE %1$s SET c = 200 WHERE a = 1 AND b IN " + inClause + " IF c = 1;" +
+                                 "APPLY BATCH");
+
+            assertInvalidMessage("IN on the clustering key columns is not supported with conditional deletions",
+                                 "BEGIN BATCH " +
+                                 "UPDATE %1$s SET c = 100 WHERE a = 1 AND b = 1 IF c = 1;" +
+                                 "DELETE FROM %1$s WHERE a = 1 AND b IN " + inClause + " IF c = 1;" +
+                                 "APPLY BATCH");
+
+            assertInvalidMessage("Batch with conditions cannot span multiple partitions (you cannot use IN on the partition key)",
+                                 "BEGIN BATCH " +
+                                 "UPDATE %1$s SET c = 100 WHERE a = 1 AND b = 1 IF c = 1;" +
+                                 "UPDATE %1$s SET c = 200 WHERE a IN " + inClause + " AND b = 1 IF c = 1;" +
+                                 "APPLY BATCH");
+
+            assertInvalidMessage("Batch with conditions cannot span multiple partitions (you cannot use IN on the partition key)",
+                                 "BEGIN BATCH " +
+                                 "UPDATE %1$s SET c = 100 WHERE a = 1 AND b = 1 IF c = 1;" +
+                                 "DELETE FROM %1$s WHERE a IN " + inClause + " AND b = 1 IF c = 1;" +
+                                 "APPLY BATCH");
+        }
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1,1,1),
+                   row(1,2,2),
+                   row(1,3,3));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
index b9ccafb..18a6ca3 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
@@ -1165,12 +1165,6 @@ public class DeleteTest extends CQLTester
         }
     }
 
-    private void flush(boolean forceFlush)
-    {
-        if (forceFlush)
-            flush();
-    }
-
     @Test
     public void testDeleteAndReverseQueries() throws Throwable
     {
@@ -1196,4 +1190,61 @@ public class DeleteTest extends CQLTester
             row(9), row(8), row(1), row(0)
         );
     }
+
+    /**
+     * Test for CASSANDRA-12829
+     */
+    @Test
+    public void testDeleteWithEmptyInRestriction() throws Throwable
+    {
+        createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))");
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 1, 1);
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 2, 2);
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 3, 3);
+
+        execute("DELETE FROM %s WHERE a IN ();");
+        execute("DELETE FROM %s WHERE a IN () AND b IN ();");
+        execute("DELETE FROM %s WHERE a IN () AND b = 1;");
+        execute("DELETE FROM %s WHERE a = 1 AND b IN ();");
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1, 1, 1),
+                   row(1, 2, 2),
+                   row(1, 3, 3));
+
+        createTable("CREATE TABLE %s (a int, b int, c int, d int, s int static, PRIMARY KEY ((a,b), c))");
+        execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 1, 1, 1);
+        execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 2, 2, 1);
+        execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 3, 3, 1);
+
+        execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN ();");
+        execute("DELETE FROM %s WHERE a = 1 AND b IN () AND c IN ();");
+        execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN ();");
+        execute("DELETE FROM %s WHERE a IN () AND b = 1 AND c IN ();");
+        execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1;");
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1, 1, 1, 1, 1),
+                   row(1, 1, 2, 1, 2),
+                   row(1, 1, 3, 1, 3));
+
+        createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY ((a,b), c, d))");
+        execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 1, 1);
+        execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 2, 2);
+        execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 3, 3);
+        execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 4, 4);
+
+        execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN ();");
+        execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c = 1 AND d IN ();");
+        execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN () AND d IN ();");
+        execute("DELETE FROM %s WHERE a = 1 AND b IN () AND c IN () AND d IN ();");
+        execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN () AND d IN ();");
+        execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN () AND d = 1;");
+        execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1 AND d = 1;");
+        execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1 AND d IN ();");
+        execute("DELETE FROM %s WHERE a IN () AND b = 1");
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1, 1, 1, 1, 1),
+                   row(1, 1, 1, 2, 2),
+                   row(1, 1, 1, 3, 3),
+                   row(1, 1, 1, 4, 4));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
index a030613..c9a9faf 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
@@ -285,12 +285,6 @@ public class InsertTest extends CQLTester
                              "INSERT INTO %s (partitionKey, clustering_2, staticValue) VALUES (0, 0, 'A')");
     }
 
-    private void flush(boolean forceFlush)
-    {
-        if (forceFlush)
-            flush();
-    }
-
     @Test
     public void testPKInsertWithValueOver64K() throws Throwable
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
index f1dc9a2..fd02a69 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
@@ -119,6 +119,8 @@ public class InsertUpdateIfConditionTest extends CQLTester
 
         createTable(" CREATE TABLE %s (k int, c int, v1 text, PRIMARY KEY(k, c))");
         assertInvalidMessage("IN on the clustering key columns is not supported with conditional updates",
+                             "UPDATE %s SET v1 = 'A' WHERE k = 0 AND c IN () IF EXISTS");
+        assertInvalidMessage("IN on the clustering key columns is not supported with conditional updates",
                              "UPDATE %s SET v1 = 'A' WHERE k = 0 AND c IN (1, 2) IF EXISTS");
     }
 
@@ -227,7 +229,11 @@ public class InsertUpdateIfConditionTest extends CQLTester
         assertInvalidMessage("IN on the clustering key columns is not supported with conditional deletions",
                              "DELETE FROM %s WHERE k = 'k' AND i IN (0, 1) IF v = 'foo'");
         assertInvalidMessage("IN on the clustering key columns is not supported with conditional deletions",
+                             "DELETE FROM %s WHERE k = 'k' AND i IN () IF v = 'foo'");
+        assertInvalidMessage("IN on the clustering key columns is not supported with conditional deletions",
                              "DELETE FROM %s WHERE k = 'k' AND i IN (0, 1) IF EXISTS");
+        assertInvalidMessage("IN on the clustering key columns is not supported with conditional deletions",
+                             "DELETE FROM %s WHERE k = 'k' AND i IN () IF EXISTS");
 
         assertInvalidMessage("Invalid 'unset' value in condition",
                              "DELETE FROM %s WHERE k = 'k' AND i = 0 IF v = ?", unset());

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9fc1ffb6/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
index 0170ed2..690d4f9 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
@@ -521,9 +521,72 @@ public class UpdateTest extends CQLTester
         assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", "v4", "v3")));
     }
 
-    private void flush(boolean forceFlush)
+    /**
+     * Test for CASSANDRA-12829
+     */
+    @Test
+    public void testUpdateWithEmptyInRestriction() throws Throwable
     {
-        if (forceFlush)
-            flush();
+        createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))");
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,1,1);
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,2,2);
+        execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,3,3);
+
+        assertInvalidMessage("Some clustering keys are missing: b",
+                             "UPDATE %s SET c = 100 WHERE a IN ();");
+        execute("UPDATE %s SET c = 100 WHERE a IN () AND b IN ();");
+        execute("UPDATE %s SET c = 100 WHERE a IN () AND b = 1;");
+        execute("UPDATE %s SET c = 100 WHERE a = 1 AND b IN ();");
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1,1,1),
+                   row(1,2,2),
+                   row(1,3,3));
+
+        createTable("CREATE TABLE %s (a int, b int, c int, d int, s int static, PRIMARY KEY ((a,b), c))");
+        execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,1,1,1);
+        execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,2,2,1);
+        execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,3,3,1);
+
+        execute("UPDATE %s SET d = 100 WHERE a = 1 AND b = 1 AND c IN ();");
+        execute("UPDATE %s SET d = 100 WHERE a = 1 AND b IN () AND c IN ();");
+        execute("UPDATE %s SET d = 100 WHERE a IN () AND b IN () AND c IN ();");
+        execute("UPDATE %s SET d = 100 WHERE a IN () AND b IN () AND c = 1;");
+        execute("UPDATE %s SET d = 100 WHERE a IN () AND b = 1 AND c IN ();");
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1,1,1,1,1),
+                   row(1,1,2,1,2),
+                   row(1,1,3,1,3));
+
+        // No clustering keys restricted, update whole partition
+        execute("UPDATE %s set s = 100 where a = 1 AND b = 1;");
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1,1,1,100,1),
+                   row(1,1,2,100,2),
+                   row(1,1,3,100,3));
+
+        execute("UPDATE %s set s = 200 where a = 1 AND b IN ();");
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1,1,1,100,1),
+                   row(1,1,2,100,2),
+                   row(1,1,3,100,3));
+
+        createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY ((a,b), c, d))");
+        execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,1,1);
+        execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,2,2);
+        execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,3,3);
+        execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,4,4);
+
+        execute("UPDATE %s SET e = 100 WHERE a = 1 AND b = 1 AND c = 1 AND d IN ();");
+        execute("UPDATE %s SET e = 100 WHERE a = 1 AND b = 1 AND c IN () AND d IN ();");
+        execute("UPDATE %s SET e = 100 WHERE a = 1 AND b IN () AND c IN () AND d IN ();");
+        execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c IN () AND d IN ();");
+        execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c IN () AND d = 1;");
+        execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c = 1 AND d = 1;");
+        execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c = 1 AND d IN ();");
+        assertRows(execute("SELECT * FROM %s"),
+                   row(1,1,1,1,1),
+                   row(1,1,1,2,2),
+                   row(1,1,1,3,3),
+                   row(1,1,1,4,4));
     }
 }


[2/3] cassandra git commit: Merge branch cassandra-3.0 into cassandra-3.11

Posted by bl...@apache.org.
Merge branch cassandra-3.0 into cassandra-3.11


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

Branch: refs/heads/cassandra-3.X
Commit: 73547a3421cc92e07d0373846fc1bff796570275
Parents: 249e4b1 9fc1ffb
Author: Benjamin Lerer <b....@gmail.com>
Authored: Thu Dec 15 18:04:34 2016 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Thu Dec 15 18:07:59 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../restrictions/StatementRestrictions.java     | 11 +++
 .../cql3/statements/BatchStatement.java         | 11 ++-
 .../cql3/statements/ModificationStatement.java  | 10 ++-
 .../cql3/validation/operations/BatchTest.java   | 40 +++++++++++
 .../cql3/validation/operations/DeleteTest.java  | 57 ++++++++++++++++
 .../operations/InsertUpdateIfConditionTest.java |  6 ++
 .../cql3/validation/operations/UpdateTest.java  | 70 ++++++++++++++++++++
 8 files changed, 194 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index f95dd81,e69bf08..3db0179
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,114 -1,5 +1,115 @@@
 -3.0.11
 +3.10
 + * Remove outboundBindAny configuration property (CASSANDRA-12673)
 + * Use correct bounds for all-data range when filtering (CASSANDRA-12666)
 + * Remove timing window in test case (CASSANDRA-12875)
 + * Resolve unit testing without JCE security libraries installed (CASSANDRA-12945)
 + * Fix inconsistencies in cassandra-stress load balancing policy (CASSANDRA-12919)
 + * Fix validation of non-frozen UDT cells (CASSANDRA-12916)
 + * Don't shut down socket input/output on StreamSession (CASSANDRA-12903)
 + * Fix Murmur3PartitionerTest (CASSANDRA-12858)
 + * Move cqlsh syntax rules into separate module and allow easier customization (CASSANDRA-12897)
 + * Fix CommitLogSegmentManagerTest (CASSANDRA-12283)
 + * Fix cassandra-stress truncate option (CASSANDRA-12695)
 + * Fix crossNode value when receiving messages (CASSANDRA-12791)
 + * Don't load MX4J beans twice (CASSANDRA-12869)
 + * Extend native protocol request flags, add versions to SUPPORTED, and introduce ProtocolVersion enum (CASSANDRA-12838)
 + * Set JOINING mode when running pre-join tasks (CASSANDRA-12836)
 + * remove net.mintern.primitive library due to license issue (CASSANDRA-12845)
 + * Properly format IPv6 addresses when logging JMX service URL (CASSANDRA-12454)
 + * Optimize the vnode allocation for single replica per DC (CASSANDRA-12777)
 + * Use non-token restrictions for bounds when token restrictions are overridden (CASSANDRA-12419)
 + * Fix CQLSH auto completion for PER PARTITION LIMIT (CASSANDRA-12803)
 + * Use different build directories for Eclipse and Ant (CASSANDRA-12466)
 + * Avoid potential AttributeError in cqlsh due to no table metadata (CASSANDRA-12815)
 + * Fix RandomReplicationAwareTokenAllocatorTest.testExistingCluster (CASSANDRA-12812)
 + * Upgrade commons-codec to 1.9 (CASSANDRA-12790)
 + * Make the fanout size for LeveledCompactionStrategy to be configurable (CASSANDRA-11550)
 + * Add duration data type (CASSANDRA-11873)
 + * Fix timeout in ReplicationAwareTokenAllocatorTest (CASSANDRA-12784)
 + * Improve sum aggregate functions (CASSANDRA-12417)
 + * Make cassandra.yaml docs for batch_size_*_threshold_in_kb reflect changes in CASSANDRA-10876 (CASSANDRA-12761)
 + * cqlsh fails to format collections when using aliases (CASSANDRA-11534)
 + * Check for hash conflicts in prepared statements (CASSANDRA-12733)
 + * Exit query parsing upon first error (CASSANDRA-12598)
 + * Fix cassandra-stress to use single seed in UUID generation (CASSANDRA-12729)
 + * CQLSSTableWriter does not allow Update statement (CASSANDRA-12450)
 + * Config class uses boxed types but DD exposes primitive types (CASSANDRA-12199)
 + * Add pre- and post-shutdown hooks to Storage Service (CASSANDRA-12461)
 + * Add hint delivery metrics (CASSANDRA-12693)
 + * Remove IndexInfo cache from FileIndexInfoRetriever (CASSANDRA-12731)
 + * ColumnIndex does not reuse buffer (CASSANDRA-12502)
 + * cdc column addition still breaks schema migration tasks (CASSANDRA-12697)
 + * Upgrade metrics-reporter dependencies (CASSANDRA-12089)
 + * Tune compaction thread count via nodetool (CASSANDRA-12248)
 + * Add +=/-= shortcut syntax for update queries (CASSANDRA-12232)
 + * Include repair session IDs in repair start message (CASSANDRA-12532)
 + * Add a blocking task to Index, run before joining the ring (CASSANDRA-12039)
 + * Fix NPE when using CQLSSTableWriter (CASSANDRA-12667)
 + * Support optional backpressure strategies at the coordinator (CASSANDRA-9318)
 + * Make randompartitioner work with new vnode allocation (CASSANDRA-12647)
 + * Fix cassandra-stress graphing (CASSANDRA-12237)
 + * Allow filtering on partition key columns for queries without secondary indexes (CASSANDRA-11031)
 + * Fix Cassandra Stress reporting thread model and precision (CASSANDRA-12585)
 + * Add JMH benchmarks.jar (CASSANDRA-12586)
 + * Cleanup uses of AlterTableStatementColumn (CASSANDRA-12567)
 + * Add keep-alive to streaming (CASSANDRA-11841)
 + * Tracing payload is passed through newSession(..) (CASSANDRA-11706)
 + * avoid deleting non existing sstable files and improve related log messages (CASSANDRA-12261)
 + * json/yaml output format for nodetool compactionhistory (CASSANDRA-12486)
 + * Retry all internode messages once after a connection is
 +   closed and reopened (CASSANDRA-12192)
 + * Add support to rebuild from targeted replica (CASSANDRA-9875)
 + * Add sequence distribution type to cassandra stress (CASSANDRA-12490)
 + * "SELECT * FROM foo LIMIT ;" does not error out (CASSANDRA-12154)
 + * Define executeLocally() at the ReadQuery Level (CASSANDRA-12474)
 + * Extend read/write failure messages with a map of replica addresses
 +   to error codes in the v5 native protocol (CASSANDRA-12311)
 + * Fix rebuild of SASI indexes with existing index files (CASSANDRA-12374)
 + * Let DatabaseDescriptor not implicitly startup services (CASSANDRA-9054, 12550)
 + * Fix clustering indexes in presence of static columns in SASI (CASSANDRA-12378)
 + * Fix queries on columns with reversed type on SASI indexes (CASSANDRA-12223)
 + * Added slow query log (CASSANDRA-12403)
 + * Count full coordinated request against timeout (CASSANDRA-12256)
 + * Allow TTL with null value on insert and update (CASSANDRA-12216)
 + * Make decommission operation resumable (CASSANDRA-12008)
 + * Add support to one-way targeted repair (CASSANDRA-9876)
 + * Remove clientutil jar (CASSANDRA-11635)
 + * Fix compaction throughput throttle (CASSANDRA-12366, CASSANDRA-12717)
 + * Delay releasing Memtable memory on flush until PostFlush has finished running (CASSANDRA-12358)
 + * Cassandra stress should dump all setting on startup (CASSANDRA-11914)
 + * Make it possible to compact a given token range (CASSANDRA-10643)
 + * Allow updating DynamicEndpointSnitch properties via JMX (CASSANDRA-12179)
 + * Collect metrics on queries by consistency level (CASSANDRA-7384)
 + * Add support for GROUP BY to SELECT statement (CASSANDRA-10707)
 + * Deprecate memtable_cleanup_threshold and update default for memtable_flush_writers (CASSANDRA-12228)
 + * Upgrade to OHC 0.4.4 (CASSANDRA-12133)
 + * Add version command to cassandra-stress (CASSANDRA-12258)
 + * Create compaction-stress tool (CASSANDRA-11844)
 + * Garbage-collecting compaction operation and schema option (CASSANDRA-7019)
 + * Add beta protocol flag for v5 native protocol (CASSANDRA-12142)
 + * Support filtering on non-PRIMARY KEY columns in the CREATE
 +   MATERIALIZED VIEW statement's WHERE clause (CASSANDRA-10368)
 + * Unify STDOUT and SYSTEMLOG logback format (CASSANDRA-12004)
 + * COPY FROM should raise error for non-existing input files (CASSANDRA-12174)
 + * Faster write path (CASSANDRA-12269)
 + * Option to leave omitted columns in INSERT JSON unset (CASSANDRA-11424)
 + * Support json/yaml output in nodetool tpstats (CASSANDRA-12035)
 + * Expose metrics for successful/failed authentication attempts (CASSANDRA-10635)
 + * Prepend snapshot name with "truncated" or "dropped" when a snapshot
 +   is taken before truncating or dropping a table (CASSANDRA-12178)
 + * Optimize RestrictionSet (CASSANDRA-12153)
 + * cqlsh does not automatically downgrade CQL version (CASSANDRA-12150)
 + * Omit (de)serialization of state variable in UDAs (CASSANDRA-9613)
 + * Create a system table to expose prepared statements (CASSANDRA-8831)
 + * Reuse DataOutputBuffer from ColumnIndex (CASSANDRA-11970)
 + * Remove DatabaseDescriptor dependency from SegmentedFile (CASSANDRA-11580)
 + * Add supplied username to authentication error messages (CASSANDRA-12076)
 + * Remove pre-startup check for open JMX port (CASSANDRA-12074)
 + * Remove compaction Severity from DynamicEndpointSnitch (CASSANDRA-11738)
 + * Restore resumable hints delivery (CASSANDRA-11960)
 + * Properly report LWT contention (CASSANDRA-12626)
 +Merged from 3.0:
+  * Fix DELETE and UPDATE queries with empty IN restrictions (CASSANDRA-12829)
   * Mark MVs as built after successful bootstrap (CASSANDRA-12984)
   * Estimated TS drop-time histogram updated with Cell.NO_DELETION_TIME (CASSANDRA-13040)
   * Nodetool compactionstats fails with NullPointerException (CASSANDRA-13021)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
index 2d04633,542dec9..6b89579
--- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
@@@ -471,6 -430,17 +471,17 @@@ public final class StatementRestriction
      }
  
      /**
+      * Checks if restrictions on the clustering key have IN restrictions.
+      *
+      * @return <code>true</code> if the restrictions on the clustering key have IN restrictions,
+      * <code>false</code> otherwise.
+      */
+     public boolean clusteringKeyRestrictionsHasIN()
+     {
 -        return clusteringColumnsRestrictions.isIN();
++        return clusteringColumnsRestrictions.hasIN();
+     }
+ 
+     /**
       * Processes the clustering column restrictions.
       *
       * @param hasQueriableIndex <code>true</code> if some of the queried data are indexed, <code>false</code> otherwise

http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
index 118a1e2,18a6ca3..62a7954
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
@@@ -1244,4 -1164,87 +1244,61 @@@ public class DeleteTest extends CQLTest
                         row(bytes("foo123"), bytes("1"), bytes("2"), bytes("3")));
          }
      }
+ 
 -    @Test
 -    public void testDeleteAndReverseQueries() throws Throwable
 -    {
 -        // This test insert rows in one sstable and a range tombstone covering some of those rows in another, and it
 -        // validates we correctly get only the non-removed rows when doing reverse queries.
 -
 -        createTable("CREATE TABLE %s (k text, i int, PRIMARY KEY (k, i))");
 -
 -        for (int i = 0; i < 10; i++)
 -            execute("INSERT INTO %s(k, i) values (?, ?)", "a", i);
 -
 -        flush();
 -
 -        execute("DELETE FROM %s WHERE k = ? AND i >= ? AND i <= ?", "a", 2, 7);
 -
 -        assertRows(execute("SELECT i FROM %s WHERE k = ? ORDER BY i DESC", "a"),
 -            row(9), row(8), row(1), row(0)
 -        );
 -
 -        flush();
 -
 -        assertRows(execute("SELECT i FROM %s WHERE k = ? ORDER BY i DESC", "a"),
 -            row(9), row(8), row(1), row(0)
 -        );
 -    }
 -
+     /**
+      * Test for CASSANDRA-12829
+      */
+     @Test
+     public void testDeleteWithEmptyInRestriction() throws Throwable
+     {
+         createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))");
+         execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 1, 1);
+         execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 2, 2);
+         execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 3, 3);
+ 
+         execute("DELETE FROM %s WHERE a IN ();");
+         execute("DELETE FROM %s WHERE a IN () AND b IN ();");
+         execute("DELETE FROM %s WHERE a IN () AND b = 1;");
+         execute("DELETE FROM %s WHERE a = 1 AND b IN ();");
+         assertRows(execute("SELECT * FROM %s"),
+                    row(1, 1, 1),
+                    row(1, 2, 2),
+                    row(1, 3, 3));
+ 
+         createTable("CREATE TABLE %s (a int, b int, c int, d int, s int static, PRIMARY KEY ((a,b), c))");
+         execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 1, 1, 1);
+         execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 2, 2, 1);
+         execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 3, 3, 1);
+ 
+         execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN ();");
+         execute("DELETE FROM %s WHERE a = 1 AND b IN () AND c IN ();");
+         execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN ();");
+         execute("DELETE FROM %s WHERE a IN () AND b = 1 AND c IN ();");
+         execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1;");
+         assertRows(execute("SELECT * FROM %s"),
+                    row(1, 1, 1, 1, 1),
+                    row(1, 1, 2, 1, 2),
+                    row(1, 1, 3, 1, 3));
+ 
+         createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY ((a,b), c, d))");
+         execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 1, 1);
+         execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 2, 2);
+         execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 3, 3);
+         execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 4, 4);
+ 
+         execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN ();");
+         execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c = 1 AND d IN ();");
+         execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN () AND d IN ();");
+         execute("DELETE FROM %s WHERE a = 1 AND b IN () AND c IN () AND d IN ();");
+         execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN () AND d IN ();");
+         execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN () AND d = 1;");
+         execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1 AND d = 1;");
+         execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1 AND d IN ();");
+         execute("DELETE FROM %s WHERE a IN () AND b = 1");
+         assertRows(execute("SELECT * FROM %s"),
+                    row(1, 1, 1, 1, 1),
+                    row(1, 1, 1, 2, 2),
+                    row(1, 1, 1, 3, 3),
+                    row(1, 1, 1, 4, 4));
+     }
  }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
index 494abaa,690d4f9..51280a9
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
@@@ -526,59 -521,72 +526,129 @@@ public class UpdateTest extends CQLTest
          assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", "v4", "v3")));
      }
  
 +    @Test
 +    public void testUpdateWithDefaultTtl() throws Throwable
 +    {
 +        final int secondsPerMinute = 60;
 +        createTable("CREATE TABLE %s (a int PRIMARY KEY, b int) WITH default_time_to_live = " + (10 * secondsPerMinute));
 +
 +        execute("UPDATE %s SET b = 1 WHERE a = 1");
 +        UntypedResultSet resultSet = execute("SELECT ttl(b) FROM %s WHERE a = 1");
 +        Assert.assertEquals(1, resultSet.size());
 +        Row row = resultSet.one();
 +        Assert.assertTrue(row.getInt("ttl(b)") >= (9 * secondsPerMinute));
 +
 +        execute("UPDATE %s USING TTL ? SET b = 3 WHERE a = 1", 0);
 +        assertRows(execute("SELECT ttl(b) FROM %s WHERE a = 1"), row(new Object[]{null}));
 +
 +        execute("UPDATE %s SET b = 3 WHERE a = 1");
 +        resultSet = execute("SELECT ttl(b) FROM %s WHERE a = 1");
 +        Assert.assertEquals(1, resultSet.size());
 +        row = resultSet.one();
 +        Assert.assertTrue(row.getInt("ttl(b)") >= (9 * secondsPerMinute));
 +
 +        execute("UPDATE %s USING TTL ? SET b = 2 WHERE a = 2", unset());
 +        resultSet = execute("SELECT ttl(b) FROM %s WHERE a = 2");
 +        Assert.assertEquals(1, resultSet.size());
 +        row = resultSet.one();
 +        Assert.assertTrue(row.getInt("ttl(b)") >= (9 * secondsPerMinute));
 +
 +        execute("UPDATE %s USING TTL ? SET b = ? WHERE a = ?", null, 3, 3);
 +        assertRows(execute("SELECT ttl(b) FROM %s WHERE a = 3"), row(new Object[] { null }));
 +    }
 +
 +    @Test
 +    public void testUpdateWithTtl() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
 +
 +        execute("INSERT INTO %s (k, v) VALUES (1, 1) USING TTL ?", 3600);
 +        execute("INSERT INTO %s (k, v) VALUES (2, 2) USING TTL ?", 3600);
 +
 +        // test with unset
 +        execute("UPDATE %s USING TTL ? SET v = ? WHERE k = ?", unset(), 1, 1); // treat as 'unlimited'
 +        assertRows(execute("SELECT ttl(v) FROM %s WHERE k = 1"), row(new Object[] { null }));
 +
 +        // test with null
 +        execute("UPDATE %s USING TTL ? SET v = ? WHERE k = ?", unset(), 2, 2);
 +        assertRows(execute("SELECT k, v, TTL(v) FROM %s WHERE k = 2"), row(2, 2, null));
 +
 +        // test error handling
 +        assertInvalidMessage("A TTL must be greater or equal to 0, but was -5",
 +                             "UPDATE %s USING TTL ? SET v = ? WHERE k = ?", -5, 1, 1);
 +
 +        assertInvalidMessage("ttl is too large.",
 +                             "UPDATE %s USING TTL ? SET v = ? WHERE k = ?",
 +                             Attributes.MAX_TTL + 1, 1, 1);
 +    }
++
+     /**
+      * Test for CASSANDRA-12829
+      */
+     @Test
+     public void testUpdateWithEmptyInRestriction() throws Throwable
+     {
+         createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))");
+         execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,1,1);
+         execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,2,2);
+         execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,3,3);
+ 
+         assertInvalidMessage("Some clustering keys are missing: b",
+                              "UPDATE %s SET c = 100 WHERE a IN ();");
+         execute("UPDATE %s SET c = 100 WHERE a IN () AND b IN ();");
+         execute("UPDATE %s SET c = 100 WHERE a IN () AND b = 1;");
+         execute("UPDATE %s SET c = 100 WHERE a = 1 AND b IN ();");
+         assertRows(execute("SELECT * FROM %s"),
+                    row(1,1,1),
+                    row(1,2,2),
+                    row(1,3,3));
+ 
+         createTable("CREATE TABLE %s (a int, b int, c int, d int, s int static, PRIMARY KEY ((a,b), c))");
+         execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,1,1,1);
+         execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,2,2,1);
+         execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,3,3,1);
+ 
+         execute("UPDATE %s SET d = 100 WHERE a = 1 AND b = 1 AND c IN ();");
+         execute("UPDATE %s SET d = 100 WHERE a = 1 AND b IN () AND c IN ();");
+         execute("UPDATE %s SET d = 100 WHERE a IN () AND b IN () AND c IN ();");
+         execute("UPDATE %s SET d = 100 WHERE a IN () AND b IN () AND c = 1;");
+         execute("UPDATE %s SET d = 100 WHERE a IN () AND b = 1 AND c IN ();");
+         assertRows(execute("SELECT * FROM %s"),
+                    row(1,1,1,1,1),
+                    row(1,1,2,1,2),
+                    row(1,1,3,1,3));
+ 
+         // No clustering keys restricted, update whole partition
+         execute("UPDATE %s set s = 100 where a = 1 AND b = 1;");
+         assertRows(execute("SELECT * FROM %s"),
+                    row(1,1,1,100,1),
+                    row(1,1,2,100,2),
+                    row(1,1,3,100,3));
+ 
+         execute("UPDATE %s set s = 200 where a = 1 AND b IN ();");
+         assertRows(execute("SELECT * FROM %s"),
+                    row(1,1,1,100,1),
+                    row(1,1,2,100,2),
+                    row(1,1,3,100,3));
+ 
+         createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY ((a,b), c, d))");
+         execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,1,1);
+         execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,2,2);
+         execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,3,3);
+         execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,4,4);
+ 
+         execute("UPDATE %s SET e = 100 WHERE a = 1 AND b = 1 AND c = 1 AND d IN ();");
+         execute("UPDATE %s SET e = 100 WHERE a = 1 AND b = 1 AND c IN () AND d IN ();");
+         execute("UPDATE %s SET e = 100 WHERE a = 1 AND b IN () AND c IN () AND d IN ();");
+         execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c IN () AND d IN ();");
+         execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c IN () AND d = 1;");
+         execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c = 1 AND d = 1;");
+         execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c = 1 AND d IN ();");
+         assertRows(execute("SELECT * FROM %s"),
+                    row(1,1,1,1,1),
+                    row(1,1,1,2,2),
+                    row(1,1,1,3,3),
+                    row(1,1,1,4,4));
+     }
++
  }


[3/3] cassandra git commit: Merge branch cassandra-3.11 into cassandra-3.X

Posted by bl...@apache.org.
Merge branch cassandra-3.11 into cassandra-3.X


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

Branch: refs/heads/cassandra-3.X
Commit: e5a77cfeaa2be7f6c68965603e7a87034ff7b576
Parents: de84f26 73547a3
Author: Benjamin Lerer <b....@gmail.com>
Authored: Thu Dec 15 18:09:52 2016 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Thu Dec 15 18:10:01 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../restrictions/StatementRestrictions.java     | 11 +++
 .../cql3/statements/BatchStatement.java         | 11 ++-
 .../cql3/statements/ModificationStatement.java  | 10 ++-
 .../cql3/validation/operations/BatchTest.java   | 40 +++++++++++
 .../cql3/validation/operations/DeleteTest.java  | 57 ++++++++++++++++
 .../operations/InsertUpdateIfConditionTest.java |  6 ++
 .../cql3/validation/operations/UpdateTest.java  | 70 ++++++++++++++++++++
 8 files changed, 194 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


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

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e5a77cfe/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
----------------------------------------------------------------------