This is an automated email from the ASF dual-hosted git repository. bereng pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra-dtest.git
The following commit(s) were added to refs/heads/trunk by this push: new 5e06a1f5 CONTAINS and CONTAINS KEY support for Lightweight Transactions 5e06a1f5 is described below commit 5e06a1f5c192670b586abf8d1a68e4f884ba4e42 Author: ROCHETEAU Antoine <arochet...@jouve.com> AuthorDate: Tue Mar 22 09:26:17 2022 +0100 CONTAINS and CONTAINS KEY support for Lightweight Transactions patch by ROCHETEAU Antoine; reviewed by Benjamin Lerer, Berenguer Blasi for CASSANDRA-10537 --- upgrade_tests/cql_tests.py | 164 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 128 insertions(+), 36 deletions(-) diff --git a/upgrade_tests/cql_tests.py b/upgrade_tests/cql_tests.py index cb4d5667..59e37cb1 100644 --- a/upgrade_tests/cql_tests.py +++ b/upgrade_tests/cql_tests.py @@ -29,7 +29,7 @@ from tools.assertions import (assert_all, assert_invalid, assert_length_equal, from tools.data import rows_to_list from tools.misc import add_skip from .upgrade_base import UpgradeTester -from .upgrade_manifest import build_upgrade_pairs, CASSANDRA_4_0 +from .upgrade_manifest import build_upgrade_pairs, CASSANDRA_4_0, CASSANDRA_4_1 since = pytest.mark.since logger = logging.getLogger(__name__) @@ -4351,8 +4351,13 @@ class TestCQL(UpgradeTester): cursor.execute("INSERT INTO {}(k, l) VALUES (0, ['foo', 'bar', 'foobar'])".format(table)) def check_applies(condition): + # UPDATE statement assert_one(cursor, "UPDATE {} SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF {}".format(table, condition), [True], cl=self.CL) assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']]) # read back at default cl.one + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), [True], cl=self.CL) + assert_none(cursor, "SELECT * FROM {}".format(table)) # read back at default cl.one + cursor.execute("INSERT INTO {}(k, l) VALUES (0, ['foo', 'bar', 'foobar'])".format(table)) check_applies("l = ['foo', 'bar', 'foobar']") check_applies("l != ['baz']") @@ -4367,9 +4372,14 @@ class TestCQL(UpgradeTester): check_applies("l != null AND l IN (['foo', 'bar', 'foobar'])") def check_does_not_apply(condition): + # UPDATE statement assert_one(cursor, "UPDATE {} SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF {}".format(table, condition), [False, ['foo', 'bar', 'foobar']], cl=self.CL) - assert_one(cursor, "SELECT * FROM {}".format((table)), [0, ['foo', 'bar', 'foobar']]) # read back at default cl.one + assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']]) # read back at default cl.one + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), + [False, ['foo', 'bar', 'foobar']], cl=self.CL) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']]) # read back at default cl.one # should not apply check_does_not_apply("l = ['baz']") @@ -4386,8 +4396,12 @@ class TestCQL(UpgradeTester): check_does_not_apply("l > ['zzz'] AND l < ['zzz']") def check_invalid(condition, expected=InvalidRequest): + # UPDATE statement assert_invalid(cursor, "UPDATE {} SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF {}".format(table, condition), expected=expected) assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']], cl=self.CL) + # DELETE statement + assert_invalid(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), expected=expected) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']], cl=self.CL) check_invalid("l = [null]") check_invalid("l < null") @@ -4396,10 +4410,18 @@ class TestCQL(UpgradeTester): check_invalid("l >= null") check_invalid("l IN null", expected=SyntaxException) check_invalid("l IN 367", expected=SyntaxException) - check_invalid("l CONTAINS KEY 123", expected=SyntaxException) - # not supported yet - check_invalid("m CONTAINS 'bar'", expected=SyntaxException) + # @jira_ticket CASSANDRA-10537 + if self.get_node_version(is_upgraded) >= LooseVersion(CASSANDRA_4_1): + check_applies("l CONTAINS 'bar'") + check_applies("l CONTAINS 'foo' AND l CONTAINS 'foobar'") + check_does_not_apply("l CONTAINS 'baz'") + check_does_not_apply("l CONTAINS 'bar' AND l CONTAINS 'baz'") + check_invalid("m CONTAINS 'bar'") + check_invalid("l CONTAINS KEY 123") + else: + check_invalid("m CONTAINS 'bar'", expected=SyntaxException) + check_invalid("l CONTAINS KEY 123", expected=SyntaxException) @since('2.1') def test_list_item_conditional(self): @@ -4467,11 +4489,17 @@ class TestCQL(UpgradeTester): table = "frozentlist" if frozen else "tlist" - cursor.execute("INSERT INTO %s(k, l) VALUES (0, ['foo', 'bar', 'foobar'])" % (table,)) + cursor.execute("INSERT INTO {}(k, l) VALUES (0, ['foo', 'bar', 'foobar'])".format(table,)) def check_applies(condition): - assert_one(cursor, "UPDATE %s SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF %s" % (table, condition), [True]) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, ['foo', 'bar', 'foobar']]) + # UPDATE statement + assert_one(cursor, "UPDATE {} SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF {}".format(table, condition), [True]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']]) + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), [True]) + assert_none(cursor, "SELECT * FROM {}".format(table), cl=ConsistencyLevel.SERIAL) + cursor.execute("INSERT INTO {}(k, l) VALUES (0, ['foo', 'bar', 'foobar'])".format(table,)) + check_applies("l[1] < 'zzz'") check_applies("l[1] <= 'bar'") @@ -4487,8 +4515,12 @@ class TestCQL(UpgradeTester): check_applies("l[3] IN (null, 'xxx', 'bar')") def check_does_not_apply(condition): - assert_one(cursor, "UPDATE %s SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF %s" % (table, condition), [False, ['foo', 'bar', 'foobar']]) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, ['foo', 'bar', 'foobar']]) + # UPDATE statement + assert_one(cursor, "UPDATE {} SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF {}".format(table, condition), [False, ['foo', 'bar', 'foobar']]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']]) + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), [False, ['foo', 'bar', 'foobar']]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']]) check_does_not_apply("l[1] < 'aaa'") check_does_not_apply("l[1] <= 'aaa'") @@ -4504,8 +4536,12 @@ class TestCQL(UpgradeTester): check_does_not_apply("l[3] = 'xxx'") def check_invalid(condition, expected=InvalidRequest): - assert_invalid(cursor, "UPDATE %s SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF %s" % (table, condition), expected=expected) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, ['foo', 'bar', 'foobar']]) + # UPDATE statement + assert_invalid(cursor, "UPDATE {} SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF {}".format(table, condition), expected=expected) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']]) + # DELETE statement + assert_invalid(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), expected=expected) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, ['foo', 'bar', 'foobar']]) check_invalid("l[1] < null") check_invalid("l[1] <= null") @@ -4542,11 +4578,16 @@ class TestCQL(UpgradeTester): for frozen in (False, True): table = "frozentset" if frozen else "tset" - assert_one(cursor, "INSERT INTO %s(k, s) VALUES (0, {'bar', 'foo'}) IF NOT EXISTS" % (table,), [True]) + assert_one(cursor, "INSERT INTO {}(k, s) VALUES (0, {{'bar', 'foo'}}) IF NOT EXISTS".format(table), [True]) def check_applies(condition): - assert_one(cursor, "UPDATE %s SET s = {'bar', 'foo'} WHERE k=0 IF %s" % (table, condition), [True]) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, set(['bar', 'foo'])], cl=ConsistencyLevel.SERIAL) + # UPDATE statement + assert_one(cursor, "UPDATE {} SET s = {{'bar', 'foo'}} WHERE k=0 IF {}".format(table, condition), [True]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'bar', 'foo'}], cl=ConsistencyLevel.SERIAL) + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), [True]) + assert_none(cursor, "SELECT * FROM {}".format(table), cl=ConsistencyLevel.SERIAL) + assert_one(cursor, "INSERT INTO {}(k, s) VALUES (0, {{'bar', 'foo'}}) IF NOT EXISTS".format(table), [True]) check_applies("s = {'bar', 'foo'}") check_applies("s = {'foo', 'bar'}") @@ -4562,9 +4603,14 @@ class TestCQL(UpgradeTester): check_applies("s IN (null, {'bar', 'foo'}, {'a'}) AND s IN ({'a'}, {'bar', 'foo'}, null)") def check_does_not_apply(condition): - assert_one(cursor, "UPDATE %s SET s = {'bar', 'foo'} WHERE k=0 IF %s" % (table, condition), + # UPDATE statement + assert_one(cursor, "UPDATE {} SET s = {{'bar', 'foo'}} WHERE k=0 IF {}".format(table, condition), [False, {'bar', 'foo'}]) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, {'bar', 'foo'}], cl=ConsistencyLevel.SERIAL) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'bar', 'foo'}], cl=ConsistencyLevel.SERIAL) + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), + [False, {'bar', 'foo'}]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'bar', 'foo'}], cl=ConsistencyLevel.SERIAL) # should not apply check_does_not_apply("s = {'baz'}") @@ -4578,8 +4624,12 @@ class TestCQL(UpgradeTester): check_does_not_apply("s != null AND s IN ()") def check_invalid(condition, expected=InvalidRequest): - assert_invalid(cursor, "UPDATE %s SET s = {'bar', 'foo'} WHERE k=0 IF %s" % (table, condition), expected=expected) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, {'bar', 'foo'}], cl=ConsistencyLevel.SERIAL) + # UPDATE statement + assert_invalid(cursor, "UPDATE {} SET s = {{'bar', 'foo'}} WHERE k=0 IF {}".format(table, condition), expected=expected) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'bar', 'foo'}], cl=ConsistencyLevel.SERIAL) + # DELETE statement + assert_invalid(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), expected=expected) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'bar', 'foo'}], cl=ConsistencyLevel.SERIAL) check_invalid("s = {null}") check_invalid("s < null") @@ -4588,13 +4638,20 @@ class TestCQL(UpgradeTester): check_invalid("s >= null") check_invalid("s IN null", expected=SyntaxException) check_invalid("s IN 367", expected=SyntaxException) - check_invalid("s CONTAINS KEY 123", expected=SyntaxException) # element access is not allow for sets check_invalid("s['foo'] = 'foobar'") - # not supported yet - check_invalid("m CONTAINS 'bar'", expected=SyntaxException) + # @jira_ticket CASSANDRA-10537 + if self.get_node_version(is_upgraded) >= LooseVersion(CASSANDRA_4_1): + check_applies("s CONTAINS 'foo'") + check_applies("s CONTAINS 'foo' AND s CONTAINS 'bar'") + check_does_not_apply("s CONTAINS 'baz'") + check_invalid("s CONTAINS null") + check_invalid("s CONTAINS KEY 123") + else: + check_invalid("s CONTAINS null", expected=SyntaxException) + check_invalid("s CONTAINS KEY 123", expected=SyntaxException) @since('2.1.1') def test_whole_map_conditional(self): @@ -4624,8 +4681,13 @@ class TestCQL(UpgradeTester): cursor.execute("INSERT INTO %s(k, m) VALUES (0, {'foo' : 'bar'})" % (table,)) def check_applies(condition): - assert_one(cursor, "UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF %s" % (table, condition), [True]) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) + # UPDATE statement + assert_one(cursor, "UPDATE {} SET m = {{'foo': 'bar'}} WHERE k=0 IF {}".format(table, condition), [True]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), [True]) + assert_none(cursor, "SELECT * FROM {}".format(table), cl=ConsistencyLevel.SERIAL) + cursor.execute("INSERT INTO {}(k, m) VALUES (0, {{'foo' : 'bar'}})".format(table)) check_applies("m = {'foo': 'bar'}") check_applies("m > {'a': 'a'}") @@ -4640,8 +4702,12 @@ class TestCQL(UpgradeTester): check_applies("m != null AND m IN (null, {'a': 'a'}, {'foo': 'bar'})") def check_does_not_apply(condition): - assert_one(cursor, "UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF %s" % (table, condition), [False, {'foo': 'bar'}]) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) + # UPDATE statement + assert_one(cursor, "UPDATE {} SET m = {{'foo': 'bar'}} WHERE k=0 IF {}".format(table, condition), [False, {'foo': 'bar'}]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), [False, {'foo': 'bar'}]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) # should not apply check_does_not_apply("m = {'a': 'a'}") @@ -4655,8 +4721,12 @@ class TestCQL(UpgradeTester): check_does_not_apply("m = null AND m != null") def check_invalid(condition, expected=InvalidRequest): - assert_invalid(cursor, "UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF %s" % (table, condition), expected=expected) - assert_one(cursor, "SELECT * FROM %s" % (table,), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) + # UPDATE statement + assert_invalid(cursor, "UPDATE {} SET m = {{'foo': 'bar'}} WHERE k=0 IF {}".format(table, condition), expected=expected) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) + # DELETE statement + assert_invalid(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), expected=expected) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) check_invalid("m = {null: null}") check_invalid("m = {'a': null}") @@ -4664,11 +4734,20 @@ class TestCQL(UpgradeTester): check_invalid("m < null") check_invalid("m IN null", expected=SyntaxException) - # not supported yet - check_invalid("m CONTAINS 'bar'", expected=SyntaxException) - check_invalid("m CONTAINS KEY 'foo'", expected=SyntaxException) - check_invalid("m CONTAINS null", expected=SyntaxException) - check_invalid("m CONTAINS KEY null", expected=SyntaxException) + # @jira_ticket CASSANDRA-10537 + if self.get_node_version(is_upgraded) >= LooseVersion(CASSANDRA_4_1): + check_applies("m CONTAINS 'bar'") + check_applies("m CONTAINS KEY 'foo'") + check_applies("m CONTAINS 'bar' AND m CONTAINS KEY 'foo'") + check_does_not_apply("m CONTAINS 'foo'") + check_does_not_apply("m CONTAINS KEY 'bar'") + check_invalid("m CONTAINS null") + check_invalid("m CONTAINS KEY null") + else: + check_invalid("m CONTAINS 'bar'", expected=SyntaxException) + check_invalid("m CONTAINS KEY 'foo'", expected=SyntaxException) + check_invalid("m CONTAINS null", expected=SyntaxException) + check_invalid("m CONTAINS KEY null", expected=SyntaxException) @since('2.1') def test_map_item_conditional(self): @@ -4742,8 +4821,13 @@ class TestCQL(UpgradeTester): cursor.execute("INSERT INTO %s (k, m) VALUES (0, {'foo' : 'bar'})" % table) def check_applies(condition): - assert_one(cursor, "UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF %s" % (table, condition), [True]) + # UPDATE statement + assert_one(cursor, "UPDATE {} SET m = {{'foo': 'bar'}} WHERE k=0 IF {}".format(table, condition), [True]) assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), [True]) + assert_none(cursor, "SELECT * FROM {}".format(table), cl=ConsistencyLevel.SERIAL) + cursor.execute("INSERT INTO {} (k, m) VALUES (0, {{'foo' : 'bar'}})".format(table)) check_applies("m['xxx'] = null") check_applies("m['foo'] < 'zzz'") @@ -4759,7 +4843,11 @@ class TestCQL(UpgradeTester): check_applies("m['foo'] < 'zzz' AND m['foo'] > 'aaa'") def check_does_not_apply(condition): - assert_one(cursor, "UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF %s" % (table, condition), [False, {'foo': 'bar'}]) + # UPDATE statement + assert_one(cursor, "UPDATE {} SET m = {{'foo': 'bar'}} WHERE k=0 IF {}".format(table, condition), [False, {'foo': 'bar'}]) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) + # DELETE statement + assert_one(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), [False, {'foo': 'bar'}]) assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}], cl=ConsistencyLevel.SERIAL) check_does_not_apply("m['foo'] < 'aaa'") @@ -4773,7 +4861,11 @@ class TestCQL(UpgradeTester): check_does_not_apply("m['foo'] != null AND m['foo'] = null") def check_invalid(condition, expected=InvalidRequest): - assert_invalid(cursor, "UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF %s" % (table, condition), expected=expected) + # UPDATE statement + assert_invalid(cursor, "UPDATE {} SET m = {{'foo': 'bar'}} WHERE k=0 IF {}".format(table, condition), expected=expected) + assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}]) + # DELETE statement + assert_invalid(cursor, "DELETE FROM {} WHERE k=0 IF {}".format(table, condition), expected=expected) assert_one(cursor, "SELECT * FROM {}".format(table), [0, {'foo': 'bar'}]) check_invalid("m['foo'] < null") --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org