blob: fff476ba57a60b3d6bd311611cb2414dd04850be [file] [log] [blame]
/*
* 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.validation.entities;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Arrays;
import java.util.UUID;
import org.junit.Test;
import com.datastax.driver.core.utils.UUIDs;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.utils.FBUtilities;
import static org.junit.Assert.assertEquals;
public class CollectionsTest extends CQLTester
{
@Test
public void testMapBulkRemoval() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, m map<text, text>)");
execute("INSERT INTO %s(k, m) VALUES (?, ?)", 0, map("k1", "v1", "k2", "v2", "k3", "v3"));
assertRows(execute("SELECT * FROM %s"),
row(0, map("k1", "v1", "k2", "v2", "k3", "v3"))
);
execute("UPDATE %s SET m = m - ? WHERE k = ?", set("k2"), 0);
assertRows(execute("SELECT * FROM %s"),
row(0, map("k1", "v1", "k3", "v3"))
);
execute("UPDATE %s SET m = m + ?, m = m - ? WHERE k = ?", map("k4", "v4"), set("k3"), 0);
assertRows(execute("SELECT * FROM %s"),
row(0, map("k1", "v1", "k4", "v4"))
);
}
@Test
public void testInvalidCollectionsMix() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l list<text>, s set<text>, m map<text, text>)");
// Note: we force the non-prepared form for some of those tests because a list and a set
// have the same serialized format in practice and CQLTester don't validate that the type
// of what's passed as a value in the prepared case, so the queries would work (which is ok,
// CQLTester is just a "dumb" client).
assertInvalid("UPDATE %s SET l = l + { 'a', 'b' } WHERE k = 0");
assertInvalid("UPDATE %s SET l = l - { 'a', 'b' } WHERE k = 0");
assertInvalid("UPDATE %s SET l = l + ? WHERE k = 0", map("a", "b", "c", "d"));
assertInvalid("UPDATE %s SET l = l - ? WHERE k = 0", map("a", "b", "c", "d"));
assertInvalid("UPDATE %s SET s = s + [ 'a', 'b' ] WHERE k = 0");
assertInvalid("UPDATE %s SET s = s - [ 'a', 'b' ] WHERE k = 0");
assertInvalid("UPDATE %s SET s = s + ? WHERE k = 0", map("a", "b", "c", "d"));
assertInvalid("UPDATE %s SET s = s - ? WHERE k = 0", map("a", "b", "c", "d"));
assertInvalid("UPDATE %s SET m = m + ? WHERE k = 0", list("a", "b"));
assertInvalid("UPDATE %s SET m = m - [ 'a', 'b' ] WHERE k = 0");
assertInvalid("UPDATE %s SET m = m + ? WHERE k = 0", set("a", "b"));
assertInvalid("UPDATE %s SET m = m - ? WHERE k = 0", map("a", "b", "c", "d"));
}
@Test
public void testSets() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s set<text>)");
execute("INSERT INTO %s(k, s) VALUES (0, ?)", set("v1", "v2", "v3", "v4"));
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v1", "v2", "v3", "v4"))
);
execute("DELETE s[?] FROM %s WHERE k = 0", "v1");
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v2", "v3", "v4"))
);
// Full overwrite
execute("UPDATE %s SET s = ? WHERE k = 0", set("v6", "v5"));
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v5", "v6"))
);
execute("UPDATE %s SET s = s + ? WHERE k = 0", set("v7"));
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v5", "v6", "v7"))
);
execute("UPDATE %s SET s = s - ? WHERE k = 0", set("v6", "v5"));
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v7"))
);
execute("DELETE s[?] FROM %s WHERE k = 0", set("v7"));
// Deleting an element that does not exist will succeed
execute("DELETE s[?] FROM %s WHERE k = 0", set("v7"));
execute("DELETE s FROM %s WHERE k = 0");
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row((Object) null)
);
}
@Test
public void testMaps() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, m map<text, int>)");
execute("INSERT INTO %s(k, m) VALUES (0, ?)", map("v1", 1, "v2", 2));
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v1", 1, "v2", 2))
);
execute("UPDATE %s SET m[?] = ?, m[?] = ? WHERE k = 0", "v3", 3, "v4", 4);
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v1", 1, "v2", 2, "v3", 3, "v4", 4))
);
execute("DELETE m[?] FROM %s WHERE k = 0", "v1");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v2", 2, "v3", 3, "v4", 4))
);
// Full overwrite
execute("UPDATE %s SET m = ? WHERE k = 0", map("v6", 6, "v5", 5));
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v5", 5, "v6", 6))
);
execute("UPDATE %s SET m = m + ? WHERE k = 0", map("v7", 7));
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v5", 5, "v6", 6, "v7", 7))
);
execute("DELETE m[?] FROM %s WHERE k = 0", "v7");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v5", 5, "v6", 6))
);
execute("DELETE m[?] FROM %s WHERE k = 0", "v6");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v5", 5))
);
execute("DELETE m[?] FROM %s WHERE k = 0", "v5");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row((Object) null)
);
// Deleting a non-existing key should succeed
execute("DELETE m[?] FROM %s WHERE k = 0", "v5");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row((Object) null)
);
// The empty map is parsed as an empty set (because we don't have enough info at parsing
// time when we see a {}) and special cased later. This test checks this work properly
execute("UPDATE %s SET m = {} WHERE k = 0");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row((Object)null)
);
}
@Test
public void testLists() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l list<text>)");
execute("INSERT INTO %s(k, l) VALUES (0, ?)", list("v1", "v2", "v3"));
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", "v2", "v3")));
execute("DELETE l[?] FROM %s WHERE k = 0", 1);
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", "v3")));
execute("UPDATE %s SET l[?] = ? WHERE k = 0", 1, "v4");
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", "v4")));
// Full overwrite
execute("UPDATE %s SET l = ? WHERE k = 0", list("v6", "v5"));
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v6", "v5")));
execute("UPDATE %s SET l = l + ? WHERE k = 0", list("v7", "v8"));
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v6", "v5", "v7", "v8")));
execute("UPDATE %s SET l = ? + l WHERE k = 0", list("v9"));
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v9", "v6", "v5", "v7", "v8")));
execute("UPDATE %s SET l = l - ? WHERE k = 0", list("v5", "v8"));
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v9", "v6", "v7")));
execute("DELETE l FROM %s WHERE k = 0");
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row((Object) null));
assertInvalidMessage("Attempted to delete an element from a list which is null",
"DELETE l[0] FROM %s WHERE k=0 ");
assertInvalidMessage("Attempted to set an element on a list which is null",
"UPDATE %s SET l[0] = ? WHERE k=0", list("v10"));
execute("UPDATE %s SET l = l - ? WHERE k=0", list("v11"));
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row((Object) null));
}
@Test
public void testMapWithUnsetValues() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, m map<text,text>)");
// set up
Object m = map("k", "v");
execute("INSERT INTO %s (k, m) VALUES (10, ?)", m);
assertRows(execute("SELECT m FROM %s WHERE k = 10"),
row(m)
);
// test putting an unset map, should not delete the contents
execute("INSERT INTO %s (k, m) VALUES (10, ?)", unset());
assertRows(execute("SELECT m FROM %s WHERE k = 10"),
row(m)
);
// test unset variables in a map update operaiotn, should not delete the contents
execute("UPDATE %s SET m['k'] = ? WHERE k = 10", unset());
assertRows(execute("SELECT m FROM %s WHERE k = 10"),
row(m)
);
assertInvalidMessage("Invalid unset map key", "UPDATE %s SET m[?] = 'foo' WHERE k = 10", unset());
// test unset value for map key
assertInvalidMessage("Invalid unset map key", "DELETE m[?] FROM %s WHERE k = 10", unset());
}
@Test
public void testListWithUnsetValues() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l list<text>)");
// set up
Object l = list("foo", "foo");
execute("INSERT INTO %s (k, l) VALUES (10, ?)", l);
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
);
// replace list with unset value
execute("INSERT INTO %s (k, l) VALUES (10, ?)", unset());
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
);
// add to position
execute("UPDATE %s SET l[1] = ? WHERE k = 10", unset());
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
);
// set in index
assertInvalidMessage("Invalid unset value for list index", "UPDATE %s SET l[?] = 'foo' WHERE k = 10", unset());
// remove element by index
execute("DELETE l[?] FROM %s WHERE k = 10", unset());
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
);
// remove all occurrences of element
execute("UPDATE %s SET l = l - ? WHERE k = 10", unset());
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
);
// select with in clause
assertInvalidMessage("Invalid unset value for column k", "SELECT * FROM %s WHERE k IN ?", unset());
assertInvalidMessage("Invalid unset value for column k", "SELECT * FROM %s WHERE k IN (?)", unset());
}
@Test
public void testSetWithUnsetValues() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s set<text>)");
Object s = set("bar", "baz", "foo");
execute("INSERT INTO %s (k, s) VALUES (10, ?)", s);
assertRows(execute("SELECT s FROM %s WHERE k = 10"),
row(s)
);
// replace set with unset value
execute("INSERT INTO %s (k, s) VALUES (10, ?)", unset());
assertRows(execute("SELECT s FROM %s WHERE k = 10"),
row(s)
);
// add to set
execute("UPDATE %s SET s = s + ? WHERE k = 10", unset());
assertRows(execute("SELECT s FROM %s WHERE k = 10"),
row(s)
);
// remove all occurrences of element
execute("UPDATE %s SET s = s - ? WHERE k = 10", unset());
assertRows(execute("SELECT s FROM %s WHERE k = 10"),
row(s)
);
}
/**
* Migrated from cql_tests.py:TestCQL.set_test()
*/
@Test
public void testSet() throws Throwable
{
createTable("CREATE TABLE %s ( fn text, ln text, tags set<text>, PRIMARY KEY (fn, ln) )");
execute("UPDATE %s SET tags = tags + { 'foo' } WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + { 'bar' } WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + { 'foo' } WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + { 'foobar' } WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags - { 'bar' } WHERE fn='Tom' AND ln='Bombadil'");
assertRows(execute("SELECT tags FROM %s"),
row(set("foo", "foobar")));
execute("UPDATE %s SET tags = { 'a', 'c', 'b' } WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(set("a", "b", "c")));
execute("UPDATE %s SET tags = { 'm', 'n' } WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(set("m", "n")));
execute("DELETE tags['m'] FROM %s WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(set("n")));
execute("DELETE tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'");
assertEmpty(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"));
}
/**
* Migrated from cql_tests.py:TestCQL.map_test()
*/
@Test
public void testMap() throws Throwable
{
createTable("CREATE TABLE %s (fn text, ln text, m map<text, int>, PRIMARY KEY (fn, ln))");
execute("UPDATE %s SET m['foo'] = 3 WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET m['bar'] = 4 WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET m['woot'] = 5 WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET m['bar'] = 6 WHERE fn='Tom' AND ln='Bombadil'");
execute("DELETE m['foo'] FROM %s WHERE fn='Tom' AND ln='Bombadil'");
assertRows(execute("SELECT m FROM %s"),
row(map("bar", 6, "woot", 5)));
execute("UPDATE %s SET m = { 'a' : 4 , 'c' : 3, 'b' : 2 } WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT m FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(map("a", 4, "b", 2, "c", 3)));
execute("UPDATE %s SET m = { 'm' : 4 , 'n' : 1, 'o' : 2 } WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT m FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(map("m", 4, "n", 1, "o", 2)));
execute("UPDATE %s SET m = {} WHERE fn='Bilbo' AND ln='Baggins'");
assertEmpty(execute("SELECT m FROM %s WHERE fn='Bilbo' AND ln='Baggins'"));
}
/**
* Migrated from cql_tests.py:TestCQL.list_test()
*/
@Test
public void testList() throws Throwable
{
createTable("CREATE TABLE %s (fn text, ln text, tags list<text>, PRIMARY KEY (fn, ln))");
execute("UPDATE %s SET tags = tags + [ 'foo' ] WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + [ 'bar' ] WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + [ 'foo' ] WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + [ 'foobar' ] WHERE fn='Tom' AND ln='Bombadil'");
assertRows(execute("SELECT tags FROM %s"),
row(list("foo", "bar", "foo", "foobar")));
execute("UPDATE %s SET tags = [ 'a', 'c', 'b', 'c' ] WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("a", "c", "b", "c")));
execute("UPDATE %s SET tags = [ 'm', 'n' ] + tags WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("m", "n", "a", "c", "b", "c")));
execute("UPDATE %s SET tags[2] = 'foo', tags[4] = 'bar' WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("m", "n", "foo", "c", "bar", "c")));
execute("DELETE tags[2] FROM %s WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("m", "n", "c", "bar", "c")));
execute("UPDATE %s SET tags = tags - [ 'bar' ] WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("m", "n", "c", "c")));
}
/**
* Migrated from cql_tests.py:TestCQL.multi_collection_test()
*/
@Test
public void testMultiCollections() throws Throwable
{
UUID id = UUID.fromString("b017f48f-ae67-11e1-9096-005056c00008");
createTable("CREATE TABLE %s (k uuid PRIMARY KEY, L list<int>, M map<text, int>, S set<int> )");
execute("UPDATE %s SET L = [1, 3, 5] WHERE k = ?", id);
execute("UPDATE %s SET L = L + [7, 11, 13] WHERE k = ?;", id);
execute("UPDATE %s SET S = {1, 3, 5} WHERE k = ?", id);
execute("UPDATE %s SET S = S + {7, 11, 13} WHERE k = ?", id);
execute("UPDATE %s SET M = {'foo': 1, 'bar' : 3} WHERE k = ?", id);
execute("UPDATE %s SET M = M + {'foobar' : 4} WHERE k = ?", id);
assertRows(execute("SELECT L, M, S FROM %s WHERE k = ?", id),
row(list(1, 3, 5, 7, 11, 13),
map("bar", 3, "foo", 1, "foobar", 4),
set(1, 3, 5, 7, 11, 13)));
}
/**
* Migrated from cql_tests.py:TestCQL.collection_and_regular_test()
*/
@Test
public void testCollectionAndRegularColumns() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l list<int>, c int)");
execute("INSERT INTO %s (k, l, c) VALUES(3, [0, 1, 2], 4)");
execute("UPDATE %s SET l[0] = 1, c = 42 WHERE k = 3");
assertRows(execute("SELECT l, c FROM %s WHERE k = 3"),
row(list(1, 1, 2), 42));
}
/**
* Migrated from cql_tests.py:TestCQL.multi_list_set_test()
*/
@Test
public void testMultipleLists() throws Throwable
{
createTable(" CREATE TABLE %s (k int PRIMARY KEY, l1 list<int>, l2 list<int>)");
execute("INSERT INTO %s (k, l1, l2) VALUES (0, [1, 2, 3], [4, 5, 6])");
execute("UPDATE %s SET l2[1] = 42, l1[1] = 24 WHERE k = 0");
assertRows(execute("SELECT l1, l2 FROM %s WHERE k = 0"),
row(list(1, 24, 3), list(4, 42, 6)));
}
/**
* Test you can add columns in a table with collections (#4982 bug),
* migrated from cql_tests.py:TestCQL.alter_with_collections_test()
*/
@Test
public void testAlterCollections() throws Throwable
{
createTable("CREATE TABLE %s (key int PRIMARY KEY, aset set<text>)");
execute("ALTER TABLE %s ADD c text");
execute("ALTER TABLE %s ADD alist list<text>");
}
/**
* Migrated from cql_tests.py:TestCQL.collection_compact_test()
*/
@Test
public void testCompactCollections() throws Throwable
{
String tableName = KEYSPACE + "." + createTableName();
assertInvalid(String.format("CREATE TABLE %s (user ascii PRIMARY KEY, mails list < text >) WITH COMPACT STORAGE;", tableName));
}
/**
* Migrated from cql_tests.py:TestCQL.collection_function_test()
*/
@Test
public void testFunctionsOnCollections() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l set<int>)");
assertInvalid("SELECT ttl(l) FROM %s WHERE k = 0");
assertInvalid("SELECT writetime(l) FROM %s WHERE k = 0");
}
/**
* Migrated from cql_tests.py:TestCQL.bug_5376()
*/
@Test
public void testInClauseWithCollections() throws Throwable
{
createTable("CREATE TABLE %s (key text, c bigint, v text, x set < text >, PRIMARY KEY(key, c) )");
assertInvalid("select * from %s where key = 'foo' and c in (1,3,4)");
}
/**
* Test for bug #5795,
* migrated from cql_tests.py:TestCQL.nonpure_function_collection_test()
*/
@Test
public void testNonPureFunctionCollection() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v list<timeuuid>)");
// we just want to make sure this doesn't throw
execute("INSERT INTO %s (k, v) VALUES (0, [now()])");
}
/**
* Test for 5805 bug,
* migrated from cql_tests.py:TestCQL.collection_flush_test()
*/
@Test
public void testCollectionFlush() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s set<int>)");
execute("INSERT INTO %s (k, s) VALUES (1, {1})");
flush();
execute("INSERT INTO %s (k, s) VALUES (1, {2})");
flush();
assertRows(execute("SELECT * FROM %s"),
row(1, set(2)));
}
/**
* Test for 6276,
* migrated from cql_tests.py:TestCQL.drop_and_readd_collection_test()
*/
@Test
public void testDropAndReaddCollection() throws Throwable
{
createTable("create table %s (k int primary key, v set<text>, x int)");
execute("insert into %s (k, v) VALUES (0, {'fffffffff'})");
flush();
execute("alter table %s drop v");
assertInvalid("alter table %s add v set<int>");
}
@Test
public void testDropAndReaddFrozenCollection() throws Throwable
{
createTable("create table %s (k int primary key, v frozen<set<text>>, x int)");
execute("insert into %s (k, v) VALUES (0, {'fffffffff'})");
flush();
execute("alter table %s drop v");
assertInvalid("alter table %s add v frozen<set<int>>");
}
@Test
public void testMapWithLargePartition() throws Throwable
{
Random r = new Random();
long seed = System.nanoTime();
System.out.println("Seed " + seed);
r.setSeed(seed);
int len = (1024 * 1024)/100;
createTable("CREATE TABLE %s (userid text PRIMARY KEY, properties map<int, text>) with compression = {}");
final int numKeys = 200;
for (int i = 0; i < numKeys; i++)
{
byte[] b = new byte[len];
r.nextBytes(b);
execute("UPDATE %s SET properties[?] = ? WHERE userid = 'user'", i, new String(b));
}
flush();
Object[][] rows = getRows(execute("SELECT properties from %s where userid = 'user'"));
assertEquals(1, rows.length);
assertEquals(numKeys, ((Map) rows[0][0]).size());
}
@Test
public void testMapWithTwoSStables() throws Throwable
{
createTable("CREATE TABLE %s (userid text PRIMARY KEY, properties map<int, text>) with compression = {}");
final int numKeys = 100;
for (int i = 0; i < numKeys; i++)
execute("UPDATE %s SET properties[?] = ? WHERE userid = 'user'", i, "prop_" + Integer.toString(i));
flush();
for (int i = numKeys; i < 2*numKeys; i++)
execute("UPDATE %s SET properties[?] = ? WHERE userid = 'user'", i, "prop_" + Integer.toString(i));
flush();
Object[][] rows = getRows(execute("SELECT properties from %s where userid = 'user'"));
assertEquals(1, rows.length);
assertEquals(numKeys * 2, ((Map) rows[0][0]).size());
}
@Test
public void testSetWithTwoSStables() throws Throwable
{
createTable("CREATE TABLE %s (userid text PRIMARY KEY, properties set<text>) with compression = {}");
final int numKeys = 100;
for (int i = 0; i < numKeys; i++)
execute("UPDATE %s SET properties = properties + ? WHERE userid = 'user'", set("prop_" + Integer.toString(i)));
flush();
for (int i = numKeys; i < 2*numKeys; i++)
execute("UPDATE %s SET properties = properties + ? WHERE userid = 'user'", set("prop_" + Integer.toString(i)));
flush();
Object[][] rows = getRows(execute("SELECT properties from %s where userid = 'user'"));
assertEquals(1, rows.length);
assertEquals(numKeys * 2, ((Set) rows[0][0]).size());
}
@Test
public void testUpdateStaticList() throws Throwable
{
createTable("CREATE TABLE %s (k1 text, k2 text, s_list list<int> static, PRIMARY KEY (k1, k2))");
execute("insert into %s (k1, k2) VALUES ('a','b')");
execute("update %s set s_list = s_list + [0] where k1='a'");
assertRows(execute("select s_list from %s where k1='a'"), row(list(0)));
execute("update %s set s_list[0] = 100 where k1='a'");
assertRows(execute("select s_list from %s where k1='a'"), row(list(100)));
execute("update %s set s_list = s_list + [0] where k1='a'");
assertRows(execute("select s_list from %s where k1='a'"), row(list(100, 0)));
execute("delete s_list[0] from %s where k1='a'");
assertRows(execute("select s_list from %s where k1='a'"), row(list(0)));
}
@Test
public void testListWithElementsBiggerThan64K() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l list<text>)");
byte[] bytes = new byte[FBUtilities.MAX_UNSIGNED_SHORT + 10];
Arrays.fill(bytes, (byte) 1);
String largeText = new String(bytes);
bytes = new byte[FBUtilities.MAX_UNSIGNED_SHORT + 10];
Arrays.fill(bytes, (byte) 2);
String largeText2 = new String(bytes);
execute("INSERT INTO %s(k, l) VALUES (0, ?)", list(largeText, "v2"));
flush();
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list(largeText, "v2")));
execute("DELETE l[?] FROM %s WHERE k = 0", 0);
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v2")));
execute("UPDATE %s SET l[?] = ? WHERE k = 0", 0, largeText);
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list(largeText)));
// Full overwrite
execute("UPDATE %s SET l = ? WHERE k = 0", list("v1", largeText));
flush();
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", largeText)));
execute("UPDATE %s SET l = l + ? WHERE k = 0", list("v2", largeText2));
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", largeText, "v2", largeText2)));
execute("UPDATE %s SET l = l - ? WHERE k = 0", list(largeText, "v2"));
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", largeText2)));
execute("DELETE l FROM %s WHERE k = 0");
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row((Object) null));
execute("INSERT INTO %s(k, l) VALUES (0, ['" + largeText + "', 'v2'])");
flush();
assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list(largeText, "v2")));
}
@Test
public void testMapsWithElementsBiggerThan64K() throws Throwable
{
byte[] bytes = new byte[FBUtilities.MAX_UNSIGNED_SHORT + 10];
Arrays.fill(bytes, (byte) 1);
String largeText = new String(bytes);
bytes = new byte[FBUtilities.MAX_UNSIGNED_SHORT + 10];
Arrays.fill(bytes, (byte) 2);
String largeText2 = new String(bytes);
createTable("CREATE TABLE %s (k int PRIMARY KEY, m map<text, text>)");
execute("INSERT INTO %s(k, m) VALUES (0, ?)", map("k1", largeText, largeText, "v2"));
flush();
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("k1", largeText, largeText, "v2")));
execute("UPDATE %s SET m[?] = ? WHERE k = 0", "k3", largeText);
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("k1", largeText, largeText, "v2", "k3", largeText)));
execute("UPDATE %s SET m[?] = ? WHERE k = 0", largeText2, "v4");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("k1", largeText, largeText, "v2", "k3", largeText, largeText2, "v4")));
execute("DELETE m[?] FROM %s WHERE k = 0", "k1");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map(largeText, "v2", "k3", largeText, largeText2, "v4")));
execute("DELETE m[?] FROM %s WHERE k = 0", largeText2);
flush();
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map(largeText, "v2", "k3", largeText)));
// Full overwrite
execute("UPDATE %s SET m = ? WHERE k = 0", map("k5", largeText, largeText, "v6"));
flush();
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("k5", largeText, largeText, "v6")));
execute("UPDATE %s SET m = m + ? WHERE k = 0", map("k7", largeText));
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("k5", largeText, largeText, "v6", "k7", largeText)));
execute("UPDATE %s SET m = m + ? WHERE k = 0", map(largeText2, "v8"));
flush();
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("k5", largeText, largeText, "v6", "k7", largeText, largeText2, "v8")));
execute("DELETE m FROM %s WHERE k = 0");
assertRows(execute("SELECT m FROM %s WHERE k = 0"), row((Object) null));
execute("INSERT INTO %s(k, m) VALUES (0, {'" + largeText + "' : 'v1', 'k2' : '" + largeText + "'})");
flush();
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map(largeText, "v1", "k2", largeText)));
}
@Test
public void testSetsWithElementsBiggerThan64K() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s set<text>)");
byte[] bytes = new byte[FBUtilities.MAX_UNSIGNED_SHORT + 10];
Arrays.fill(bytes, (byte) 1);
String largeText = new String(bytes);
bytes = new byte[FBUtilities.MAX_UNSIGNED_SHORT + 10];
Arrays.fill(bytes, (byte) 2);
String largeText2 = new String(bytes);
execute("INSERT INTO %s(k, s) VALUES (0, ?)", set(largeText, "v2"));
flush();
assertRows(execute("SELECT s FROM %s WHERE k = 0"), row(set(largeText, "v2")));
execute("DELETE s[?] FROM %s WHERE k = 0", largeText);
assertRows(execute("SELECT s FROM %s WHERE k = 0"), row(set("v2")));
// Full overwrite
execute("UPDATE %s SET s = ? WHERE k = 0", set("v1", largeText));
flush();
assertRows(execute("SELECT s FROM %s WHERE k = 0"), row(set("v1", largeText)));
execute("UPDATE %s SET s = s + ? WHERE k = 0", set("v2", largeText2));
assertRows(execute("SELECT s FROM %s WHERE k = 0"), row(set("v1", largeText, "v2", largeText2)));
execute("UPDATE %s SET s = s - ? WHERE k = 0", set(largeText, "v2"));
assertRows(execute("SELECT s FROM %s WHERE k = 0"), row(set("v1", largeText2)));
execute("DELETE s FROM %s WHERE k = 0");
assertRows(execute("SELECT s FROM %s WHERE k = 0"), row((Object) null));
execute("INSERT INTO %s(k, s) VALUES (0, {'" + largeText + "', 'v2'})");
flush();
assertRows(execute("SELECT s FROM %s WHERE k = 0"), row(set(largeText, "v2")));
}
@Test
public void testRemovalThroughUpdate() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l list<int>)");
execute("INSERT INTO %s(k, l) VALUES(?, ?)", 0, list(1, 2, 3));
assertRows(execute("SELECT * FROM %s"), row(0, list(1, 2, 3)));
execute("UPDATE %s SET l[0] = null WHERE k=0");
assertRows(execute("SELECT * FROM %s"), row(0, list(2, 3)));
}
@Test
public void testInvalidInputForList() throws Throwable
{
createTable("CREATE TABLE %s(pk int PRIMARY KEY, l list<text>)");
assertInvalidMessage("Not enough bytes to read a list",
"INSERT INTO %s (pk, l) VALUES (?, ?)", 1, "test");
assertInvalidMessage("Not enough bytes to read a list",
"INSERT INTO %s (pk, l) VALUES (?, ?)", 1, Long.MAX_VALUE);
assertInvalidMessage("Not enough bytes to read a list",
"INSERT INTO %s (pk, l) VALUES (?, ?)", 1, "");
assertInvalidMessage("The data cannot be deserialized as a list",
"INSERT INTO %s (pk, l) VALUES (?, ?)", 1, -1);
}
@Test
public void testInvalidInputForSet() throws Throwable
{
createTable("CREATE TABLE %s(pk int PRIMARY KEY, s set<text>)");
assertInvalidMessage("Not enough bytes to read a set",
"INSERT INTO %s (pk, s) VALUES (?, ?)", 1, "test");
assertInvalidMessage("String didn't validate.",
"INSERT INTO %s (pk, s) VALUES (?, ?)", 1, Long.MAX_VALUE);
assertInvalidMessage("Not enough bytes to read a set",
"INSERT INTO %s (pk, s) VALUES (?, ?)", 1, "");
assertInvalidMessage("The data cannot be deserialized as a set",
"INSERT INTO %s (pk, s) VALUES (?, ?)", 1, -1);
}
@Test
public void testInvalidInputForMap() throws Throwable
{
createTable("CREATE TABLE %s(pk int PRIMARY KEY, m map<text, text>)");
assertInvalidMessage("Not enough bytes to read a map",
"INSERT INTO %s (pk, m) VALUES (?, ?)", 1, "test");
assertInvalidMessage("String didn't validate.",
"INSERT INTO %s (pk, m) VALUES (?, ?)", 1, Long.MAX_VALUE);
assertInvalidMessage("Not enough bytes to read a map",
"INSERT INTO %s (pk, m) VALUES (?, ?)", 1, "");
assertInvalidMessage("The data cannot be deserialized as a map",
"INSERT INTO %s (pk, m) VALUES (?, ?)", 1, -1);
}
@Test
public void testMultipleOperationOnListWithinTheSameQuery() throws Throwable
{
createTable("CREATE TABLE %s (pk int PRIMARY KEY, l list<int>)");
execute("INSERT INTO %s (pk, l) VALUES (1, [1, 2, 3, 4])");
// Checks that when the same element is updated twice the update with the greatest value is the one taken into account
execute("UPDATE %s SET l[?] = ?, l[?] = ? WHERE pk = ?", 2, 7, 2, 8, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, list(1, 2, 8, 4)));
execute("UPDATE %s SET l[?] = ?, l[?] = ? WHERE pk = ?", 2, 9, 2, 6, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, list(1, 2, 9, 4)));
// Checks that deleting twice the same element will result in the deletion of the element with the index
// and of the following element.
execute("DELETE l[?], l[?] FROM %s WHERE pk = ?", 2, 2, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, list(1, 2)));
// Checks that the set operation is performed on the added elements and that the greatest value win
execute("UPDATE %s SET l = l + ?, l[?] = ? WHERE pk = ?", list(3, 4), 3, 7, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, list(1, 2, 3, 7)));
execute("UPDATE %s SET l = l + ?, l[?] = ? WHERE pk = ?", list(6, 8), 4, 5, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, list(1, 2, 3, 7, 6, 8)));
// Checks that the order of the operations matters
assertInvalidMessage("List index 6 out of bound, list has size 6",
"UPDATE %s SET l[?] = ?, l = l + ? WHERE pk = ?", 6, 5, list(9), 1);
// Checks that the updated element is deleted.
execute("UPDATE %s SET l[?] = ? , l = l - ? WHERE pk = ?", 2, 8, list(8), 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, list(1, 2, 7, 6)));
// Checks that we cannot update an element that has been removed.
assertInvalidMessage("List index 3 out of bound, list has size 3",
"UPDATE %s SET l = l - ?, l[?] = ? WHERE pk = ?", list(6), 3, 4, 1);
// Checks that the element is updated before the other ones are shifted.
execute("UPDATE %s SET l[?] = ? , l = l - ? WHERE pk = ?", 2, 8, list(1), 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, list(2, 8, 6)));
// Checks that the element are shifted before the element is updated.
execute("UPDATE %s SET l = l - ?, l[?] = ? WHERE pk = ?", list(2, 6), 0, 9, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, list(9)));
}
@Test
public void testMultipleOperationOnMapWithinTheSameQuery() throws Throwable
{
createTable("CREATE TABLE %s (pk int PRIMARY KEY, m map<int, int>)");
execute("INSERT INTO %s (pk, m) VALUES (1, {0 : 1, 1 : 2, 2 : 3, 3 : 4})");
// Checks that when the same element is updated twice the update with the greatest value is the one taken into account
execute("UPDATE %s SET m[?] = ?, m[?] = ? WHERE pk = ?", 2, 7, 2, 8, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = 1") , row(1, map(0, 1, 1, 2, 2, 8, 3, 4)));
execute("UPDATE %s SET m[?] = ?, m[?] = ? WHERE pk = ?", 2, 9, 2, 6, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = 1") , row(1, map(0, 1, 1, 2, 2, 9, 3, 4)));
// Checks that deleting twice the same element has no side effect
execute("DELETE m[?], m[?] FROM %s WHERE pk = ?", 2, 2, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, map(0, 1, 1, 2, 3, 4)));
// Checks that the set operation is performed on the added elements and that the greatest value win
execute("UPDATE %s SET m = m + ?, m[?] = ? WHERE pk = ?", map(4, 5), 4, 7, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, map(0, 1, 1, 2, 3, 4, 4, 7)));
execute("UPDATE %s SET m = m + ?, m[?] = ? WHERE pk = ?", map(4, 8), 4, 6, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, map(0, 1, 1, 2, 3, 4, 4, 8)));
// Checks that, as tombstones win over updates for the same timestamp, the removed element is not readded
execute("UPDATE %s SET m = m - ?, m[?] = ? WHERE pk = ?", set(4), 4, 9, 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, map(0, 1, 1, 2, 3, 4)));
// Checks that the update is taken into account before the removal
execute("UPDATE %s SET m[?] = ?, m = m - ? WHERE pk = ?", 5, 9, set(5), 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, map(0, 1, 1, 2, 3, 4)));
// Checks that the set operation is merged with the change of the append and that the greatest value win
execute("UPDATE %s SET m[?] = ?, m = m + ? WHERE pk = ?", 5, 9, map(5, 8, 6, 9), 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, map(0, 1, 1, 2, 3, 4, 5, 9, 6, 9)));
execute("UPDATE %s SET m[?] = ?, m = m + ? WHERE pk = ?", 7, 1, map(7, 2), 1);
assertRows(execute("SELECT * FROM %s WHERE pk = ?", 1) , row(1, map(0, 1, 1, 2, 3, 4, 5, 9, 6, 9, 7, 2)));
}
@Test
public void testMultipleOperationOnSetWithinTheSameQuery() throws Throwable
{
createTable("CREATE TABLE %s (pk int PRIMARY KEY, s set<int>)");
execute("INSERT INTO %s (pk, s) VALUES (1, {0, 1, 2})");
// Checks that the two operation are merged and that the tombstone always win
execute("UPDATE %s SET s = s + ? , s = s - ? WHERE pk = ?", set(3, 4), set(3), 1);
assertRows(execute("SELECT * FROM %s WHERE pk = 1") , row(1, set(0, 1, 2, 4)));
execute("UPDATE %s SET s = s - ? , s = s + ? WHERE pk = ?", set(3), set(3, 4), 1);
assertRows(execute("SELECT * FROM %s WHERE pk = 1") , row(1, set(0, 1, 2, 4)));
}
@Test
public void testInsertingCollectionsWithInvalidElements() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s frozen<set<tuple<int, text, double>>>)");
assertInvalidMessage("Invalid remaining data after end of tuple value",
"INSERT INTO %s (k, s) VALUES (0, ?)",
set(tuple(1, "1", 1.0, 1), tuple(2, "2", 2.0, 2)));
assertInvalidMessage("Invalid set literal for s: value (1, '1', 1.0, 1) is not of type frozen<tuple<int, text, double>>",
"INSERT INTO %s (k, s) VALUES (0, {(1, '1', 1.0, 1)})");
createTable("CREATE TABLE %s (k int PRIMARY KEY, l frozen<list<tuple<int, text, double>>>)");
assertInvalidMessage("Invalid remaining data after end of tuple value",
"INSERT INTO %s (k, l) VALUES (0, ?)",
list(tuple(1, "1", 1.0, 1), tuple(2, "2", 2.0, 2)));
assertInvalidMessage("Invalid list literal for l: value (1, '1', 1.0, 1) is not of type frozen<tuple<int, text, double>>",
"INSERT INTO %s (k, l) VALUES (0, [(1, '1', 1.0, 1)])");
createTable("CREATE TABLE %s (k int PRIMARY KEY, m frozen<map<tuple<int, text, double>, int>>)");
assertInvalidMessage("Invalid remaining data after end of tuple value",
"INSERT INTO %s (k, m) VALUES (0, ?)",
map(tuple(1, "1", 1.0, 1), 1, tuple(2, "2", 2.0, 2), 2));
assertInvalidMessage("Invalid map literal for m: key (1, '1', 1.0, 1) is not of type frozen<tuple<int, text, double>>",
"INSERT INTO %s (k, m) VALUES (0, {(1, '1', 1.0, 1) : 1})");
createTable("CREATE TABLE %s (k int PRIMARY KEY, m frozen<map<int, tuple<int, text, double>>>)");
assertInvalidMessage("Invalid remaining data after end of tuple value",
"INSERT INTO %s (k, m) VALUES (0, ?)",
map(1, tuple(1, "1", 1.0, 1), 2, tuple(2, "2", 2.0, 2)));
assertInvalidMessage("Invalid map literal for m: value (1, '1', 1.0, 1) is not of type frozen<tuple<int, text, double>>",
"INSERT INTO %s (k, m) VALUES (0, {1 : (1, '1', 1.0, 1)})");
}
/*
Tests for CASSANDRA-17623
Before CASSANDRA-17623, parameterized queries with maps as values would fail because frozen maps were
required to be sorted by the sort order of their key type, but weren't always sorted correctly.
Also adding tests for Sets, which did work because they always used SortedSet, to make sure this behavior is maintained.
We use `executeNet` in these tests because `execute` passes parameters through CqlTester#transformValues(), which calls
AbstractType#decompose() on the value, which "fixes" the map order, but wouldn't happen normally.
*/
@Test
public void testInsertingMapDataWithParameterizedQueriesIsKeyOrderIndependent() throws Throwable
{
UUID uuid1 = UUIDs.timeBased();
UUID uuid2 = UUIDs.timeBased();
createTable("CREATE TABLE %s (k text, c frozen<map<timeuuid, text>>, PRIMARY KEY (k, c));");
executeNet("INSERT INTO %s (k, c) VALUES ('0', ?)", linkedHashMap(uuid1, "0", uuid2, "1"));
executeNet("INSERT INTO %s (k, c) VALUES ('0', ?)", linkedHashMap(uuid2, "3", uuid1, "4"));
beforeAndAfterFlush(() -> {
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k='0' AND c={" + uuid1 + ": '0', " + uuid2 + ": '1'}"), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k='0' AND c={" + uuid2 + ": '1', " + uuid1 + ": '0'}"), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k='0' AND c={" + uuid1 + ": '4', " + uuid2 + ": '3'}"), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k='0' AND c={" + uuid2 + ": '3', " + uuid1 + ": '4'}"), 1);
});
}
@Test
public void testSelectingMapDataWithParameterizedQueriesIsKeyOrderIndependent() throws Throwable
{
UUID uuid1 = UUIDs.timeBased();
UUID uuid2 = UUIDs.timeBased();
createTable("CREATE TABLE %s (k text, c frozen<map<timeuuid, text>>, PRIMARY KEY (k, c));");
executeNet("INSERT INTO %s (k, c) VALUES ('0', {" + uuid1 + ": '0', " + uuid2 + ": '1'})");
executeNet("INSERT INTO %s (k, c) VALUES ('0', {" + uuid2 + ": '3', " + uuid1 + ": '4'})");
beforeAndAfterFlush(() -> {
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k=? AND c=?", "0", linkedHashMap(uuid1, "0", uuid2, "1")), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k=? AND c=?", "0", linkedHashMap(uuid2, "1", uuid1, "0")), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k=? AND c=?", "0", linkedHashMap(uuid1, "4", uuid2, "3")), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k=? AND c=?", "0", linkedHashMap(uuid2, "3", uuid1, "4")), 1);
});
}
@Test
public void testInsertingSetDataWithParameterizedQueriesIsKeyOrderIndependent() throws Throwable
{
UUID uuid1 = UUIDs.timeBased();
UUID uuid2 = UUIDs.timeBased();
createTable("CREATE TABLE %s (k text, c frozen<set<timeuuid>>, PRIMARY KEY (k, c));");
executeNet("INSERT INTO %s (k, c) VALUES ('0', ?)", linkedHashSet(uuid1, uuid2));
executeNet("INSERT INTO %s (k, c) VALUES ('0', ?)", linkedHashSet(uuid2, uuid1));
beforeAndAfterFlush(() -> {
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k='0' AND c={" + uuid1 + ", " + uuid2 + '}'), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k='0' AND c={" + uuid2 + ", " + uuid1 + '}'), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k='0' AND c={" + uuid1 + ", " + uuid2 + '}'), 1);
assertRowCountNet(executeNet("SELECT * FROM %s WHERE k='0' AND c={" + uuid2 + ", " + uuid1 + '}'), 1);
});
}
@Test
public void testSelectingSetDataWithParameterizedQueriesIsKeyOrderIndependent() throws Throwable
{
UUID uuid1 = UUIDs.timeBased();
UUID uuid2 = UUIDs.timeBased();
createTable("CREATE TABLE %s (k text, c frozen<set<timeuuid>>, PRIMARY KEY (k, c));");
executeNet("INSERT INTO %s (k, c) VALUES ('0', {" + uuid1 + ", " + uuid2 + "})");
beforeAndAfterFlush(() -> {
assertRowsNet(executeNet("SELECT k, c from %s where k='0' and c=?", linkedHashSet(uuid1, uuid2)), row("0", list(uuid1, uuid2)));
assertRowsNet(executeNet("SELECT k, c from %s where k='0' and c=?", linkedHashSet(uuid2, uuid1)), row("0", list(uuid1, uuid2)));
});
}
// End tests for CASSANDRA-17623
}