diff --git a/CHANGES.txt b/CHANGES.txt index 3eff22c227..261a53ac93 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,6 +5,7 @@ * Deprecate Pig support (CASSANDRA-10542) * Reduce contention getting instances of CompositeType (CASSANDRA-10433) Merged from 2.1: + * Fix conditions on static columns (CASSANDRA-10264) * AssertionError: attempted to delete non-existing file CommitLog (CASSANDRA-10377) * (cqlsh) Distinguish negative and positive infinity in output (CASSANDRA-10523) * (cqlsh) allow custom time_format for COPY TO (CASSANDRA-8970) diff --git a/pylib/cqlshlib/cql3handling.py b/pylib/cqlshlib/cql3handling.py index 0ee0a38496..b4edac1141 100644 --- a/pylib/cqlshlib/cql3handling.py +++ b/pylib/cqlshlib/cql3handling.py @@ -146,7 +146,7 @@ JUNK ::= /([ \t\r\f\v]+|(--|[/][/])[^\n\r]*([\n\r]|$)|[/][*].*?[*][/])/ ; ::= "*" ; ::= ";" ; ::= /[-+=,().]/ ; - ::= /[<>]=?/ ; + ::= /[<>!]=?/ ; ::= /[][{}]/ ; ::= "-"? ; diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java index 9e897572a5..8b594ddac1 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java @@ -335,7 +335,7 @@ public abstract class ModificationStatement implements CQLStatement // UPDATE t SET s = 3 WHERE k = 0 AND v = 1 // DELETE v FROM t WHERE k = 0 AND v = 1 // sounds like you don't really understand what your are doing. - if (setsStaticColumns && !setsRegularColumns) + if (appliesOnlyToStaticColumns()) { // If we set no non-static columns, then it's fine not to have clustering columns if (hasNoClusteringColumns) @@ -357,6 +357,27 @@ public abstract class ModificationStatement implements CQLStatement return createClusteringPrefixBuilderInternal(options); } + /** + * Checks that the modification only apply to static columns. + * @return true if the modification only apply to static columns, false otherwise. + */ + private boolean appliesOnlyToStaticColumns() + { + return setsStaticColumns && !appliesToRegularColumns(); + } + + /** + * Checks that the modification apply to regular columns. + * @return true if the modification apply to regular columns, false otherwise. + */ + private boolean appliesToRegularColumns() + { + // If we have regular operations, this applies to regular columns. + // Otherwise, if the statement is a DELETE and columnOperations is empty, this means we have no operations, + // which for a DELETE means a full row deletion. Which means the operation applies to all columns and regular ones in particular. + return setsRegularColumns || (type == StatementType.DELETE && columnOperations.isEmpty()); + } + private Composite createClusteringPrefixBuilderInternal(QueryOptions options) throws InvalidRequestException { 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 522495ca33..b73ecdf9cb 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java @@ -26,7 +26,6 @@ import org.apache.cassandra.exceptions.SyntaxException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; public class InsertUpdateIfConditionTest extends CQLTester { @@ -181,6 +180,17 @@ public class InsertUpdateIfConditionTest extends CQLTester assertInvalid("DELETE FROM %s WHERE i = 0 IF EXISTS"); assertInvalid("DELETE FROM %s WHERE k = 0 AND i > 0 IF EXISTS"); assertInvalid("DELETE FROM %s WHERE k = 0 AND i > 0 IF v = 'foo'"); + + createTable("CREATE TABLE %s(k int, s int static, i int, v text, PRIMARY KEY(k, i))"); + execute("INSERT INTO %s (k, s, i, v) VALUES ( 1, 1, 2, '1')"); + assertRows(execute("DELETE v FROM %s WHERE k = 1 AND i = 2 IF s != 1"), row(false, 1)); + assertRows(execute("DELETE v FROM %s WHERE k = 1 AND i = 2 IF s = 1"), row(true)); + assertRows(execute("SELECT * FROM %s WHERE k = 1 AND i = 2"), row(1, 2, 1, null)); + + assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 2 IF s != 1"), row(false, 1)); + 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)); } /**