From 90208c0a29157fdc4ac88d7e24708535650b5d55 Mon Sep 17 00:00:00 2001 From: Benjamin Lerer Date: Tue, 4 Jun 2024 17:31:41 +0200 Subject: [PATCH] Makes LWT conditions behavior on frozen and non-frozen columns consistent for null column values Patch by Benjamin Lerer; review by Ekaterina Dimitrova for CASSANDRA-19637 --- CHANGES.txt | 3 +- .../cql3/conditions/ColumnCondition.java | 28 +- .../cassandra/db/marshal/CollectionType.java | 7 + .../cql3/conditions/ColumnConditionTest.java | 609 ++++++++++-------- ...nsertUpdateIfConditionCollectionsTest.java | 145 ++++- 5 files changed, 491 insertions(+), 301 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 2d56a56c61..2536042d93 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,7 @@ 4.0.14 + * Make LWT conditions behavior on frozen and non-frozen columns consistent for null column values (CASSANDRA-19637) * Add timeout specifically for bootstrapping nodes (CASSANDRA-15439) - * Bring Redhat packge dirs/ownership/perms in line with Debian package (CASSANDRA-19565) + * Bring Redhat package dirs/ownership/perms in line with Debian package (CASSANDRA-19565) 4.0.13 diff --git a/src/java/org/apache/cassandra/cql3/conditions/ColumnCondition.java b/src/java/org/apache/cassandra/cql3/conditions/ColumnCondition.java index 93ed6ae941..548795c253 100644 --- a/src/java/org/apache/cassandra/cql3/conditions/ColumnCondition.java +++ b/src/java/org/apache/cassandra/cql3/conditions/ColumnCondition.java @@ -461,15 +461,16 @@ public abstract class ColumnCondition this.values = values; } + @Override public boolean appliesTo(Row row) { - CollectionType type = (CollectionType)column.type; + CollectionType type = (CollectionType) column.type; // copy iterator contents so that we can properly reuse them for each comparison with an IN value for (Term.Terminal value : values) { Iterator> iter = getCells(row, column); - if (value == null) + if (value == null || isEmpty(type, value)) { if (comparisonOperator == Operator.EQ) { @@ -481,7 +482,10 @@ public abstract class ColumnCondition if (comparisonOperator == Operator.NEQ) return iter.hasNext(); - throw invalidRequest("Invalid comparison with null for operator \"%s\"", comparisonOperator); + if (value == null) + throw invalidRequest("Invalid comparison with null for operator \"%s\"", comparisonOperator); + + throw invalidRequest("Invalid comparison with an empty %s for operator \"%s\"", type.kind, comparisonOperator); } if (valueAppliesTo(type, iter, value, comparisonOperator)) @@ -490,10 +494,24 @@ public abstract class ColumnCondition return false; } + private boolean isEmpty(CollectionType type, Terminal value) + { + switch (type.kind) + { + case LIST: + return ((Lists.Value) value).elements.isEmpty(); + case SET: + return ((Sets.Value) value).elements.isEmpty(); + case MAP: + return ((Maps.Value) value).map.isEmpty(); + } + throw new AssertionError(); + } + private static boolean valueAppliesTo(CollectionType type, Iterator> iter, Term.Terminal value, Operator operator) { - if (value == null) - return !iter.hasNext(); + if (!iter.hasNext() && operator != Operator.NEQ) + return false; switch (type.kind) { diff --git a/src/java/org/apache/cassandra/db/marshal/CollectionType.java b/src/java/org/apache/cassandra/db/marshal/CollectionType.java index c52cddc07f..e7ff96d29c 100644 --- a/src/java/org/apache/cassandra/db/marshal/CollectionType.java +++ b/src/java/org/apache/cassandra/db/marshal/CollectionType.java @@ -21,6 +21,7 @@ import java.nio.ByteBuffer; import java.io.IOException; import java.util.List; import java.util.Iterator; +import java.util.Locale; import org.apache.cassandra.cql3.CQL3Type; import org.apache.cassandra.cql3.ColumnSpecification; @@ -71,6 +72,12 @@ public abstract class CollectionType extends AbstractType }; public abstract ColumnSpecification makeCollectionReceiver(ColumnSpecification collection, boolean isKey); + + @Override + public String toString() + { + return super.toString().toLowerCase(Locale.US); + } } public final Kind kind; diff --git a/test/unit/org/apache/cassandra/cql3/conditions/ColumnConditionTest.java b/test/unit/org/apache/cassandra/cql3/conditions/ColumnConditionTest.java index f62119d4e6..306ad6273b 100644 --- a/test/unit/org/apache/cassandra/cql3/conditions/ColumnConditionTest.java +++ b/test/unit/org/apache/cassandra/cql3/conditions/ColumnConditionTest.java @@ -120,7 +120,7 @@ public class ColumnConditionTest return builder.build(); } - private static boolean conditionApplies(ByteBuffer rowValue, Operator op, ByteBuffer conditionValue) + private static boolean appliesSimpleCondition(ByteBuffer rowValue, Operator op, ByteBuffer conditionValue) { ColumnMetadata definition = ColumnMetadata.regularColumn("ks", "cf", "c", Int32Type.instance); ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(new Constants.Value(conditionValue))); @@ -128,26 +128,29 @@ public class ColumnConditionTest return bound.appliesTo(newRow(definition, rowValue)); } - private static boolean conditionApplies(List rowValue, Operator op, List conditionValue) + private static boolean appliesListCondition(List rowValue, Operator op, List conditionValue) { ColumnMetadata definition = ColumnMetadata.regularColumn("ks", "cf", "c", ListType.getInstance(Int32Type.instance, true)); - ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(new Lists.Value(conditionValue))); + Term term = conditionValue == null ? Constants.NULL_VALUE : new Lists.Value(conditionValue); + ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(term)); ColumnCondition.Bound bound = condition.bind(QueryOptions.DEFAULT); return bound.appliesTo(newRow(definition, rowValue)); } - private static boolean conditionApplies(SortedSet rowValue, Operator op, SortedSet conditionValue) + private static boolean appliesSetCondition(SortedSet rowValue, Operator op, SortedSet conditionValue) { ColumnMetadata definition = ColumnMetadata.regularColumn("ks", "cf", "c", SetType.getInstance(Int32Type.instance, true)); - ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(new Sets.Value(conditionValue))); + Term term = conditionValue == null ? Constants.NULL_VALUE : new Sets.Value(conditionValue); + ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(term)); ColumnCondition.Bound bound = condition.bind(QueryOptions.DEFAULT); return bound.appliesTo(newRow(definition, rowValue)); } - private static boolean conditionApplies(Map rowValue, Operator op, SortedMap conditionValue) + private static boolean appliesMapCondition(Map rowValue, Operator op, SortedMap conditionValue) { ColumnMetadata definition = ColumnMetadata.regularColumn("ks", "cf", "c", MapType.getInstance(Int32Type.instance, Int32Type.instance, true)); - ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(new Maps.Value(conditionValue))); + Term term = conditionValue == null ? Constants.NULL_VALUE : new Maps.Value(conditionValue); + ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(term)); ColumnCondition.Bound bound = condition.bind(QueryOptions.DEFAULT); return bound.appliesTo(newRow(definition, rowValue)); } @@ -174,66 +177,66 @@ public class ColumnConditionTest public void testSimpleBoundIsSatisfiedByValue() throws InvalidRequestException { // EQ - assertTrue(conditionApplies(ONE, EQ, ONE)); - assertFalse(conditionApplies(TWO, EQ, ONE)); - assertFalse(conditionApplies(ONE, EQ, TWO)); - assertFalse(conditionApplies(ONE, EQ, EMPTY_BYTE_BUFFER)); - assertFalse(conditionApplies(EMPTY_BYTE_BUFFER, EQ, ONE)); - assertTrue(conditionApplies(EMPTY_BYTE_BUFFER, EQ, EMPTY_BYTE_BUFFER)); - assertFalse(conditionApplies(ONE, EQ, null)); - assertFalse(conditionApplies(null, EQ, ONE)); - assertTrue(conditionApplies((ByteBuffer) null, EQ, (ByteBuffer) null)); + assertTrue(appliesSimpleCondition(ONE, EQ, ONE)); + assertFalse(appliesSimpleCondition(TWO, EQ, ONE)); + assertFalse(appliesSimpleCondition(ONE, EQ, TWO)); + assertFalse(appliesSimpleCondition(ONE, EQ, EMPTY_BYTE_BUFFER)); + assertFalse(appliesSimpleCondition(EMPTY_BYTE_BUFFER, EQ, ONE)); + assertTrue(appliesSimpleCondition(EMPTY_BYTE_BUFFER, EQ, EMPTY_BYTE_BUFFER)); + assertFalse(appliesSimpleCondition(ONE, EQ, null)); + assertFalse(appliesSimpleCondition(null, EQ, ONE)); + assertTrue(appliesSimpleCondition((ByteBuffer) null, EQ, (ByteBuffer) null)); // NEQ - assertFalse(conditionApplies(ONE, NEQ, ONE)); - assertTrue(conditionApplies(TWO, NEQ, ONE)); - assertTrue(conditionApplies(ONE, NEQ, TWO)); - assertTrue(conditionApplies(ONE, NEQ, EMPTY_BYTE_BUFFER)); - assertTrue(conditionApplies(EMPTY_BYTE_BUFFER, NEQ, ONE)); - assertFalse(conditionApplies(EMPTY_BYTE_BUFFER, NEQ, EMPTY_BYTE_BUFFER)); - assertTrue(conditionApplies(ONE, NEQ, null)); - assertTrue(conditionApplies(null, NEQ, ONE)); - assertFalse(conditionApplies((ByteBuffer) null, NEQ, (ByteBuffer) null)); + assertFalse(appliesSimpleCondition(ONE, NEQ, ONE)); + assertTrue(appliesSimpleCondition(TWO, NEQ, ONE)); + assertTrue(appliesSimpleCondition(ONE, NEQ, TWO)); + assertTrue(appliesSimpleCondition(ONE, NEQ, EMPTY_BYTE_BUFFER)); + assertTrue(appliesSimpleCondition(EMPTY_BYTE_BUFFER, NEQ, ONE)); + assertFalse(appliesSimpleCondition(EMPTY_BYTE_BUFFER, NEQ, EMPTY_BYTE_BUFFER)); + assertTrue(appliesSimpleCondition(ONE, NEQ, null)); + assertTrue(appliesSimpleCondition(null, NEQ, ONE)); + assertFalse(appliesSimpleCondition((ByteBuffer) null, NEQ, (ByteBuffer) null)); // LT - assertFalse(conditionApplies(ONE, LT, ONE)); - assertFalse(conditionApplies(TWO, LT, ONE)); - assertTrue(conditionApplies(ONE, LT, TWO)); - assertFalse(conditionApplies(ONE, LT, EMPTY_BYTE_BUFFER)); - assertTrue(conditionApplies(EMPTY_BYTE_BUFFER, LT, ONE)); - assertFalse(conditionApplies(EMPTY_BYTE_BUFFER, LT, EMPTY_BYTE_BUFFER)); - assertThrowsIRE(() -> conditionApplies(ONE, LT, null), "Invalid comparison with null for operator \"<\""); - assertFalse(conditionApplies(null, LT, ONE)); + assertFalse(appliesSimpleCondition(ONE, LT, ONE)); + assertFalse(appliesSimpleCondition(TWO, LT, ONE)); + assertTrue(appliesSimpleCondition(ONE, LT, TWO)); + assertFalse(appliesSimpleCondition(ONE, LT, EMPTY_BYTE_BUFFER)); + assertTrue(appliesSimpleCondition(EMPTY_BYTE_BUFFER, LT, ONE)); + assertFalse(appliesSimpleCondition(EMPTY_BYTE_BUFFER, LT, EMPTY_BYTE_BUFFER)); + assertThrowsIRE(() -> appliesSimpleCondition(ONE, LT, null), "Invalid comparison with null for operator \"<\""); + assertFalse(appliesSimpleCondition(null, LT, ONE)); // LTE - assertTrue(conditionApplies(ONE, LTE, ONE)); - assertFalse(conditionApplies(TWO, LTE, ONE)); - assertTrue(conditionApplies(ONE, LTE, TWO)); - assertFalse(conditionApplies(ONE, LTE, EMPTY_BYTE_BUFFER)); - assertTrue(conditionApplies(EMPTY_BYTE_BUFFER, LTE, ONE)); - assertTrue(conditionApplies(EMPTY_BYTE_BUFFER, LTE, EMPTY_BYTE_BUFFER)); - assertThrowsIRE(() -> conditionApplies(ONE, LTE, null), "Invalid comparison with null for operator \"<=\""); - assertFalse(conditionApplies(null, LTE, ONE)); + assertTrue(appliesSimpleCondition(ONE, LTE, ONE)); + assertFalse(appliesSimpleCondition(TWO, LTE, ONE)); + assertTrue(appliesSimpleCondition(ONE, LTE, TWO)); + assertFalse(appliesSimpleCondition(ONE, LTE, EMPTY_BYTE_BUFFER)); + assertTrue(appliesSimpleCondition(EMPTY_BYTE_BUFFER, LTE, ONE)); + assertTrue(appliesSimpleCondition(EMPTY_BYTE_BUFFER, LTE, EMPTY_BYTE_BUFFER)); + assertThrowsIRE(() -> appliesSimpleCondition(ONE, LTE, null), "Invalid comparison with null for operator \"<=\""); + assertFalse(appliesSimpleCondition(null, LTE, ONE)); // GT - assertFalse(conditionApplies(ONE, GT, ONE)); - assertTrue(conditionApplies(TWO, GT, ONE)); - assertFalse(conditionApplies(ONE, GT, TWO)); - assertTrue(conditionApplies(ONE, GT, EMPTY_BYTE_BUFFER)); - assertFalse(conditionApplies(EMPTY_BYTE_BUFFER, GT, ONE)); - assertFalse(conditionApplies(EMPTY_BYTE_BUFFER, GT, EMPTY_BYTE_BUFFER)); - assertThrowsIRE(() -> conditionApplies(ONE, GT, null), "Invalid comparison with null for operator \">\""); - assertFalse(conditionApplies(null, GT, ONE)); + assertFalse(appliesSimpleCondition(ONE, GT, ONE)); + assertTrue(appliesSimpleCondition(TWO, GT, ONE)); + assertFalse(appliesSimpleCondition(ONE, GT, TWO)); + assertTrue(appliesSimpleCondition(ONE, GT, EMPTY_BYTE_BUFFER)); + assertFalse(appliesSimpleCondition(EMPTY_BYTE_BUFFER, GT, ONE)); + assertFalse(appliesSimpleCondition(EMPTY_BYTE_BUFFER, GT, EMPTY_BYTE_BUFFER)); + assertThrowsIRE(() -> appliesSimpleCondition(ONE, GT, null), "Invalid comparison with null for operator \">\""); + assertFalse(appliesSimpleCondition(null, GT, ONE)); // GTE - assertTrue(conditionApplies(ONE, GTE, ONE)); - assertTrue(conditionApplies(TWO, GTE, ONE)); - assertFalse(conditionApplies(ONE, GTE, TWO)); - assertTrue(conditionApplies(ONE, GTE, EMPTY_BYTE_BUFFER)); - assertFalse(conditionApplies(EMPTY_BYTE_BUFFER, GTE, ONE)); - assertTrue(conditionApplies(EMPTY_BYTE_BUFFER, GTE, EMPTY_BYTE_BUFFER)); - assertThrowsIRE(() -> conditionApplies(ONE, GTE, null), "Invalid comparison with null for operator \">=\""); - assertFalse(conditionApplies(null, GTE, ONE)); + assertTrue(appliesSimpleCondition(ONE, GTE, ONE)); + assertTrue(appliesSimpleCondition(TWO, GTE, ONE)); + assertFalse(appliesSimpleCondition(ONE, GTE, TWO)); + assertTrue(appliesSimpleCondition(ONE, GTE, EMPTY_BYTE_BUFFER)); + assertFalse(appliesSimpleCondition(EMPTY_BYTE_BUFFER, GTE, ONE)); + assertTrue(appliesSimpleCondition(EMPTY_BYTE_BUFFER, GTE, EMPTY_BYTE_BUFFER)); + assertThrowsIRE(() -> appliesSimpleCondition(ONE, GTE, null), "Invalid comparison with null for operator \">=\""); + assertFalse(appliesSimpleCondition(null, GTE, ONE)); } private static List list(ByteBuffer... values) @@ -246,88 +249,100 @@ public class ColumnConditionTest public void testListCollectionBoundAppliesTo() throws InvalidRequestException { // EQ - assertTrue(conditionApplies(list(ONE), EQ, list(ONE))); - assertTrue(conditionApplies(list(), EQ, list())); - assertFalse(conditionApplies(list(ONE), EQ, list(ZERO))); - assertFalse(conditionApplies(list(ZERO), EQ, list(ONE))); - assertFalse(conditionApplies(list(ONE, ONE), EQ, list(ONE))); - assertFalse(conditionApplies(list(ONE), EQ, list(ONE, ONE))); - assertFalse(conditionApplies(list(ONE), EQ, list())); - assertFalse(conditionApplies(list(), EQ, list(ONE))); + assertTrue(appliesListCondition(list(ONE), EQ, list(ONE))); + assertTrue(appliesListCondition(null, EQ, null)); + assertTrue(appliesListCondition(null, EQ, list())); + assertFalse(appliesListCondition(list(ONE), EQ, list(ZERO))); + assertFalse(appliesListCondition(list(ZERO), EQ, list(ONE))); + assertFalse(appliesListCondition(list(ONE, ONE), EQ, list(ONE))); + assertFalse(appliesListCondition(list(ONE), EQ, list(ONE, ONE))); + assertFalse(appliesListCondition(list(ONE), EQ, null)); + assertFalse(appliesListCondition(list(ONE), EQ, list())); + assertFalse(appliesListCondition(null, EQ, list(ONE))); - assertFalse(conditionApplies(list(ONE), EQ, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, list(ONE))); - assertTrue(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesListCondition(list(ONE), EQ, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, list(ONE))); + assertTrue(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // NEQ - assertFalse(conditionApplies(list(ONE), NEQ, list(ONE))); - assertFalse(conditionApplies(list(), NEQ, list())); - assertTrue(conditionApplies(list(ONE), NEQ, list(ZERO))); - assertTrue(conditionApplies(list(ZERO), NEQ, list(ONE))); - assertTrue(conditionApplies(list(ONE, ONE), NEQ, list(ONE))); - assertTrue(conditionApplies(list(ONE), NEQ, list(ONE, ONE))); - assertTrue(conditionApplies(list(ONE), NEQ, list())); - assertTrue(conditionApplies(list(), NEQ, list(ONE))); + assertFalse(appliesListCondition(list(ONE), NEQ, list(ONE))); + assertFalse(appliesListCondition(null, NEQ, null)); + assertFalse(appliesListCondition(null, NEQ, list())); + assertTrue(appliesListCondition(list(ONE), NEQ, list(ZERO))); + assertTrue(appliesListCondition(list(ZERO), NEQ, list(ONE))); + assertTrue(appliesListCondition(list(ONE, ONE), NEQ, list(ONE))); + assertTrue(appliesListCondition(list(ONE), NEQ, list(ONE, ONE))); + assertTrue(appliesListCondition(list(ONE), NEQ, null)); + assertTrue(appliesListCondition(list(ONE), NEQ, list())); + assertTrue(appliesListCondition(null, NEQ, list(ONE))); - assertTrue(conditionApplies(list(ONE), NEQ, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, list(ONE))); - assertFalse(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesListCondition(list(ONE), NEQ, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, list(ONE))); + assertFalse(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // LT - assertFalse(conditionApplies(list(ONE), LT, list(ONE))); - assertFalse(conditionApplies(list(), LT, list())); - assertFalse(conditionApplies(list(ONE), LT, list(ZERO))); - assertTrue(conditionApplies(list(ZERO), LT, list(ONE))); - assertFalse(conditionApplies(list(ONE, ONE), LT, list(ONE))); - assertTrue(conditionApplies(list(ONE), LT, list(ONE, ONE))); - assertFalse(conditionApplies(list(ONE), LT, list())); - assertTrue(conditionApplies(list(), LT, list(ONE))); + assertFalse(appliesListCondition(list(ONE), LT, list(ONE))); + assertThrowsIRE(() -> appliesListCondition(null, LT, null), "Invalid comparison with null for operator \"<\""); + assertThrowsIRE(() -> appliesListCondition(null, LT, list()), "Invalid comparison with an empty list for operator \"<\""); + assertFalse(appliesListCondition(list(ONE), LT, list(ZERO))); + assertTrue(appliesListCondition(list(ZERO), LT, list(ONE))); + assertFalse(appliesListCondition(list(ONE, ONE), LT, list(ONE))); + assertTrue(appliesListCondition(list(ONE), LT, list(ONE, ONE))); + assertThrowsIRE(() -> appliesListCondition(list(ONE), LT, null), "Invalid comparison with null for operator \"<\""); + assertThrowsIRE(() -> appliesListCondition(list(ONE), LT, list()), "Invalid comparison with an empty list for operator \"<\""); + assertFalse(appliesListCondition(null, LT, list(ONE))); - assertFalse(conditionApplies(list(ONE), LT, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, list(ONE))); - assertFalse(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesListCondition(list(ONE), LT, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, list(ONE))); + assertFalse(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // LTE - assertTrue(conditionApplies(list(ONE), LTE, list(ONE))); - assertTrue(conditionApplies(list(), LTE, list())); - assertFalse(conditionApplies(list(ONE), LTE, list(ZERO))); - assertTrue(conditionApplies(list(ZERO), LTE, list(ONE))); - assertFalse(conditionApplies(list(ONE, ONE), LTE, list(ONE))); - assertTrue(conditionApplies(list(ONE), LTE, list(ONE, ONE))); - assertFalse(conditionApplies(list(ONE), LTE, list())); - assertTrue(conditionApplies(list(), LTE, list(ONE))); + assertTrue(appliesListCondition(list(ONE), LTE, list(ONE))); + assertThrowsIRE(() -> appliesListCondition(null, LTE, null), "Invalid comparison with null for operator \"<=\""); + assertThrowsIRE(() -> appliesListCondition(null, LTE, list()), "Invalid comparison with an empty list for operator \"<=\""); + assertFalse(appliesListCondition(list(ONE), LTE, list(ZERO))); + assertTrue(appliesListCondition(list(ZERO), LTE, list(ONE))); + assertFalse(appliesListCondition(list(ONE, ONE), LTE, list(ONE))); + assertTrue(appliesListCondition(list(ONE), LTE, list(ONE, ONE))); + assertThrowsIRE(() -> appliesListCondition(list(ONE), LTE, null), "Invalid comparison with null for operator \"<=\""); + assertThrowsIRE(() -> appliesListCondition(list(ONE), LTE, list()), "Invalid comparison with an empty list for operator \"<=\""); + assertFalse(appliesListCondition(null, LTE, list(ONE))); - assertFalse(conditionApplies(list(ONE), LTE, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, list(ONE))); - assertTrue(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesListCondition(list(ONE), LTE, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, list(ONE))); + assertTrue(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // GT - assertFalse(conditionApplies(list(ONE), GT, list(ONE))); - assertFalse(conditionApplies(list(), GT, list())); - assertTrue(conditionApplies(list(ONE), GT, list(ZERO))); - assertFalse(conditionApplies(list(ZERO), GT, list(ONE))); - assertTrue(conditionApplies(list(ONE, ONE), GT, list(ONE))); - assertFalse(conditionApplies(list(ONE), GT, list(ONE, ONE))); - assertTrue(conditionApplies(list(ONE), GT, list())); - assertFalse(conditionApplies(list(), GT, list(ONE))); + assertFalse(appliesListCondition(list(ONE), GT, list(ONE))); + assertThrowsIRE(() -> appliesListCondition(null, GT, null), "Invalid comparison with null for operator \">\""); + assertThrowsIRE(() -> appliesListCondition(null, GT, list()), "Invalid comparison with an empty list for operator \">\""); + assertTrue(appliesListCondition(list(ONE), GT, list(ZERO))); + assertFalse(appliesListCondition(list(ZERO), GT, list(ONE))); + assertTrue(appliesListCondition(list(ONE, ONE), GT, list(ONE))); + assertFalse(appliesListCondition(list(ONE), GT, list(ONE, ONE))); + assertThrowsIRE(() -> appliesListCondition(list(ONE), GT, null), "Invalid comparison with null for operator \">\""); + assertThrowsIRE(() -> appliesListCondition(list(ONE), GT, list()), "Invalid comparison with an empty list for operator \">\""); + assertFalse(appliesListCondition(null, GT, list(ONE))); - assertTrue(conditionApplies(list(ONE), GT, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, list(ONE))); - assertFalse(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesListCondition(list(ONE), GT, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, list(ONE))); + assertFalse(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // GTE - assertTrue(conditionApplies(list(ONE), GTE, list(ONE))); - assertTrue(conditionApplies(list(), GTE, list())); - assertTrue(conditionApplies(list(ONE), GTE, list(ZERO))); - assertFalse(conditionApplies(list(ZERO), GTE, list(ONE))); - assertTrue(conditionApplies(list(ONE, ONE), GTE, list(ONE))); - assertFalse(conditionApplies(list(ONE), GTE, list(ONE, ONE))); - assertTrue(conditionApplies(list(ONE), GTE, list())); - assertFalse(conditionApplies(list(), GTE, list(ONE))); + assertTrue(appliesListCondition(list(ONE), GTE, list(ONE))); + assertThrowsIRE(() -> appliesListCondition(null, GTE, null), "Invalid comparison with null for operator \">=\""); + assertThrowsIRE(() -> appliesListCondition(null, GTE, list()), "Invalid comparison with an empty list for operator \">=\""); + assertTrue(appliesListCondition(list(ONE), GTE, list(ZERO))); + assertFalse(appliesListCondition(list(ZERO), GTE, list(ONE))); + assertTrue(appliesListCondition(list(ONE, ONE), GTE, list(ONE))); + assertFalse(appliesListCondition(list(ONE), GTE, list(ONE, ONE))); + assertThrowsIRE(() -> appliesListCondition(list(ONE), GTE, null), "Invalid comparison with null for operator \">=\""); + assertThrowsIRE(() -> appliesListCondition(list(ONE), GTE, list()), "Invalid comparison with an empty list for operator \">=\""); + assertFalse(appliesListCondition(null, GTE, list(ONE))); - assertTrue(conditionApplies(list(ONE), GTE, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, list(ONE))); - assertTrue(conditionApplies(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesListCondition(list(ONE), GTE, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, list(ONE))); + assertTrue(appliesListCondition(list(ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); } private static SortedSet set(ByteBuffer... values) @@ -341,88 +356,100 @@ public class ColumnConditionTest public void testSetCollectionBoundAppliesTo() throws InvalidRequestException { // EQ - assertTrue(conditionApplies(set(ONE), EQ, set(ONE))); - assertTrue(conditionApplies(set(), EQ, set())); - assertFalse(conditionApplies(set(ONE), EQ, set(ZERO))); - assertFalse(conditionApplies(set(ZERO), EQ, set(ONE))); - assertFalse(conditionApplies(set(ONE, TWO), EQ, set(ONE))); - assertFalse(conditionApplies(set(ONE), EQ, set(ONE, TWO))); - assertFalse(conditionApplies(set(ONE), EQ, set())); - assertFalse(conditionApplies(set(), EQ, set(ONE))); + assertTrue(appliesSetCondition(set(ONE), EQ, set(ONE))); + assertTrue(appliesSetCondition(null, EQ, null)); + assertTrue(appliesSetCondition(null, EQ, set())); + assertFalse(appliesSetCondition(set(ONE), EQ, set(ZERO))); + assertFalse(appliesSetCondition(set(ZERO), EQ, set(ONE))); + assertFalse(appliesSetCondition(set(ONE, TWO), EQ, set(ONE))); + assertFalse(appliesSetCondition(set(ONE), EQ, set(ONE, TWO))); + assertFalse(appliesSetCondition(set(ONE), EQ, null)); + assertFalse(appliesSetCondition(set(ONE), EQ, set())); + assertFalse(appliesSetCondition(null, EQ, set(ONE))); - assertFalse(conditionApplies(set(ONE), EQ, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, set(ONE))); - assertTrue(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesSetCondition(set(ONE), EQ, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, set(ONE))); + assertTrue(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // NEQ - assertFalse(conditionApplies(set(ONE), NEQ, set(ONE))); - assertFalse(conditionApplies(set(), NEQ, set())); - assertTrue(conditionApplies(set(ONE), NEQ, set(ZERO))); - assertTrue(conditionApplies(set(ZERO), NEQ, set(ONE))); - assertTrue(conditionApplies(set(ONE, TWO), NEQ, set(ONE))); - assertTrue(conditionApplies(set(ONE), NEQ, set(ONE, TWO))); - assertTrue(conditionApplies(set(ONE), NEQ, set())); - assertTrue(conditionApplies(set(), NEQ, set(ONE))); + assertFalse(appliesSetCondition(set(ONE), NEQ, set(ONE))); + assertFalse(appliesSetCondition(null, NEQ, null)); + assertFalse(appliesSetCondition(null, NEQ, set())); + assertTrue(appliesSetCondition(set(ONE), NEQ, set(ZERO))); + assertTrue(appliesSetCondition(set(ZERO), NEQ, set(ONE))); + assertTrue(appliesSetCondition(set(ONE, TWO), NEQ, set(ONE))); + assertTrue(appliesSetCondition(set(ONE), NEQ, set(ONE, TWO))); + assertTrue(appliesSetCondition(set(ONE), NEQ, null)); + assertTrue(appliesSetCondition(set(ONE), NEQ, set())); + assertTrue(appliesSetCondition(null, NEQ, set(ONE))); - assertTrue(conditionApplies(set(ONE), NEQ, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, set(ONE))); - assertFalse(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesSetCondition(set(ONE), NEQ, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, set(ONE))); + assertFalse(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // LT - assertFalse(conditionApplies(set(ONE), LT, set(ONE))); - assertFalse(conditionApplies(set(), LT, set())); - assertFalse(conditionApplies(set(ONE), LT, set(ZERO))); - assertTrue(conditionApplies(set(ZERO), LT, set(ONE))); - assertFalse(conditionApplies(set(ONE, TWO), LT, set(ONE))); - assertTrue(conditionApplies(set(ONE), LT, set(ONE, TWO))); - assertFalse(conditionApplies(set(ONE), LT, set())); - assertTrue(conditionApplies(set(), LT, set(ONE))); + assertFalse(appliesSetCondition(set(ONE), LT, set(ONE))); + assertThrowsIRE(() -> appliesSetCondition(null, LT, null), "Invalid comparison with null for operator \"<\""); + assertThrowsIRE(() -> appliesSetCondition(null, LT, set()), "Invalid comparison with an empty set for operator \"<\""); + assertFalse(appliesSetCondition(set(ONE), LT, set(ZERO))); + assertTrue(appliesSetCondition(set(ZERO), LT, set(ONE))); + assertFalse(appliesSetCondition(set(ONE, TWO), LT, set(ONE))); + assertTrue(appliesSetCondition(set(ONE), LT, set(ONE, TWO))); + assertThrowsIRE(() -> appliesSetCondition(set(ONE), LT, null), "Invalid comparison with null for operator \"<\""); + assertThrowsIRE(() -> appliesSetCondition(set(ONE), LT, set()), "Invalid comparison with an empty set for operator \"<\""); + assertFalse(appliesSetCondition(null, LT, set(ONE))); - assertFalse(conditionApplies(set(ONE), LT, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, set(ONE))); - assertFalse(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesSetCondition(set(ONE), LT, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, set(ONE))); + assertFalse(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // LTE - assertTrue(conditionApplies(set(ONE), LTE, set(ONE))); - assertTrue(conditionApplies(set(), LTE, set())); - assertFalse(conditionApplies(set(ONE), LTE, set(ZERO))); - assertTrue(conditionApplies(set(ZERO), LTE, set(ONE))); - assertFalse(conditionApplies(set(ONE, TWO), LTE, set(ONE))); - assertTrue(conditionApplies(set(ONE), LTE, set(ONE, TWO))); - assertFalse(conditionApplies(set(ONE), LTE, set())); - assertTrue(conditionApplies(set(), LTE, set(ONE))); + assertTrue(appliesSetCondition(set(ONE), LTE, set(ONE))); + assertThrowsIRE(() -> appliesSetCondition(null, LTE, null), "Invalid comparison with null for operator \"<=\""); + assertThrowsIRE(() -> appliesSetCondition(null, LTE, set()), "Invalid comparison with an empty set for operator \"<=\""); + assertFalse(appliesSetCondition(set(ONE), LTE, set(ZERO))); + assertTrue(appliesSetCondition(set(ZERO), LTE, set(ONE))); + assertFalse(appliesSetCondition(set(ONE, TWO), LTE, set(ONE))); + assertTrue(appliesSetCondition(set(ONE), LTE, set(ONE, TWO))); + assertThrowsIRE(() -> appliesSetCondition(set(ONE), LTE, null), "Invalid comparison with null for operator \"<=\""); + assertThrowsIRE(() -> appliesSetCondition(set(ONE), LTE, set()), "Invalid comparison with an empty set for operator \"<=\""); + assertFalse(appliesSetCondition(null, LTE, set(ONE))); - assertFalse(conditionApplies(set(ONE), LTE, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, set(ONE))); - assertTrue(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesSetCondition(set(ONE), LTE, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, set(ONE))); + assertTrue(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // GT - assertFalse(conditionApplies(set(ONE), GT, set(ONE))); - assertFalse(conditionApplies(set(), GT, set())); - assertTrue(conditionApplies(set(ONE), GT, set(ZERO))); - assertFalse(conditionApplies(set(ZERO), GT, set(ONE))); - assertTrue(conditionApplies(set(ONE, TWO), GT, set(ONE))); - assertFalse(conditionApplies(set(ONE), GT, set(ONE, TWO))); - assertTrue(conditionApplies(set(ONE), GT, set())); - assertFalse(conditionApplies(set(), GT, set(ONE))); + assertFalse(appliesSetCondition(set(ONE), GT, set(ONE))); + assertThrowsIRE(() -> appliesSetCondition(null, GT, null), "Invalid comparison with null for operator \">\""); + assertThrowsIRE(() -> appliesSetCondition(null, GT, set()), "Invalid comparison with an empty set for operator \">\""); + assertTrue(appliesSetCondition(set(ONE), GT, set(ZERO))); + assertFalse(appliesSetCondition(set(ZERO), GT, set(ONE))); + assertTrue(appliesSetCondition(set(ONE, TWO), GT, set(ONE))); + assertFalse(appliesSetCondition(set(ONE), GT, set(ONE, TWO))); + assertThrowsIRE(() -> appliesSetCondition(set(ONE), GT, null), "Invalid comparison with null for operator \">\""); + assertThrowsIRE(() -> appliesSetCondition(set(ONE), GT, set()), "Invalid comparison with an empty set for operator \">\""); + assertFalse(appliesSetCondition(null, GT, set(ONE))); - assertTrue(conditionApplies(set(ONE), GT, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, set(ONE))); - assertFalse(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesSetCondition(set(ONE), GT, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, set(ONE))); + assertFalse(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); // GTE - assertTrue(conditionApplies(set(ONE), GTE, set(ONE))); - assertTrue(conditionApplies(set(), GTE, set())); - assertTrue(conditionApplies(set(ONE), GTE, set(ZERO))); - assertFalse(conditionApplies(set(ZERO), GTE, set(ONE))); - assertTrue(conditionApplies(set(ONE, TWO), GTE, set(ONE))); - assertFalse(conditionApplies(set(ONE), GTE, set(ONE, TWO))); - assertTrue(conditionApplies(set(ONE), GTE, set())); - assertFalse(conditionApplies(set(), GTE, set(ONE))); + assertTrue(appliesSetCondition(set(ONE), GTE, set(ONE))); + assertThrowsIRE(() -> appliesSetCondition(null, GTE, null), "Invalid comparison with null for operator \">=\""); + assertThrowsIRE(() -> appliesSetCondition(null, GTE, set()), "Invalid comparison with an empty set for operator \">=\""); + assertTrue(appliesSetCondition(set(ONE), GTE, set(ZERO))); + assertFalse(appliesSetCondition(set(ZERO), GTE, set(ONE))); + assertTrue(appliesSetCondition(set(ONE, TWO), GTE, set(ONE))); + assertFalse(appliesSetCondition(set(ONE), GTE, set(ONE, TWO))); + assertThrowsIRE(() -> appliesSetCondition(set(ONE), GTE, null), "Invalid comparison with null for operator \">=\""); + assertThrowsIRE(() -> appliesSetCondition(set(ONE), GTE, set()), "Invalid comparison with an empty set for operator \">=\""); + assertFalse(appliesSetCondition(null, GTE, set(ONE))); - assertTrue(conditionApplies(set(ONE), GTE, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, set(ONE))); - assertTrue(conditionApplies(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesSetCondition(set(ONE), GTE, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, set(ONE))); + assertTrue(appliesSetCondition(set(ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, set(ByteBufferUtil.EMPTY_BYTE_BUFFER))); } // values should be a list of key, value, key, value, ... @@ -439,117 +466,129 @@ public class ColumnConditionTest public void testMapCollectionBoundIsSatisfiedByValue() throws InvalidRequestException { // EQ - assertTrue(conditionApplies(map(ONE, ONE), EQ, map(ONE, ONE))); - assertTrue(conditionApplies(map(), EQ, map())); - assertFalse(conditionApplies(map(ONE, ONE), EQ, map(ZERO, ONE))); - assertFalse(conditionApplies(map(ZERO, ONE), EQ, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), EQ, map(ONE, ZERO))); - assertFalse(conditionApplies(map(ONE, ZERO), EQ, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE, TWO, ONE), EQ, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), EQ, map(ONE, ONE, TWO, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), EQ, map())); - assertFalse(conditionApplies(map(), EQ, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), EQ, map(ONE, ONE))); + assertTrue(appliesMapCondition(null, EQ, null)); + assertTrue(appliesMapCondition(null, EQ, map())); + assertFalse(appliesMapCondition(map(ONE, ONE), EQ, map(ZERO, ONE))); + assertFalse(appliesMapCondition(map(ZERO, ONE), EQ, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), EQ, map(ONE, ZERO))); + assertFalse(appliesMapCondition(map(ONE, ZERO), EQ, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE, TWO, ONE), EQ, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), EQ, map(ONE, ONE, TWO, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), EQ, null)); + assertFalse(appliesMapCondition(map(ONE, ONE), EQ, map())); + assertFalse(appliesMapCondition(null, EQ, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), EQ, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertFalse(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), EQ, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), EQ, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, map(ONE, ONE))); - assertTrue(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), EQ, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertTrue(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesMapCondition(map(ONE, ONE), EQ, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertFalse(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), EQ, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), EQ, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), EQ, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertTrue(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), EQ, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); // NEQ - assertFalse(conditionApplies(map(ONE, ONE), NEQ, map(ONE, ONE))); - assertFalse(conditionApplies(map(), NEQ, map())); - assertTrue(conditionApplies(map(ONE, ONE), NEQ, map(ZERO, ONE))); - assertTrue(conditionApplies(map(ZERO, ONE), NEQ, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), NEQ, map(ONE, ZERO))); - assertTrue(conditionApplies(map(ONE, ZERO), NEQ, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE, TWO, ONE), NEQ, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), NEQ, map(ONE, ONE, TWO, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), NEQ, map())); - assertTrue(conditionApplies(map(), NEQ, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), NEQ, map(ONE, ONE))); + assertFalse(appliesMapCondition(null, NEQ, null)); + assertFalse(appliesMapCondition(null, NEQ, map())); + assertTrue(appliesMapCondition(map(ONE, ONE), NEQ, map(ZERO, ONE))); + assertTrue(appliesMapCondition(map(ZERO, ONE), NEQ, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), NEQ, map(ONE, ZERO))); + assertTrue(appliesMapCondition(map(ONE, ZERO), NEQ, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE, TWO, ONE), NEQ, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), NEQ, map(ONE, ONE, TWO, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), NEQ, null)); + assertTrue(appliesMapCondition(map(ONE, ONE), NEQ, map())); + assertTrue(appliesMapCondition(null, NEQ, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), NEQ, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertTrue(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), NEQ, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), NEQ, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, map(ONE, ONE))); - assertFalse(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), NEQ, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertFalse(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesMapCondition(map(ONE, ONE), NEQ, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertTrue(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), NEQ, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), NEQ, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), NEQ, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertFalse(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), NEQ, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); // LT - assertFalse(conditionApplies(map(ONE, ONE), LT, map(ONE, ONE))); - assertFalse(conditionApplies(map(), LT, map())); - assertFalse(conditionApplies(map(ONE, ONE), LT, map(ZERO, ONE))); - assertTrue(conditionApplies(map(ZERO, ONE), LT, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), LT, map(ONE, ZERO))); - assertTrue(conditionApplies(map(ONE, ZERO), LT, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE, TWO, ONE), LT, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), LT, map(ONE, ONE, TWO, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), LT, map())); - assertTrue(conditionApplies(map(), LT, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), LT, map(ONE, ONE))); + assertThrowsIRE(() -> appliesMapCondition(null, LT, null), "Invalid comparison with null for operator \"<\""); + assertThrowsIRE(() -> appliesMapCondition(null, LT, map()), "Invalid comparison with an empty map for operator \"<\""); + assertFalse(appliesMapCondition(map(ONE, ONE), LT, map(ZERO, ONE))); + assertTrue(appliesMapCondition(map(ZERO, ONE), LT, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), LT, map(ONE, ZERO))); + assertTrue(appliesMapCondition(map(ONE, ZERO), LT, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE, TWO, ONE), LT, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), LT, map(ONE, ONE, TWO, ONE))); + assertThrowsIRE(() -> appliesMapCondition(map(ONE, ONE), LT, null), "Invalid comparison with null for operator \"<\""); + assertThrowsIRE(() -> appliesMapCondition(map(ONE, ONE), LT, map()), "Invalid comparison with an empty map for operator \"<\""); + assertFalse(appliesMapCondition(null, LT, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), LT, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertTrue(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), LT, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), LT, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, map(ONE, ONE))); - assertFalse(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), LT, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertFalse(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesMapCondition(map(ONE, ONE), LT, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertTrue(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), LT, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), LT, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), LT, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertFalse(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), LT, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); // LTE - assertTrue(conditionApplies(map(ONE, ONE), LTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(), LTE, map())); - assertFalse(conditionApplies(map(ONE, ONE), LTE, map(ZERO, ONE))); - assertTrue(conditionApplies(map(ZERO, ONE), LTE, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), LTE, map(ONE, ZERO))); - assertTrue(conditionApplies(map(ONE, ZERO), LTE, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE, TWO, ONE), LTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), LTE, map(ONE, ONE, TWO, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), LTE, map())); - assertTrue(conditionApplies(map(), LTE, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), LTE, map(ONE, ONE))); + assertThrowsIRE(() -> appliesMapCondition(null, LTE, null), "Invalid comparison with null for operator \"<=\""); + assertThrowsIRE(() -> appliesMapCondition(null, LTE, map()), "Invalid comparison with an empty map for operator \"<=\""); + assertFalse(appliesMapCondition(map(ONE, ONE), LTE, map(ZERO, ONE))); + assertTrue(appliesMapCondition(map(ZERO, ONE), LTE, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), LTE, map(ONE, ZERO))); + assertTrue(appliesMapCondition(map(ONE, ZERO), LTE, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE, TWO, ONE), LTE, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), LTE, map(ONE, ONE, TWO, ONE))); + assertThrowsIRE(() -> appliesMapCondition(map(ONE, ONE), LTE, null), "Invalid comparison with null for operator \"<=\""); + assertThrowsIRE(() -> appliesMapCondition(map(ONE, ONE), LTE, map()), "Invalid comparison with an empty map for operator \"<=\""); + assertFalse(appliesMapCondition(null, LTE, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), LTE, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertTrue(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), LTE, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), LTE, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertTrue(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), LTE, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertTrue(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesMapCondition(map(ONE, ONE), LTE, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertTrue(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), LTE, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), LTE, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), LTE, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertTrue(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), LTE, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); // GT - assertFalse(conditionApplies(map(ONE, ONE), GT, map(ONE, ONE))); - assertFalse(conditionApplies(map(), GT, map())); - assertTrue(conditionApplies(map(ONE, ONE), GT, map(ZERO, ONE))); - assertFalse(conditionApplies(map(ZERO, ONE), GT, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), GT, map(ONE, ZERO))); - assertFalse(conditionApplies(map(ONE, ZERO), GT, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE, TWO, ONE), GT, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), GT, map(ONE, ONE, TWO, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), GT, map())); - assertFalse(conditionApplies(map(), GT, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), GT, map(ONE, ONE))); + assertThrowsIRE(() -> appliesMapCondition(null, GT, null), "Invalid comparison with null for operator \">\""); + assertThrowsIRE(() -> appliesMapCondition(null, GT, map()), "Invalid comparison with an empty map for operator \">\""); + assertTrue(appliesMapCondition(map(ONE, ONE), GT, map(ZERO, ONE))); + assertFalse(appliesMapCondition(map(ZERO, ONE), GT, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), GT, map(ONE, ZERO))); + assertFalse(appliesMapCondition(map(ONE, ZERO), GT, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE, TWO, ONE), GT, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), GT, map(ONE, ONE, TWO, ONE))); + assertThrowsIRE(() -> appliesMapCondition(map(ONE, ONE), GT, null), "Invalid comparison with null for operator \">\""); + assertThrowsIRE(() -> appliesMapCondition(map(ONE, ONE), GT, map()), "Invalid comparison with an empty map for operator \">\""); + assertFalse(appliesMapCondition(null, GT, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), GT, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertFalse(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), GT, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), GT, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, map(ONE, ONE))); - assertFalse(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), GT, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertFalse(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesMapCondition(map(ONE, ONE), GT, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertFalse(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), GT, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), GT, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), GT, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertFalse(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), GT, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); // GTE - assertTrue(conditionApplies(map(ONE, ONE), GTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(), GTE, map())); - assertTrue(conditionApplies(map(ONE, ONE), GTE, map(ZERO, ONE))); - assertFalse(conditionApplies(map(ZERO, ONE), GTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), GTE, map(ONE, ZERO))); - assertFalse(conditionApplies(map(ONE, ZERO), GTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE, TWO, ONE), GTE, map(ONE, ONE))); - assertFalse(conditionApplies(map(ONE, ONE), GTE, map(ONE, ONE, TWO, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), GTE, map())); - assertFalse(conditionApplies(map(), GTE, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), GTE, map(ONE, ONE))); + assertThrowsIRE(() -> appliesMapCondition(null, GTE, null), "Invalid comparison with null for operator \">=\""); + assertThrowsIRE(() -> appliesMapCondition(null, GTE, map()), "Invalid comparison with an empty map for operator \">=\""); + assertTrue(appliesMapCondition(map(ONE, ONE), GTE, map(ZERO, ONE))); + assertFalse(appliesMapCondition(map(ZERO, ONE), GTE, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), GTE, map(ONE, ZERO))); + assertFalse(appliesMapCondition(map(ONE, ZERO), GTE, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE, TWO, ONE), GTE, map(ONE, ONE))); + assertFalse(appliesMapCondition(map(ONE, ONE), GTE, map(ONE, ONE, TWO, ONE))); + assertThrowsIRE(() -> appliesMapCondition(map(ONE, ONE), GTE, null), "Invalid comparison with null for operator \">=\""); + assertThrowsIRE(() -> appliesMapCondition(map(ONE, ONE), GTE, map()), "Invalid comparison with an empty map for operator \">=\""); + assertFalse(appliesMapCondition(null, GTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), GTE, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertFalse(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), GTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(ONE, ONE), GTE, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); - assertFalse(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, map(ONE, ONE))); - assertTrue(conditionApplies(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), GTE, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); - assertTrue(conditionApplies(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertTrue(appliesMapCondition(map(ONE, ONE), GTE, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertFalse(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), GTE, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ONE, ONE), GTE, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); + assertFalse(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, map(ONE, ONE))); + assertTrue(appliesMapCondition(map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE), GTE, map(ByteBufferUtil.EMPTY_BYTE_BUFFER, ONE))); + assertTrue(appliesMapCondition(map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER), GTE, map(ONE, ByteBufferUtil.EMPTY_BYTE_BUFFER))); } } diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionCollectionsTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionCollectionsTest.java index 7ad41e3084..9e316a5814 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionCollectionsTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionCollectionsTest.java @@ -767,23 +767,148 @@ public class InsertUpdateIfConditionCollectionsTest extends CQLTester } @Test - public void testFrozenWithNullValues() throws Throwable + public void testListConditionsWithNullValues() throws Throwable { - createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, m %s)", "frozen>")); - execute("INSERT INTO %s (k, m) VALUES (0, null)"); + for (boolean frozen : new boolean[]{true, false}) + { + String type = frozen ? "frozen>" : "list"; + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, l %s)", type)); + execute("INSERT INTO %s (k, l) VALUES (0, null)"); + execute("INSERT INTO %s (k, l) VALUES (1, null)"); - assertRows(execute("UPDATE %s SET m = ? WHERE k = 0 IF m = ?", list("test"), list("comparison")), row(false, null)); + for (String operator : new String[]{ ">", "<", ">=", "<=", "=" }) + { + assertRows(execute("UPDATE %s SET l = ? WHERE k = 0 IF l " + operator + " ?", list("test"), list("comparison")), row(false, null)); + } - createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, m %s)", "frozen>")); - execute("INSERT INTO %s (k, m) VALUES (0, null)"); + assertRows(execute("UPDATE %s SET l = ? WHERE k = 0 IF l != NULL", list("test")), row(false, null)); + assertRows(execute("UPDATE %s SET l = ? WHERE k = 0 IF l = NULL", list("test")), row(true)); + assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("test"))); - assertRows(execute("UPDATE %s SET m = ? WHERE k = 0 IF m = ?", map("test", 3), map("comparison", 2)), row(false, null)); + if (!frozen) + { + assertRows(execute("UPDATE %s SET l = ? WHERE k = 1 IF l != []", list("test")), row(false, null)); + assertRows(execute("UPDATE %s SET l = ? WHERE k = 1 IF l = []", list("test")), row(true)); + assertRows(execute("SELECT l FROM %s WHERE k = 1"), row(list("test"))); + } - createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, m %s)", "frozen>")); - execute("INSERT INTO %s (k, m) VALUES (0, null)"); + for (String operator : new String[]{ ">", "<", ">=", "<=" }) + { + assertInvalidMessage("Invalid comparison with null for operator \"" + operator + '"', + "UPDATE %s SET l = ? WHERE k = 0 IF l " + operator + " NULL", list("test")); - assertRows(execute("UPDATE %s SET m = ? WHERE k = 0 IF m = ?", set("test"), set("comparison")), row(false, null)); + if (!frozen) + assertInvalidMessage("Invalid comparison with an empty list for operator \"" + operator + '"', + "UPDATE %s SET l = ? WHERE k = 0 IF l " + operator + " []", list("test")); + } + } } + + @Test + public void testSetConditionsWithNullValues() throws Throwable + { + for (boolean frozen : new boolean[]{true, false}) + { + String type = frozen ? "frozen>" : "set"; + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, s %s)", type)); + execute("INSERT INTO %s (k, s) VALUES (0, null)"); + execute("INSERT INTO %s (k, s) VALUES (1, null)"); + + for (String operator : new String[]{ ">", "<", ">=", "<=", "=" }) + { + assertRows(execute("UPDATE %s SET s = ? WHERE k = 0 IF s " + operator + " ?", set("test"), set("comparison")), row(false, null)); + } + + assertRows(execute("UPDATE %s SET s = ? WHERE k = 0 IF s != NULL", set("test")), row(false, null)); + assertRows(execute("UPDATE %s SET s = ? WHERE k = 0 IF s = NULL", set("test")), row(true)); + assertRows(execute("SELECT s FROM %s WHERE k = 0"), row(set("test"))); + + if (!frozen) + { + assertRows(execute("UPDATE %s SET s = ? WHERE k = 1 IF s != {}", set("test")), row(false, null)); + assertRows(execute("UPDATE %s SET s = ? WHERE k = 1 IF s = {}", set("test")), row(true)); + assertRows(execute("SELECT s FROM %s WHERE k = 1"), row(set("test"))); + } + + for (String operator : new String[]{ ">", "<", ">=", "<=" }) + { + assertInvalidMessage("Invalid comparison with null for operator \"" + operator + '"', + "UPDATE %s SET s = ? WHERE k = 0 IF s " + operator + " NULL", set("test")); + + if (!frozen) + assertInvalidMessage("Invalid comparison with an empty set for operator \"" + operator + '"', + "UPDATE %s SET s = ? WHERE k = 0 IF s " + operator + " {}", set("test")); + } + } + } + + @Test + public void testMapConditionsWithNullValues() throws Throwable + { + for (boolean frozen : new boolean[]{true, false}) + { + String type = frozen ? "frozen>" : "map"; + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, m %s)", type)); + execute("INSERT INTO %s (k, m) VALUES (0, null)"); + execute("INSERT INTO %s (k, m) VALUES (1, null)"); + + for (String operator : new String[]{ ">", "<", ">=", "<=", "=" }) + { + assertRows(execute("UPDATE %s SET m = ? WHERE k = 0 IF m " + operator + " ?", map("test", 3), map("comparison", 2)), row(false, null)); + } + + assertRows(execute("UPDATE %s SET m = ? WHERE k = 0 IF m != NULL", map("test", 3)), row(false, null)); + assertRows(execute("UPDATE %s SET m = ? WHERE k = 0 IF m = NULL", map("test", 3)), row(true)); + assertRows(execute("SELECT m FROM %s WHERE k = 0"), row(map("test", 3))); + + if (!frozen) + { + assertRows(execute("UPDATE %s SET m = ? WHERE k = 1 IF m != {}", map("test", 3)), row(false, null)); + assertRows(execute("UPDATE %s SET m = ? WHERE k = 1 IF m = {}", map("test", 3)), row(true)); + assertRows(execute("SELECT m FROM %s WHERE k = 1"), row(map("test", 3))); + } + + for (String operator : new String[]{ ">", "<", ">=", "<=" }) + { + assertInvalidMessage("Invalid comparison with null for operator \"" + operator + '"', + "UPDATE %s SET m = ? WHERE k = 0 IF m " + operator + " NULL", map("test", 3)); + + if (!frozen) + assertInvalidMessage("Invalid comparison with an empty map for operator \"" + operator + '"', + "UPDATE %s SET m = ? WHERE k = 0 IF m " + operator + " {}", map("test", 3)); + } + } + } + + @Test + public void testUdtConditionsWithNullValues() throws Throwable + { + for (boolean frozen : new boolean[]{true, false}) + { + String userType = createType("CREATE TYPE %s (a int, b int)"); + String type = frozen ? "frozen<" + userType + '>' : userType; + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, t %s)", type)); + execute("INSERT INTO %s (k, t) VALUES (0, null)"); + + for (String operator : new String[]{ ">", "<", ">=", "<=", "=" }) + { + assertRows(execute("UPDATE %s SET t = ? WHERE k = 0 IF t " + operator + " ?", + userType("a", 1, "b", 2), userType("a", 4, "b", 5)), + row(false, null)); + } + + assertRows(execute("UPDATE %s SET t = ? WHERE k = 0 IF t != NULL", userType("a", 1, "b", 2)), row(false, null)); + assertRows(execute("UPDATE %s SET t = ? WHERE k = 0 IF t = NULL", userType("a", 1, "b", 2)), row(true)); + assertRows(execute("SELECT t FROM %s WHERE k = 0"), row(userType("a", 1, "b", 2))); + + for (String operator : new String[]{ ">", "<", ">=", "<=" }) + { + assertInvalidMessage("Invalid comparison with null for operator \"" + operator + '"', + "UPDATE %s SET t = ? WHERE k = 0 IF t " + operator + " NULL", userType("a", 1, "b", 2)); + } + } + } + /** * Test expanded functionality from CASSANDRA-6839, * migrated from cql_tests.py:TestCQL.expanded_map_item_conditional_test()