Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id C9214200C14 for ; Tue, 7 Feb 2017 10:48:37 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id C7CED160B68; Tue, 7 Feb 2017 09:48:37 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 01E1B160B3E for ; Tue, 7 Feb 2017 10:48:36 +0100 (CET) Received: (qmail 61889 invoked by uid 500); 7 Feb 2017 09:48:36 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 61871 invoked by uid 99); 7 Feb 2017 09:48:36 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Feb 2017 09:48:36 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 1233CDFADC; Tue, 7 Feb 2017 09:48:36 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: blerer@apache.org To: commits@cassandra.apache.org Date: Tue, 07 Feb 2017 09:48:36 -0000 Message-Id: <80e89401c7d445c2ab4ae0f902b3aa97@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/2] cassandra git commit: Fix UPDATE queries with empty IN restrictions archived-at: Tue, 07 Feb 2017 09:48:37 -0000 Repository: cassandra Updated Branches: refs/heads/cassandra-3.11 97861e68c -> 3acdcaf8d 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.11 Commit: fb606dd41c9f14324749efc1344421237c36a6db Parents: dab0e31 Author: Benjamin Lerer Authored: Tue Feb 7 10:35:48 2017 +0100 Committer: Benjamin Lerer 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 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; + } }