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 2017/02/07 09:37:59 UTC
cassandra git commit: Fix UPDATE queries with empty IN restrictions
Repository: cassandra
Updated Branches:
refs/heads/cassandra-3.0 dab0e31ba -> fb606dd41
Fix UPDATE queries with empty IN restrictions
patch by Benjamin Lerer; reviewed by Alex Petrov for CASSANDRA-13152
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/fb606dd4
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/fb606dd4
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/fb606dd4
Branch: refs/heads/cassandra-3.0
Commit: fb606dd41c9f14324749efc1344421237c36a6db
Parents: dab0e31
Author: Benjamin Lerer <b....@gmail.com>
Authored: Tue Feb 7 10:35:48 2017 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Tue Feb 7 10:35:48 2017 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../cql3/statements/ModificationStatement.java | 4 ++
.../cql3/validation/operations/DeleteTest.java | 54 ++++++++++++++++++++
.../cql3/validation/operations/UpdateTest.java | 53 ++++++++++++++++++-
4 files changed, 111 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/fb606dd4/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 1a90b1f..4387019 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
3.0.11
+ * Fix UPDATE queries with empty IN restrictions (CASSANDRA-13152)
* Abort or retry on failed hints delivery (CASSANDRA-13124)
* Fix handling of partition with partition-level deletion plus
live rows in sstabledump (CASSANDRA-13177)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/fb606dd4/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 acfa16b..1722f02 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@ -657,6 +657,10 @@ public abstract class ModificationStatement implements CQLStatement
{
NavigableSet<Clustering> clusterings = createClustering(options);
+ // If some of the restrictions were unspecified (e.g. empty IN restrictions) we do not need to do anything.
+ if (restrictions.hasClusteringColumnsRestriction() && clusterings.isEmpty())
+ return;
+
UpdateParameters params = makeUpdateParameters(keys, clusterings, options, local, now);
for (ByteBuffer key : keys)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/fb606dd4/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 18a6ca3..09098ac 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java
@@ -28,11 +28,14 @@ import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.db.ColumnFamilyStore;
+import org.apache.cassandra.db.Keyspace;
import static org.apache.cassandra.utils.ByteBufferUtil.EMPTY_BYTE_BUFFER;
import static org.apache.cassandra.utils.ByteBufferUtil.bytes;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
public class DeleteTest extends CQLTester
{
@@ -1247,4 +1250,55 @@ public class DeleteTest extends CQLTester
row(1, 1, 1, 3, 3),
row(1, 1, 1, 4, 4));
}
+
+ /**
+ * Test for CASSANDRA-13152
+ */
+ @Test
+ public void testThatDeletesWithEmptyInRestrictionDoNotCreateMutations() throws Throwable
+ {
+ createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))");
+
+ 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 ();");
+
+ assertTrue("The memtable should be empty but is not", isMemtableEmpty());
+
+ createTable("CREATE TABLE %s (a int, b int, c int, d int, s int static, PRIMARY KEY ((a,b), c))");
+
+ 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;");
+
+ assertTrue("The memtable should be empty but is not", isMemtableEmpty());
+
+ createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY ((a,b), c, d))");
+
+ 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");
+
+ assertTrue("The memtable should be empty but is not", isMemtableEmpty());
+ }
+
+ /**
+ * Checks if the memtable is empty or not
+ * @return {@code true} if the memtable is empty, {@code false} otherwise.
+ */
+ private boolean isMemtableEmpty()
+ {
+ Keyspace keyspace = Keyspace.open(KEYSPACE);
+ ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(currentTable());
+ return cfs.metric.allMemtablesLiveDataSize.getValue() == 0;
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/fb606dd4/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 0d81fa3..a49f828 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java
@@ -20,11 +20,15 @@ package org.apache.cassandra.cql3.validation.operations;
import java.util.Arrays;
+import org.junit.Assert;
import org.junit.Test;
import static org.apache.commons.lang3.StringUtils.isEmpty;
+import static org.junit.Assert.assertTrue;
+
import org.apache.cassandra.cql3.CQLTester;
-import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.db.ColumnFamilyStore;
+import org.apache.cassandra.db.Keyspace;
public class UpdateTest extends CQLTester
{
@@ -557,4 +561,51 @@ public class UpdateTest extends CQLTester
row(1,1,1,3,3),
row(1,1,1,4,4));
}
+
+ /**
+ * Test for CASSANDRA-13152
+ */
+ @Test
+ public void testThatUpdatesWithEmptyInRestrictionDoNotCreateMutations() throws Throwable
+ {
+ createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))");
+
+ execute("UPDATE %s SET c = 100 WHERE a IN () AND b = 1;");
+ execute("UPDATE %s SET c = 100 WHERE a = 1 AND b IN ();");
+
+ assertTrue("The memtable should be empty but is not", isMemtableEmpty());
+
+ createTable("CREATE TABLE %s (a int, b int, c int, d int, s int static, PRIMARY KEY ((a,b), c))");
+
+ 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 ();");
+
+ assertTrue("The memtable should be empty but is not", isMemtableEmpty());
+
+ createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY ((a,b), c, d))");
+
+ 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 ();");
+
+ assertTrue("The memtable should be empty but is not", isMemtableEmpty());
+ }
+
+ /**
+ * Checks if the memtable is empty or not
+ * @return {@code true} if the memtable is empty, {@code false} otherwise.
+ */
+ private boolean isMemtableEmpty()
+ {
+ Keyspace keyspace = Keyspace.open(KEYSPACE);
+ ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(currentTable());
+ return cfs.metric.allMemtablesLiveDataSize.getValue() == 0;
+ }
}