Repository: cassandra Updated Branches: refs/heads/cassandra-2.1.0 cbe4fd02a -> 8d87e0e25
Fix error when CONTAINS is used with a bind marker patch by slebresne; reviewed by tjake for CASSANDRA-7502 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/0c6fad4a Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/0c6fad4a Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/0c6fad4a Branch: refs/heads/cassandra-2.1.0 Commit: 0c6fad4a8a8d30198283f36f35077d52e8122cee Parents: cbe4fd0 Author: Sylvain Lebresne <[email protected]> Authored: Mon Jul 7 17:31:44 2014 +0200 Committer: Sylvain Lebresne <[email protected]> Committed: Mon Jul 7 17:31:44 2014 +0200 ---------------------------------------------------------------------- CHANGES.txt | 3 +- .../cql3/statements/SelectStatement.java | 1 + .../org/apache/cassandra/cql3/CQLTester.java | 52 +++++++++ .../cassandra/cql3/ContainsRelationTest.java | 106 +++++++++++-------- 4 files changed, 117 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/0c6fad4a/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index b609795..095624d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -2.1.0 +2.1.0-rc3 * Fix ClassCastException processing expired messages (CASSANDRA-7496) * Fix prepared marker for collections inside UDT (CASSANDRA-7472) * Remove left-over populate_io_cache_on_flush and replicate_on_write @@ -7,6 +7,7 @@ * Ensure writes have completed after dropping a table, before recycling commit log segments (CASSANDRA-7437) * Remove left-over rows_per_partition_to_cache (CASSANDRA-7493) + * Fix error when CONTAINS is used with a bind marker (CASSANDRA-7502) Merged from 2.0: * Fix CC#collectTimeOrderedData() tombstone optimisations (CASSANDRA-7394) * Support DISTINCT for static columns and fix behaviour when DISTINC is http://git-wip-us.apache.org/repos/asf/cassandra/blob/0c6fad4a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index b454ece..c9572c2 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -1697,6 +1697,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache boolean isKey = newRel.operator() == Relation.Type.CONTAINS_KEY; receiver = makeCollectionReceiver(receiver, isKey); Term t = newRel.getValue().prepare(keyspace(), receiver); + t.collectMarkerSpecification(boundNames); ((SingleColumnRestriction.Contains)existingRestriction).add(t, isKey); } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/0c6fad4a/test/unit/org/apache/cassandra/cql3/CQLTester.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java index b8912e7..b861d49 100644 --- a/test/unit/org/apache/cassandra/cql3/CQLTester.java +++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java @@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import com.google.common.base.Objects; +import com.google.common.collect.ImmutableSet; import org.junit.AfterClass; import org.junit.After; import org.junit.Assert; @@ -60,6 +61,8 @@ public abstract class CQLTester private String currentTable; + private final Set<String> currentTypes = new HashSet<>(); + @BeforeClass public static void setUpClass() throws Throwable { @@ -132,6 +135,13 @@ public abstract class CQLTester schemaChange(fullQuery); } + protected void createIndex(String query) + { + String fullQuery = String.format(query, KEYSPACE + "." + currentTable); + logger.info(fullQuery); + schemaChange(fullQuery); + } + private static void schemaChange(String query) { try @@ -466,6 +476,23 @@ public abstract class CQLTester return Arrays.asList(values); } + protected Object set(Object...values) + { + return ImmutableSet.copyOf(values); + } + + protected Object map(Object...values) + { + if (values.length % 2 != 0) + throw new IllegalArgumentException(); + + int size = values.length / 2; + Map m = new HashMap(size); + for (int i = 0; i < size; i++) + m.put(values[2 * i], values[(2 * i) + 1]); + return m; + } + // Attempt to find an AbstracType from a value (for serialization/printing sake). // Will work as long as we use types we know of, which is good enough for testing private static AbstractType typeFor(Object value) @@ -495,6 +522,31 @@ public abstract class CQLTester return ListType.getInstance(elt); } + if (value instanceof Set) + { + Set s = (Set)value; + AbstractType elt = s.isEmpty() ? BytesType.instance : typeFor(s.iterator().next()); + return SetType.getInstance(elt); + } + + if (value instanceof Map) + { + Map m = (Map)value; + AbstractType keys, values; + if (m.isEmpty()) + { + keys = BytesType.instance; + values = BytesType.instance; + } + else + { + Map.Entry entry = (Map.Entry)m.entrySet().iterator().next(); + keys = typeFor(entry.getKey()); + values = typeFor(entry.getValue()); + } + return MapType.getInstance(keys, values); + } + throw new IllegalArgumentException("Unsupported value type (value is " + value + ")"); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/0c6fad4a/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java b/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java index eae9b9f..0c6cfe1 100644 --- a/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java +++ b/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java @@ -17,64 +17,82 @@ */ package org.apache.cassandra.cql3; -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.Sets.newHashSet; - import org.junit.Test; -import com.google.common.collect.ImmutableMap; - public class ContainsRelationTest extends CQLTester { @Test - public void testSetContains() throws Throwable + public void testSetContains() throws Throwable { - createTable("CREATE TABLE %s (account text, id int, categories set<text>, PRIMARY KEY (account, id));"); - execute("CREATE INDEX cat_index_set ON %s(categories);"); - execute("INSERT INTO %s (account, id , categories) VALUES ('test', 5, {'lmn'});"); - - assertEmpty(execute("SELECT * FROM %s WHERE account = 'xyz' AND categories CONTAINS 'lmn';")); - - assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS 'lmn';"), row("test", 5, newHashSet("lmn"))); - assertRows(execute("SELECT * FROM %s WHERE account = 'test' AND categories CONTAINS 'lmn';"), row("test", 5, newHashSet("lmn"))); + createTable("CREATE TABLE %s (account text, id int, categories set<text>, PRIMARY KEY (account, id))"); + createIndex("CREATE INDEX ON %s(categories)"); + + execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, set("lmn")); + + assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "lmn")); + + assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "lmn"), + row("test", 5, set("lmn")) + ); + + assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "test", "lmn"), + row("test", 5, set("lmn")) + ); } - + @Test - public void testListContains() throws Throwable + public void testListContains() throws Throwable { - createTable("CREATE TABLE %s (account text, id int, categories list<text>, PRIMARY KEY (account, id));"); - execute("CREATE INDEX cat_index_list ON %s(categories);"); - execute("INSERT INTO %s (account, id , categories) VALUES ('test', 5, ['lmn']);"); - - assertEmpty(execute("SELECT * FROM %s WHERE account = 'xyz' AND categories CONTAINS 'lmn';")); - - assertRows(execute("SELECT * FROM %s WHERE account = 'test' AND categories CONTAINS 'lmn';"), row("test", 5, newArrayList("lmn"))); - assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS 'lmn';"), row("test", 5, newArrayList("lmn"))); + createTable("CREATE TABLE %s (account text, id int, categories list<text>, PRIMARY KEY (account, id))"); + createIndex("CREATE INDEX ON %s(categories)"); + + execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, list("lmn")); + + assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "lmn")); + + assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?;", "test", "lmn"), + row("test", 5, list("lmn")) + ); + + assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "lmn"), + row("test", 5, list("lmn")) + ); } - + @Test - public void testMapKeyContains() throws Throwable + public void testMapKeyContains() throws Throwable { - createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id));"); - execute("CREATE INDEX cat_index_map_key ON %s(keys(categories));"); - execute("INSERT INTO %s (account, id , categories) VALUES ('test', 5, {'lmn':'foo'});"); - - assertEmpty(execute("SELECT * FROM %s WHERE account = 'xyz' AND categories CONTAINS KEY 'lmn';")); - - assertRows(execute("SELECT * FROM %s WHERE account = 'test' AND categories CONTAINS KEY 'lmn';"), row("test", 5, ImmutableMap.of("lmn", "foo"))); - assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS KEY 'lmn';"), row("test", 5, ImmutableMap.of("lmn", "foo"))); + createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))"); + createIndex("CREATE INDEX ON %s(keys(categories))"); + + execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo")); + + assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ?", "xyz", "lmn")); + + assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ?", "test", "lmn"), + row("test", 5, map("lmn", "foo")) + ); + assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS KEY ?", "lmn"), + row("test", 5, map("lmn", "foo")) + ); } - + @Test - public void testMapValueContains() throws Throwable + public void testMapValueContains() throws Throwable { - createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id));"); - execute("CREATE INDEX cat_index_map_value ON %s(categories);"); - execute("INSERT INTO %s (account, id , categories) VALUES ('test', 5, {'lmn':'foo'});"); - - assertEmpty(execute("SELECT * FROM %s WHERE account = 'xyz' AND categories CONTAINS 'foo';")); - - assertRows(execute("SELECT * FROM %s WHERE account = 'test' AND categories CONTAINS 'foo';"), row("test", 5, ImmutableMap.of("lmn", "foo"))); - assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS 'foo';"), row("test", 5, ImmutableMap.of("lmn", "foo"))); + createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))"); + createIndex("CREATE INDEX ON %s(categories)"); + + execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo")); + + assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "foo")); + + assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "test", "foo"), + row("test", 5, map("lmn", "foo")) + ); + + assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "foo"), + row("test", 5, map("lmn", "foo")) + ); } }
