test/cql-pytest: reproducer for bug crashing Scylla on mismatched tuple
This patch addes a reproducing test for issue #13241, where attempting a SELECT restriction (b,c,d) IN ((1,2)) - where the tuple is shorter than needed - crashes Scylla (on segmentation fault) instead of generating a clean error as it should (and as done on Cassandra). The test also demonstractes that if the tuple is longer than needed (instead of shorter), the behavior is correct, and it is also correct if "=" is used instead of IN. Only the combination of IN and too-short tuple seems to be broken - but broken in a bad way (can be used to crash Scylla). Because the test crashes Scylla when fails, it is marked "skip". Refs #13241 Signed-off-by: Nadav Har'El <nyh@scylladb.com> Closes #13244
This commit is contained in:
committed by
Botond Dénes
parent
fc927b1774
commit
8b0822be77
@@ -12,6 +12,7 @@
|
||||
|
||||
import pytest
|
||||
from util import new_test_table, unique_key_int
|
||||
from cassandra.protocol import InvalidRequest
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def table1(cql, test_keyspace):
|
||||
@@ -23,6 +24,11 @@ def table2(cql, test_keyspace):
|
||||
with new_test_table(cql, test_keyspace, "a int, b int, PRIMARY KEY (a, b)") as table:
|
||||
yield table
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def table3(cql, test_keyspace):
|
||||
with new_test_table(cql, test_keyspace, "a int, b int, c int, d int, PRIMARY KEY (a, b, c, d)") as table:
|
||||
yield table
|
||||
|
||||
# Cassandra does not allow a WHERE clause restricting the same column with
|
||||
# an equality more than once. It complains that that column "cannot be
|
||||
# restricted by more than one relation if it includes an Equal".
|
||||
@@ -73,3 +79,36 @@ def test_multiple_restrictions_on_ck(cql, table2, scylla_only):
|
||||
assert [(p, 0)] == list(cql.execute(f'SELECT * FROM {table2} WHERE a = {p} AND b < 4 AND b < 1'))
|
||||
assert [(p, 0)] == list(cql.execute(f'SELECT * FROM {table2} WHERE a = {p} AND b < 1 AND b < 4'))
|
||||
assert [(p, 0)] == list(cql.execute(f'SELECT * FROM {table2} WHERE a = {p} AND b < 1 AND b < 2'))
|
||||
|
||||
# Try a multi-column restriction on several clustering columns, with the wrong
|
||||
# number of values on the right-hand-side of the restriction. Scylla should
|
||||
# cleanly report the error - and not silently ignore it or even crash as in
|
||||
# issue #13241.
|
||||
@pytest.mark.skip("Crashes due to issue #13241")
|
||||
def test_multi_column_restriction_in(cql, table3):
|
||||
p = unique_key_int()
|
||||
cql.execute(f'INSERT INTO {table3} (a, b, c, d) VALUES ({p}, 1, 2, 3)')
|
||||
# The tuple (1,2,3) is the same length as (b,c,d) so the query works:
|
||||
assert [(p,1,2,3)] == list(cql.execute(f'SELECT * FROM {table3} WHERE a={p} AND (b,c,d) IN ((1,2,3))'))
|
||||
# IN can also list several tuples of the same length:
|
||||
assert [(p,1,2,3)] == list(cql.execute(f'SELECT * FROM {table3} WHERE a={p} AND (b,c,d) IN ((4,5,6), (1,2,3))'))
|
||||
# The tuple (1,2,3,4) is too long, so fails - with different error-
|
||||
# messages in Scylla and Cassandra:
|
||||
with pytest.raises(InvalidRequest):
|
||||
cql.execute(f'SELECT * FROM {table3} WHERE a={p} AND (b,c,d) IN ((1, 2, 3, 4))')
|
||||
# The tuple (1,2) is too short, so should also fail. Reproduces #13241:
|
||||
with pytest.raises(InvalidRequest):
|
||||
cql.execute(f'SELECT * FROM {table3} WHERE a={p} AND (b,c,d) IN ((1, 2))')
|
||||
|
||||
def test_multi_column_restriction_eq(cql, table3):
|
||||
p = unique_key_int()
|
||||
cql.execute(f'INSERT INTO {table3} (a, b, c, d) VALUES ({p}, 1, 2, 3)')
|
||||
# The tuple (1,2,3) is the same length as (b,c,d) so the query works:
|
||||
assert [(p,1,2,3)] == list(cql.execute(f'SELECT * FROM {table3} WHERE a={p} AND (b,c,d) = (1,2,3)'))
|
||||
# The tuple (1,2,3,4) is too long, so fails - with different error-
|
||||
# messages in Scylla and Cassandra:
|
||||
with pytest.raises(InvalidRequest):
|
||||
cql.execute(f'SELECT * FROM {table3} WHERE a={p} AND (b,c,d) = (1, 2, 3, 4)')
|
||||
# The tuple (1,2) is too short, so should also fail.
|
||||
with pytest.raises(InvalidRequest):
|
||||
cql.execute(f'SELECT * FROM {table3} WHERE a={p} AND (b,c,d) = (1, 2)')
|
||||
|
||||
Reference in New Issue
Block a user