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:54 UTC
[2/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/cassandra-3.X
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'; " +