Files
scylladb/test/cql-pytest/test_alter_table.py

72 lines
3.3 KiB
Python

# Copyright 2024-present ScyllaDB
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# Tests for alter table statement
import time
import pytest
from util import new_test_table, unique_name
from nodetool import flush
# Test checks only case of preparing `ALTER TABLE ... DROP ... USING TIMESTAMP ?` statement.
# It is `scylla_only` because Cassandra doesn't allow to prepare the statement with ? as the timestamp.
# More tests about `ALTER TABLE ... DROP ...` are in cassandra_tests/validation/operation/alter_test.py
def testDropColumnWithTimestampPrepared(scylla_only, cql, test_keyspace):
with new_test_table(cql, test_keyspace, "id int, c1 int, v1 int, todrop int, PRIMARY KEY (id, c1)") as table:
prepared = cql.prepare(f"ALTER TABLE {table} DROP todrop USING TIMESTAMP ?")
for i in range(5):
cql.execute(f"INSERT INTO {table} (id, c1, v1, todrop) VALUES (1, {i}, {i}, {i}) USING TIMESTAMP {10000 * i}")
# It's safer to flush the table now
# Flushing is not necessary, if we are sure the table will be always in memory.
# But if the table is flushed just after dropping the column, all data from the column would be lost.
# (the data isn't part of schema at that point, so it's not saved to sstable during flush)
flush(cql, table)
cql.execute(prepared, [20000])
cql.execute(f"ALTER TABLE {table} ADD todrop int")
cql.execute(f"INSERT INTO {table} (id, c1, v1, todrop) VALUES (1, 100, 100, 100) USING TIMESTAMP 30000")
result = set(cql.execute(f"SELECT id, c1, v1, todrop FROM {table}"))
assert result == set([
(1, 0, 0, None),
(1, 1, 1, None),
(1, 2, 2, None),
(1, 3, 3, 3),
(1, 4, 4, 4),
(1, 100, 100, 100)
])
# We allow to prepare alter table statement when the schema doesn't exist yet
def testDropColumnWithTimestampPreparedNonExistingSchema(scylla_only, cql, test_keyspace):
table = test_keyspace + "." + unique_name()
prepared = cql.prepare(f"ALTER TABLE {table} DROP todrop USING TIMESTAMP ?")
cql.execute(f"CREATE TABLE {table} (id int, c1 int, v1 int, todrop int, PRIMARY KEY (id, c1))")
try:
for i in range(5):
cql.execute(f"INSERT INTO {table} (id, c1, v1, todrop) VALUES (1, {i}, {i}, {i}) USING TIMESTAMP {10000 * i}")
# It's safer to flush the table now
# Flushing is not necessary, if we are sure the table will be always in memory.
# But if the table is flushed just after dropping the column, all data from the column would be lost.
# (the data isn't part of schema at that point, so it's not saved to sstable during flush)
flush(cql, table)
cql.execute(prepared, [20000])
cql.execute(f"ALTER TABLE {table} ADD todrop int")
cql.execute(f"INSERT INTO {table} (id, c1, v1, todrop) VALUES (1, 100, 100, 100) USING TIMESTAMP 30000")
result = set(cql.execute(f"SELECT id, c1, v1, todrop FROM {table}"))
assert result == set([
(1, 0, 0, None),
(1, 1, 1, None),
(1, 2, 2, None),
(1, 3, 3, 3),
(1, 4, 4, 4),
(1, 100, 100, 100)
])
finally:
cql.execute(f"DROP TABLE {table}")