mirror of https://github.com/apache/cassandra
Fix error when CONTAINS is used with a bind marker
patch by slebresne; reviewed by tjake for CASSANDRA-7502
This commit is contained in:
parent
cbe4fd02ae
commit
0c6fad4a8a
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 + ")");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue