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 D9C2F200C06 for ; Fri, 27 Jan 2017 15:51:41 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id D8699160B47; Fri, 27 Jan 2017 14:51:41 +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 371A2160B61 for ; Fri, 27 Jan 2017 15:51:40 +0100 (CET) Received: (qmail 45571 invoked by uid 500); 27 Jan 2017 14:51:39 -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 45435 invoked by uid 99); 27 Jan 2017 14:51:38 -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; Fri, 27 Jan 2017 14:51:38 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id CAE1EDFC2A; Fri, 27 Jan 2017 14:51:38 +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: Fri, 27 Jan 2017 14:51:42 -0000 Message-Id: In-Reply-To: <11125bf9bcd240d8babf4c3b49ed8c95@git.apache.org> References: <11125bf9bcd240d8babf4c3b49ed8c95@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [5/7] cassandra git commit: Refactor ColumnCondition archived-at: Fri, 27 Jan 2017 14:51:42 -0000 http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/test/unit/org/apache/cassandra/cql3/conditions/ColumnConditionTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/conditions/ColumnConditionTest.java b/test/unit/org/apache/cassandra/cql3/conditions/ColumnConditionTest.java new file mode 100644 index 0000000..5822027 --- /dev/null +++ b/test/unit/org/apache/cassandra/cql3/conditions/ColumnConditionTest.java @@ -0,0 +1,557 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.cql3.conditions; + +import java.nio.ByteBuffer; +import java.util.*; + +import org.junit.Assert; +import org.junit.Test; + +import org.apache.cassandra.config.ColumnDefinition; +import org.apache.cassandra.cql3.*; +import org.apache.cassandra.cql3.Constants.Value; +import org.apache.cassandra.cql3.conditions.ColumnCondition; +import org.apache.cassandra.db.Clustering; +import org.apache.cassandra.db.marshal.Int32Type; +import org.apache.cassandra.db.marshal.ListType; +import org.apache.cassandra.db.marshal.MapType; +import org.apache.cassandra.db.marshal.SetType; +import org.apache.cassandra.db.rows.*; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.serializers.TimeUUIDSerializer; +import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.UUIDGen; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import static org.apache.cassandra.cql3.Operator.*; +import static org.apache.cassandra.utils.ByteBufferUtil.EMPTY_BYTE_BUFFER; + + +public class ColumnConditionTest +{ + public static final ByteBuffer ZERO = Int32Type.instance.fromString("0"); + public static final ByteBuffer ONE = Int32Type.instance.fromString("1"); + public static final ByteBuffer TWO = Int32Type.instance.fromString("2"); + + private static Row newRow(ColumnDefinition definition, ByteBuffer value) + { + BufferCell cell = new BufferCell(definition, 0L, Cell.NO_TTL, Cell.NO_DELETION_TIME, value, null); + return BTreeRow.singleCellRow(Clustering.EMPTY, cell); + } + + private static Row newRow(ColumnDefinition definition, List values) + { + Row.Builder builder = BTreeRow.sortedBuilder(); + builder.newRow(Clustering.EMPTY); + long now = System.currentTimeMillis(); + if (values != null) + { + for (int i = 0, m = values.size(); i < m; i++) + { + UUID uuid = UUIDGen.getTimeUUID(now, i); + ByteBuffer key = TimeUUIDSerializer.instance.serialize(uuid); + ByteBuffer value = values.get(i); + BufferCell cell = new BufferCell(definition, + 0L, + Cell.NO_TTL, + Cell.NO_DELETION_TIME, + value, + CellPath.create(key)); + builder.addCell(cell); + } + } + return builder.build(); + } + + private static Row newRow(ColumnDefinition definition, SortedSet values) + { + Row.Builder builder = BTreeRow.sortedBuilder(); + builder.newRow(Clustering.EMPTY); + if (values != null) + { + for (ByteBuffer value : values) + { + BufferCell cell = new BufferCell(definition, + 0L, + Cell.NO_TTL, + Cell.NO_DELETION_TIME, + ByteBufferUtil.EMPTY_BYTE_BUFFER, + CellPath.create(value)); + builder.addCell(cell); + } + } + return builder.build(); + } + + private static Row newRow(ColumnDefinition definition, Map values) + { + Row.Builder builder = BTreeRow.sortedBuilder(); + builder.newRow(Clustering.EMPTY); + if (values != null) + { + for (Map.Entry entry : values.entrySet()) + { + BufferCell cell = new BufferCell(definition, + 0L, + Cell.NO_TTL, + Cell.NO_DELETION_TIME, + entry.getValue(), + CellPath.create(entry.getKey())); + builder.addCell(cell); + } + } + return builder.build(); + } + + private static boolean conditionApplies(ByteBuffer rowValue, Operator op, ByteBuffer conditionValue) + { + ColumnDefinition definition = ColumnDefinition.regularDef("ks", "cf", "c", Int32Type.instance); + ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(new Constants.Value(conditionValue))); + ColumnCondition.Bound bound = condition.bind(QueryOptions.DEFAULT); + return bound.appliesTo(newRow(definition, rowValue)); + } + + private static boolean conditionApplies(List rowValue, Operator op, List conditionValue) + { + ColumnDefinition definition = ColumnDefinition.regularDef("ks", "cf", "c", ListType.getInstance(Int32Type.instance, true)); + ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(new Lists.Value(conditionValue))); + ColumnCondition.Bound bound = condition.bind(QueryOptions.DEFAULT); + return bound.appliesTo(newRow(definition, rowValue)); + } + + private static boolean conditionApplies(SortedSet rowValue, Operator op, SortedSet conditionValue) + { + ColumnDefinition definition = ColumnDefinition.regularDef("ks", "cf", "c", SetType.getInstance(Int32Type.instance, true)); + ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(new Sets.Value(conditionValue))); + ColumnCondition.Bound bound = condition.bind(QueryOptions.DEFAULT); + return bound.appliesTo(newRow(definition, rowValue)); + } + + private static boolean conditionApplies(Map rowValue, Operator op, Map conditionValue) + { + ColumnDefinition definition = ColumnDefinition.regularDef("ks", "cf", "c", MapType.getInstance(Int32Type.instance, Int32Type.instance, true)); + ColumnCondition condition = ColumnCondition.condition(definition, op, Terms.of(new Maps.Value(conditionValue))); + ColumnCondition.Bound bound = condition.bind(QueryOptions.DEFAULT); + return bound.appliesTo(newRow(definition, rowValue)); + } + + @FunctionalInterface + public interface CheckedFunction { + void apply(); + } + + private static void assertThrowsIRE(CheckedFunction runnable, String errorMessage) + { + try + { + runnable.apply(); + fail("Expected InvalidRequestException was not thrown"); + } catch (InvalidRequestException e) + { + Assert.assertTrue("Expected error message to contain '" + errorMessage + "', but got '" + e.getMessage() + "'", + e.getMessage().contains(errorMessage)); + } + } + + @Test + 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)); + + // 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)); + + // 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)); + + // 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)); + + // 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)); + + // 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)); + } + + private static List list(ByteBuffer... values) + { + return Arrays.asList(values); + } + + @Test + // sets use the same check as lists + 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))); + + 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))); + + // 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))); + + 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))); + + // 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(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))); + + // 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))); + + 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))); + + // 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))); + + 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))); + + // 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(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))); + } + + private static SortedSet set(ByteBuffer... values) + { + SortedSet results = new TreeSet<>(Int32Type.instance); + results.addAll(Arrays.asList(values)); + return results; + } + + @Test + 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))); + + 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))); + + // 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))); + + 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))); + + // 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(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))); + + // 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))); + + 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))); + + // 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))); + + 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))); + + // 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(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))); + } + + // values should be a list of key, value, key, value, ... + private static Map map(ByteBuffer... values) + { + Map map = new TreeMap<>(); + for (int i = 0; i < values.length; i += 2) + map.put(values[i], values[i + 1]); + + return map; + } + + @Test + 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))); + + 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))); + + // 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))); + + 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))); + + // 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(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))); + + // 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))); + + 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))); + + // 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))); + + 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))); + + // 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(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))); + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/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 1f01931..b5f8b6c 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java @@ -18,6 +18,9 @@ package org.apache.cassandra.cql3.validation.operations; +import java.nio.ByteBuffer; +import java.util.List; + import org.junit.Test; import org.apache.cassandra.config.SchemaConstants; @@ -61,7 +64,10 @@ public class InsertUpdateIfConditionTest extends CQLTester "UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 = ?", unset()); // Shouldn't apply + assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 = ?", 4), row(false)); + assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 IN (?, ?)", 1, 2), row(false)); + assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 IN ?", list(1, 2)), row(false)); assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF EXISTS"), row(false)); // Should apply @@ -77,11 +83,15 @@ public class InsertUpdateIfConditionTest extends CQLTester // Should apply (note: we want v2 before v1 in the statement order to exercise #5786) assertRows(execute("UPDATE %s SET v2 = 'bar', v1 = 3 WHERE k = 0 IF v1 = ?", 2), row(true)); + assertRows(execute("UPDATE %s SET v2 = 'bar', v1 = 2 WHERE k = 0 IF v1 IN (?, ?)", 2, 3), row(true)); + assertRows(execute("UPDATE %s SET v2 = 'bar', v1 = 3 WHERE k = 0 IF v1 IN ?", list(2, 3)), row(true)); + assertRows(execute("UPDATE %s SET v2 = 'bar', v1 = 3 WHERE k = 0 IF v1 IN ?", list(1, null, 3)), row(true)); assertRows(execute("UPDATE %s SET v2 = 'bar', v1 = 3 WHERE k = 0 IF EXISTS"), row(true)); assertRows(execute("SELECT * FROM %s"), row(0, 3, "bar", null)); // Shouldn't apply, only one condition is ok assertRows(execute("UPDATE %s SET v1 = 5, v2 = 'foobar' WHERE k = 0 IF v1 = ? AND v2 = ?", 3, "foo"), row(false, 3, "bar")); + assertRows(execute("UPDATE %s SET v1 = 5, v2 = 'foobar' WHERE k = 0 IF v1 = 3 AND v2 = 'foo'"), row(false, 3, "bar")); assertRows(execute("SELECT * FROM %s"), row(0, 3, "bar", null)); // Should apply @@ -145,6 +155,7 @@ public class InsertUpdateIfConditionTest extends CQLTester assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 IN (?, ?, ?)", 0, 1, 2), row(true)); assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 IN ?", list(142, 276)), row(false, 2)); assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 IN ()"), row(false, 2)); + assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 IN (?, ?)", unset(), 1), row(false, 2)); assertInvalidMessage("Invalid 'unset' value in condition", "UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 < ?", unset()); @@ -156,8 +167,6 @@ public class InsertUpdateIfConditionTest extends CQLTester "UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 >= ?", unset()); assertInvalidMessage("Invalid 'unset' value in condition", "UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 != ?", unset()); - assertInvalidMessage("Invalid 'unset' value in condition", - "UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 IN (?, ?)", unset(), 1); } /** @@ -1957,4 +1966,183 @@ public class InsertUpdateIfConditionTest extends CQLTester + "UPDATE %1$s SET v2 = 'bar' WHERE k = 1 AND t = 0 IF v1 = 'foo'; " + "APPLY BATCH"); } + + @Test + public void testInMarkerWithUDTs() throws Throwable + { + String typename = createType("CREATE TYPE %s (a int, b text)"); + String myType = KEYSPACE + '.' + typename; + + for (boolean frozen : new boolean[] {false, true}) + { + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, v %s)", + frozen + ? "frozen<" + myType + ">" + : myType)); + + Object v = userType("a", 0, "b", "abc"); + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + // Does not apply + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN (?, ?)", userType("a", 1, "b", "abc"), userType("a", 0, "b", "ac")), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN (?, ?)", userType("a", 1, "b", "abc"), null), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN (?, ?)", null, null), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN (?, ?)", userType("a", 1, "b", "abc"), unset()), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN (?, ?)", unset(), unset()), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN ?", list(userType("a", 1, "b", "abc"), userType("a", 0, "b", "ac"))), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v.a IN (?, ?)", 1, 2), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v.a IN (?, ?)", 1, null), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v.a IN ?", list(1, 2)), + row(false, v)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v.a IN (?, ?)", 1, unset()), + row(false, v)); + + // Does apply + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN (?, ?)", userType("a", 0, "b", "abc"), userType("a", 0, "b", "ac")), + row(true)); + assertRows(execute("UPDATE %s SET v = {a: 1, b: 'bc'} WHERE k = 0 IF v IN (?, ?)", userType("a", 0, "b", "bc"), null), + row(true)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'abc'} WHERE k = 0 IF v IN ?", list(userType("a", 1, "b", "bc"), userType("a", 0, "b", "ac"))), + row(true)); + assertRows(execute("UPDATE %s SET v = {a: 1, b: 'bc'} WHERE k = 0 IF v IN (?, ?, ?)", userType("a", 1, "b", "bc"), unset(), userType("a", 0, "b", "abc")), + row(true)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v.a IN (?, ?)", 1, 0), + row(true)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'abc'} WHERE k = 0 IF v.a IN (?, ?)", 0, null), + row(true)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v.a IN ?", list(0, 1)), + row(true)); + assertRows(execute("UPDATE %s SET v = {a: 0, b: 'abc'} WHERE k = 0 IF v.a IN (?, ?, ?)", 1, unset(), 0), + row(true)); + + assertInvalidMessage("Invalid null list in IN condition", + "UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN ?", (List) null); + assertInvalidMessage("Invalid 'unset' value in condition", + "UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v IN ?", unset()); + assertInvalidMessage("Invalid 'unset' value in condition", + "UPDATE %s SET v = {a: 0, b: 'bc'} WHERE k = 0 IF v.a IN ?", unset()); + } + } + + @Test + public void testInMarkerWithLists() throws Throwable + { + for (boolean frozen : new boolean[]{false, true}) + { + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, l %s)", + frozen + ? "frozen>" + : "list")); + + execute("INSERT INTO %s(k, l) VALUES (0, ['foo', 'bar', 'foobar'])"); + + // Does not apply + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN (?, ?)", list("foo", "foobar"), list("bar", "foobar")), + row(false, list("foo", "bar", "foobar"))); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN (?, ?)", list("foo", "foobar"), null), + row(false, list("foo", "bar", "foobar"))); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN (?, ?)", list("foo", "foobar"), unset()), + row(false, list("foo", "bar", "foobar"))); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN (?, ?)", null, null), + row(false, list("foo", "bar", "foobar"))); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN ?", list(list("foo", "foobar"), list("bar", "foobar"))), + row(false, list("foo", "bar", "foobar"))); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l[?] IN ?", 1, list("foo", "foobar")), + row(false, list("foo", "bar", "foobar"))); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l[?] IN (?, ?)", 1, "foo", "foobar"), + row(false, list("foo", "bar", "foobar"))); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l[?] IN (?, ?)", 1, "foo", null), + row(false, list("foo", "bar", "foobar"))); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l[?] IN (?, ?)", 1, "foo", unset()), + row(false, list("foo", "bar", "foobar"))); + + // Does apply + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN (?, ?)", list("foo", "bar", "foobar"), list("bar", "foobar")), + row(true)); + assertRows(execute("UPDATE %s SET l = ['foo', 'foobar'] WHERE k = 0 IF l IN (?, ?, ?)", list("foo", "bar", "foobar"), null, list("foo", "bar")), + row(true)); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN (?, ?, ?)", list("foo", "bar", "foobar"), unset(), list("foo", "foobar")), + row(true)); + assertRows(execute("UPDATE %s SET l = ['foo', 'foobar'] WHERE k = 0 IF l IN (?, ?)", list("bar", "foobar"), list("foo", "bar")), + row(true)); + assertRows(execute("UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l[?] IN ?", 1, list("bar", "foobar")), + row(true)); + assertRows(execute("UPDATE %s SET l = ['foo', 'foobar'] WHERE k = 0 IF l[?] IN (?, ?, ?)", 1, "bar", null, "foobar"), + row(true)); + assertRows(execute("UPDATE %s SET l = ['foo', 'foobar'] WHERE k = 0 IF l[?] IN (?, ?, ?)", 1, "bar", unset(), "foobar"), + row(true)); + + assertInvalidMessage("Invalid null list in IN condition", + "UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN ?", (List) null); + assertInvalidMessage("Invalid 'unset' value in condition", + "UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l IN ?", unset()); + assertInvalidMessage("Invalid 'unset' value in condition", + "UPDATE %s SET l = ['foo', 'bar'] WHERE k = 0 IF l[?] IN ?", 1, unset()); + } + } + + @Test + public void testInMarkerWithMaps() throws Throwable + { + for (boolean frozen : new boolean[] {false, true}) + { + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, m %s)", + frozen + ? "frozen>" + : "map")); + + execute("INSERT INTO %s (k, m) VALUES (0, {'foo' : 'bar'})"); + + // Does not apply + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN (?, ?)", map("foo", "foobar"), map("bar", "foobar")), + row(false, map("foo", "bar"))); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN (?, ?)", map("foo", "foobar"), null), + row(false, map("foo", "bar"))); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN (?, ?)", map("foo", "foobar"), unset()), + row(false, map("foo", "bar"))); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN (?, ?)", null, null), + row(false, map("foo", "bar"))); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN ?", list(map("foo", "foobar"), map("bar", "foobar"))), + row(false, map("foo", "bar"))); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m[?] IN ?", "foo", list("foo", "foobar")), + row(false, map("foo", "bar"))); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m[?] IN (?, ?)", "foo", "foo", "foobar"), + row(false, map("foo", "bar"))); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m[?] IN (?, ?)", "foo", "foo", null), + row(false, map("foo", "bar"))); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m[?] IN (?, ?)", "foo", "foo", unset()), + row(false, map("foo", "bar"))); + + // Does apply + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN (?, ?)", map("foo", "foobar"), map("foo", "bar")), + row(true)); + assertRows(execute("UPDATE %s SET m = {'foo' : 'bar'} WHERE k = 0 IF m IN (?, ?, ?)", map("bar", "foobar"), null, map("foo", "foobar")), + row(true)); + assertRows(execute("UPDATE %s SET m = {'foo' : 'bar'} WHERE k = 0 IF m IN (?, ?, ?)", map("bar", "foobar"), unset(), map("foo", "bar")), + row(true)); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN ?", list(map("foo", "bar"), map("bar", "foobar"))), + row(true)); + assertRows(execute("UPDATE %s SET m = {'foo' : 'bar'} WHERE k = 0 IF m[?] IN ?", "foo", list("bar", "foobar")), + row(true)); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m[?] IN (?, ?, ?)", "foo", "bar", null, "foobar"), + row(true)); + assertRows(execute("UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m[?] IN (?, ?, ?)", "foo", "bar", unset(), "foobar"), + row(true)); + + assertInvalidMessage("Invalid null list in IN condition", + "UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN ?", (List) null); + assertInvalidMessage("Invalid 'unset' value in condition", + "UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m IN ?", unset()); + assertInvalidMessage("Invalid 'unset' value in condition", + "UPDATE %s SET m = {'foo' : 'foobar'} WHERE k = 0 IF m[?] IN ?", "foo", unset()); + } + } }