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 2016/12/08 16:28:55 UTC

[3/6] cassandra git commit: Make distinction between unset row and non-existing partition for LWTs

Make distinction between unset row and non-existing partition for LWTs 

Patch by Alex Petrov; reviewed by Sylvain Lebresne for CASSANDRA-12964.

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

Branch: refs/heads/trunk
Commit: d9b06e8af41c42244f76058641aeecda53a9bf75
Parents: 3aefe35
Author: Alex Petrov <ol...@gmail.com>
Authored: Wed Dec 7 16:04:51 2016 +0100
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Thu Dec 8 17:22:06 2016 +0100

----------------------------------------------------------------------
 .../cql3/statements/CQL3CasRequest.java         | 10 +++---
 .../cassandra/db/filter/ColumnFilter.java       |  9 ++++++
 .../operations/InsertUpdateIfConditionTest.java | 32 +++++++++++++++++++-
 3 files changed, 46 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/d9b06e8a/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java b/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java
index d9e8796..db8653d 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java
@@ -20,8 +20,7 @@ package org.apache.cassandra.cql3.statements;
 import java.nio.ByteBuffer;
 import java.util.*;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import com.google.common.collect.*;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.cql3.*;
@@ -179,19 +178,22 @@ public class CQL3CasRequest implements CASRequest
     {
         assert staticConditions != null || !conditions.isEmpty();
 
+        // Fetch all columns, but query only the selected ones
+        ColumnFilter columnFilter = ColumnFilter.selection(cfm, columnsToRead());
+
         // With only a static condition, we still want to make the distinction between a non-existing partition and one
         // that exists (has some live data) but has not static content. So we query the first live row of the partition.
         if (conditions.isEmpty())
             return SinglePartitionReadCommand.create(cfm,
                                                      nowInSec,
-                                                     ColumnFilter.selection(columnsToRead()),
+                                                     columnFilter,
                                                      RowFilter.NONE,
                                                      DataLimits.cqlLimits(1),
                                                      key,
                                                      new ClusteringIndexSliceFilter(Slices.ALL, false));
 
         ClusteringIndexNamesFilter filter = new ClusteringIndexNamesFilter(conditions.navigableKeySet(), false);
-        return SinglePartitionReadCommand.create(cfm, nowInSec, key, ColumnFilter.selection(columnsToRead()), filter);
+        return SinglePartitionReadCommand.create(cfm, nowInSec, key, columnFilter, filter);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/d9b06e8a/src/java/org/apache/cassandra/db/filter/ColumnFilter.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/filter/ColumnFilter.java b/src/java/org/apache/cassandra/db/filter/ColumnFilter.java
index 8d4f8b8..2377ad0 100644
--- a/src/java/org/apache/cassandra/db/filter/ColumnFilter.java
+++ b/src/java/org/apache/cassandra/db/filter/ColumnFilter.java
@@ -95,6 +95,15 @@ public class ColumnFilter
         return new ColumnFilter(false, null, columns, null);
     }
 
+	/**
+     * A filter that fetches all columns for the provided table, but returns
+     * only the queried ones.
+     */
+    public static ColumnFilter selection(CFMetaData metadata, PartitionColumns queried)
+    {
+        return new ColumnFilter(true, metadata, queried, null);
+    }
+
     /**
      * The columns that needs to be fetched internally for this selection.
      * <p>

http://git-wip-us.apache.org/repos/asf/cassandra/blob/d9b06e8a/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 40db977..ec81cf2 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
@@ -186,6 +186,10 @@ public class InsertUpdateIfConditionTest extends CQLTester
         execute("INSERT INTO %s (k, s, i, v) VALUES ('k', 's', 0, 'v')");
         assertRows(execute("DELETE v FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(true));
         assertRows(execute("DELETE FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(true));
+        assertRows(execute("SELECT * FROM %s"), row("k", null, "s", null));
+        assertRows(execute("DELETE v FROM %s WHERE k='k' AND i=0 IF s = 'z'"), row(false, "s"));
+        assertRows(execute("DELETE v FROM %s WHERE k='k' AND i=0 IF v = 'z'"), row(false));
+        assertRows(execute("DELETE v FROM %s WHERE k='k' AND i=0 IF v = 'z' AND s = 'z'"), row(false, null, "s"));
         assertRows(execute("DELETE v FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(false));
         assertRows(execute("DELETE FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(false));
 
@@ -220,6 +224,28 @@ public class InsertUpdateIfConditionTest extends CQLTester
         assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 2 IF s = 1"), row(true));
         assertEmpty(execute("SELECT * FROM %s WHERE k = 1 AND i = 2"));
         assertRows(execute("SELECT * FROM %s WHERE k = 1"), row(1, null, 1, null));
+
+        createTable("CREATE TABLE %s (k int, i int, v1 int, v2 int, s int static, PRIMARY KEY (k, i))");
+        execute("INSERT INTO %s (k, i, v1, v2, s) VALUES (?, ?, ?, ?, ?)",
+                1, 1, 1, 1, 1);
+        assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF EXISTS"),
+                   row(true));
+        assertRows(execute("DELETE v2 FROM %s WHERE k = 1 AND i = 1 IF EXISTS"),
+                   row(true));
+        assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 1 IF EXISTS"),
+                   row(true));
+        assertRows(execute("select * from %s"),
+                   row(1, null, 1, null, null));
+        assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF EXISTS"),
+                   row(false));
+        assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF s = 5"),
+                   row(false, 1));
+        assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF v1 = 1 AND v2 = 1"),
+                   row(false));
+        assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF v1 = 1 AND v2 = 1 AND s = 1"),
+                   row(false, null, null, 1));
+        assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 5 IF s = 1"),
+                   row(true));
     }
 
     /**
@@ -249,13 +275,17 @@ public class InsertUpdateIfConditionTest extends CQLTester
         assertRows(execute("UPDATE %s SET v='bar', version=2 WHERE id=0 AND k='k2' IF version = 1"), row(true));
         assertRows(execute("SELECT * FROM %s"), row(0, "k1", 2, "foo"), row(0, "k2", 2, "bar"));
 
+        // Batch output is slightly different from non-batch CAS, since a full PK is included to disambiguate
+        // cases when conditions span across multiple rows.
+        assertRows(execute("UPDATE %1$s SET version=3 WHERE id=0 IF version=1; "),
+                   row(false, 2));
         // Testing batches
         assertRows(execute("BEGIN BATCH " +
                            "UPDATE %1$s SET v='foobar' WHERE id=0 AND k='k1'; " +
                            "UPDATE %1$s SET v='barfoo' WHERE id=0 AND k='k2'; " +
                            "UPDATE %1$s SET version=3 WHERE id=0 IF version=1; " +
                            "APPLY BATCH "),
-                   row(false, 0, null, 2));
+                   row(false, 0, "k1", 2));
 
         assertRows(execute("BEGIN BATCH " +
                            "UPDATE %1$s SET v = 'foobar' WHERE id = 0 AND k = 'k1'; " +