# Copyright 2020 ScyllaDB # # This file is part of Scylla. # # Scylla is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Scylla is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with Scylla. If not, see . ############################################################################# # Tests for finer points of the meaning of "null" in various places ############################################################################# import pytest import re from cassandra.protocol import SyntaxException, AlreadyExists, InvalidRequest, ConfigurationException, ReadFailure from util import unique_name, random_string @pytest.fixture(scope="session") def table1(cql, test_keyspace): table = test_keyspace + "." + unique_name() cql.execute(f"CREATE TABLE {table} (p text, c text, v text, primary key (p, c))") yield table cql.execute("DROP TABLE " + table) # An item cannot be inserted without a key. Verify that before we get into # the really interesting test below - trying to pass "null" as the value of # the key. # See also issue #3665. def test_insert_missing_key(cql, table1): s = random_string() # A clustering key is missing. Cassandra uses the message "Some clustering # keys are missing: c", and Scylla: "Missing mandatory PRIMARY KEY part c" with pytest.raises(InvalidRequest, match=re.compile('missing', re.IGNORECASE)): cql.execute(f"INSERT INTO {table1} (p) VALUES ('{s}')") # Similarly, a missing partition key with pytest.raises(InvalidRequest, match=re.compile('missing', re.IGNORECASE)): cql.execute(f"INSERT INTO {table1} (c) VALUES ('{s}')") # A null key, like a missing one, is also not allowed. # This reproduces issue #7852. @pytest.mark.xfail(reason="issue #7852") def test_insert_null_key(cql, table1): s = random_string() with pytest.raises(InvalidRequest, match='null value'): cql.execute(f"INSERT INTO {table1} (p,c) VALUES ('{s}', null)") with pytest.raises(InvalidRequest, match='null value'): cql.execute(f"INSERT INTO {table1} (p,c) VALUES (null, '{s}')") # Try the same thing with prepared statement, where a "None" stands for # a null. Note that this is completely different from UNSET_VALUE - only # with the latter should the insertion be ignored. stmt = cql.prepare(f"INSERT INTO {table1} (p,c) VALUES (?, ?)") with pytest.raises(InvalidRequest, match='null value'): cql.execute(stmt, [s, None]) with pytest.raises(InvalidRequest, match='null value'): cql.execute(stmt, [None, s])