mirror of
https://github.com/scylladb/scylladb.git
synced 2026-05-01 13:45:53 +00:00
Instead of lengthy blurbs, switch to single-line, machine-readable standardized (https://spdx.dev) license identifiers. The Linux kernel switched long ago, so there is strong precedent. Three cases are handled: AGPL-only, Apache-only, and dual licensed. For the latter case, I chose (AGPL-3.0-or-later and Apache-2.0), reasoning that our changes are extensive enough to apply our license. The changes we applied mechanically with a script, except to licenses/README.md. Closes #9937
177 lines
10 KiB
Python
177 lines
10 KiB
Python
# This file was translated from the original Java test from the Apache
|
|
# Cassandra source repository, as of commit 6ca34f81386dc8f6020cdf2ea4246bca2a0896c5
|
|
#
|
|
# The original Apache Cassandra license:
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
from cassandra_tests.porting import *
|
|
|
|
from cassandra.protocol import SyntaxException, AlreadyExists, InvalidRequest, ConfigurationException
|
|
from cassandra.query import UNSET_VALUE
|
|
|
|
# Test for the validation bug of CASSANDRA-4706,
|
|
# migrated from cql_tests.py:TestCQL.validate_counter_regular_test()
|
|
def testRegularCounters(cql, test_keyspace):
|
|
# The Cassandra and Scylla error messages are different: Cassandra says
|
|
# "Cannot mix counter and non counter columns in the same table", Scylla
|
|
# "Cannot add a non counter column (things) in a counter column family".
|
|
# Let's just check the common phrase "non counter".
|
|
# Cassandra changed the exception it throws on dropping a nonexistent keyspace.
|
|
# FIXME: Cassandra throws InvalidRequest here, but Scylla uses
|
|
# ConfigurationException. We shouldn't have done that... But I consider
|
|
# this difference to be so trivial I didn't want to consider this a bug.
|
|
# Maybe we should reconsider, and not allow ConfigurationException...
|
|
assert_invalid_throw_message(cql, test_keyspace + "." + unique_name(),
|
|
"non counter",
|
|
(InvalidRequest, ConfigurationException),
|
|
"CREATE TABLE %s (id bigint PRIMARY KEY, count counter, things set<text>)")
|
|
|
|
# Migrated from cql_tests.py:TestCQL.collection_counter_test()
|
|
def testCountersOnCollections(cql, test_keyspace):
|
|
assert_invalid_throw(cql, test_keyspace + "." + unique_name(),
|
|
InvalidRequest,
|
|
"CREATE TABLE %s (k int PRIMARY KEY, l list<counter>)")
|
|
|
|
assert_invalid_throw(cql, test_keyspace + "." + unique_name(),
|
|
InvalidRequest,
|
|
"CREATE TABLE %s (k int PRIMARY KEY, s set<counter>)")
|
|
|
|
assert_invalid_throw(cql, test_keyspace + "." + unique_name(),
|
|
InvalidRequest,
|
|
"CREATE TABLE %s (k int PRIMARY KEY, m map<text, counter>)")
|
|
|
|
def testCounterUpdatesWithUnset(cql, test_keyspace):
|
|
with create_table(cql, test_keyspace, "(k int PRIMARY KEY, c counter)") as table:
|
|
# set up
|
|
execute(cql, table, "UPDATE %s SET c = c + 1 WHERE k = 10")
|
|
assert_rows(execute(cql, table, "SELECT c FROM %s WHERE k = 10"), [1])
|
|
# increment
|
|
execute(cql, table, "UPDATE %s SET c = c + ? WHERE k = 10", 1)
|
|
assert_rows(execute(cql, table, "SELECT c FROM %s WHERE k = 10"), [2])
|
|
execute(cql, table, "UPDATE %s SET c = c + ? WHERE k = 10", UNSET_VALUE)
|
|
assert_rows(execute(cql, table, "SELECT c FROM %s WHERE k = 10"), [2]) # no change to the counter value
|
|
# decrement
|
|
execute(cql, table, "UPDATE %s SET c = c - ? WHERE k = 10", 1)
|
|
assert_rows(execute(cql, table, "SELECT c FROM %s WHERE k = 10"), [1])
|
|
execute(cql, table, "UPDATE %s SET c = c - ? WHERE k = 10", UNSET_VALUE)
|
|
assert_rows(execute(cql, table, "SELECT c FROM %s WHERE k = 10"), [1]) # no change to the counter value
|
|
|
|
|
|
def testCounterFiltering(cql, test_keyspace):
|
|
with create_table(cql, test_keyspace, "(k int PRIMARY KEY, a counter)") as table:
|
|
for i in range(10):
|
|
execute(cql, table, "UPDATE %s SET a = a + ? WHERE k = ?", i, i)
|
|
|
|
execute(cql, table, "UPDATE %s SET a = a + ? WHERE k = ?", 6, 10)
|
|
|
|
# GT
|
|
assert_rows_ignoring_order(execute(cql, table, "SELECT * FROM %s WHERE a > ? ALLOW FILTERING", 5),
|
|
[6, 6], [7, 7], [8, 8], [9, 9], [10, 6])
|
|
|
|
# GTE
|
|
assert_rows_ignoring_order(execute(cql, table, "SELECT * FROM %s WHERE a >= ? ALLOW FILTERING", 6),
|
|
[6, 6], [7, 7], [8, 8], [9, 9], [10, 6])
|
|
|
|
# LT
|
|
assert_rows_ignoring_order(execute(cql, table, "SELECT * FROM %s WHERE a < ? ALLOW FILTERING", 3),
|
|
[0,0], [1, 1], [2, 2])
|
|
|
|
# LTE
|
|
assert_rows_ignoring_order(execute(cql, table, "SELECT * FROM %s WHERE a <= ? ALLOW FILTERING", 3),
|
|
[0,0], [1, 1], [2, 2], [3, 3])
|
|
|
|
# EQ
|
|
assert_rows_ignoring_order(execute(cql, table, "SELECT * FROM %s WHERE a = ? ALLOW FILTERING", 6),
|
|
[6, 6], [10, 6])
|
|
|
|
def testCounterFilteringWithNull(cql, test_keyspace):
|
|
with create_table(cql, test_keyspace, "(k int PRIMARY KEY, a counter, b counter)") as table:
|
|
execute(cql, table, "UPDATE %s SET a = a + ? WHERE k = ?", 1, 1)
|
|
|
|
assert_rows(execute(cql, table, "SELECT * FROM %s WHERE a > ? ALLOW FILTERING", 0), [1, 1, None])
|
|
# GT
|
|
assert_empty(execute(cql, table, "SELECT * FROM %s WHERE b > ? ALLOW FILTERING", 1))
|
|
# GTE
|
|
assert_empty(execute(cql, table, "SELECT * FROM %s WHERE b >= ? ALLOW FILTERING", 1))
|
|
# LT
|
|
assert_empty(execute(cql, table, "SELECT * FROM %s WHERE b < ? ALLOW FILTERING", 1))
|
|
# LTE
|
|
assert_empty(execute(cql, table, "SELECT * FROM %s WHERE b <= ? ALLOW FILTERING", 1))
|
|
# EQ
|
|
assert_empty(execute(cql, table, "SELECT * FROM %s WHERE b = ? ALLOW FILTERING", 1))
|
|
# with null
|
|
assert_invalid_message(cql, table, "Invalid null value for counter increment/decrement",
|
|
"SELECT * FROM %s WHERE b = null ALLOW FILTERING")
|
|
|
|
# Test for the validation bug of CASSANDRA-9395.
|
|
def testProhibitReversedCounterAsPartOfPrimaryKey(cql, test_keyspace):
|
|
# The Cassandra message and Scylla message differ slightly -
|
|
# counter type is not supported for PRIMARY KEY column 'a'"
|
|
# counter type is not supported for PRIMARY KEY part a
|
|
# respectively.
|
|
assert_invalid_throw_message(cql, test_keyspace + "." + unique_name(),
|
|
"counter type is not supported for PRIMARY KEY",
|
|
InvalidRequest,
|
|
"CREATE TABLE %s (a counter, b int, PRIMARY KEY (b, a)) WITH CLUSTERING ORDER BY (a desc);")
|
|
|
|
# Check that a counter batch works as intended
|
|
def testCounterBatch(cql, test_keyspace):
|
|
with create_table(cql, test_keyspace, "(userid int, url text, total counter, PRIMARY KEY (userid, url))") as table:
|
|
# Ensure we handle updates to the same CQL row in the same partition properly
|
|
execute(cql, table, "BEGIN UNLOGGED BATCH " +
|
|
"UPDATE %s SET total = total + 1 WHERE userid = 1 AND url = 'http://foo.com'; " +
|
|
"UPDATE %s SET total = total + 1 WHERE userid = 1 AND url = 'http://foo.com'; " +
|
|
"UPDATE %s SET total = total + 1 WHERE userid = 1 AND url = 'http://foo.com'; " +
|
|
"APPLY BATCH; ")
|
|
assert_rows(execute(cql, table, "SELECT total FROM %s WHERE userid = 1 AND url = 'http://foo.com'"), [3])
|
|
|
|
# Ensure we handle different CQL rows in the same partition properly
|
|
execute(cql, table, "BEGIN UNLOGGED BATCH " +
|
|
"UPDATE %s SET total = total + 1 WHERE userid = 1 AND url = 'http://bar.com'; " +
|
|
"UPDATE %s SET total = total + 1 WHERE userid = 1 AND url = 'http://baz.com'; " +
|
|
"UPDATE %s SET total = total + 1 WHERE userid = 1 AND url = 'http://bad.com'; " +
|
|
"APPLY BATCH; ")
|
|
assert_rows(execute(cql, table, "SELECT url, total FROM %s WHERE userid = 1"),
|
|
["http://bad.com", 1],
|
|
["http://bar.com", 1],
|
|
["http://baz.com", 1],
|
|
["http://foo.com", 3]) # from previous batch
|
|
|
|
with create_table(cql, test_keyspace, "(userid int, url text, first counter, second counter, third counter, PRIMARY KEY (userid, url))") as table:
|
|
# Different counters in the same CQL Row
|
|
execute(cql, table, "BEGIN UNLOGGED BATCH " +
|
|
"UPDATE %s SET first = first + 1 WHERE userid = 1 AND url = 'http://foo.com'; " +
|
|
"UPDATE %s SET first = first + 1 WHERE userid = 1 AND url = 'http://foo.com'; " +
|
|
"UPDATE %s SET second = second + 1 WHERE userid = 1 AND url = 'http://foo.com'; " +
|
|
"APPLY BATCH; ")
|
|
assert_rows(execute(cql, table, "SELECT first, second, third FROM %s WHERE userid = 1 AND url = 'http://foo.com'"),
|
|
[2, 1, None])
|
|
|
|
# Different counters in different CQL Rows
|
|
execute(cql, table, "BEGIN UNLOGGED BATCH " +
|
|
"UPDATE %s SET first = first + 1 WHERE userid = 1 AND url = 'http://bad.com'; " +
|
|
"UPDATE %s SET first = first + 1, second = second + 1 WHERE userid = 1 AND url = 'http://bar.com'; " +
|
|
"UPDATE %s SET first = first - 1, second = second - 1 WHERE userid = 1 AND url = 'http://bar.com'; " +
|
|
"UPDATE %s SET second = second + 1 WHERE userid = 1 AND url = 'http://baz.com'; " +
|
|
"APPLY BATCH; ")
|
|
assert_rows(execute(cql, table, "SELECT url, first, second, third FROM %s WHERE userid = 1"),
|
|
["http://bad.com", 1, None, None],
|
|
["http://bar.com", 0, 0, None],
|
|
["http://baz.com", None, 1, None],
|
|
["http://foo.com", 2, 1, None]) # from previous batch
|
|
|
|
|
|
# Different counters in different partitions
|
|
execute(cql, table, "BEGIN UNLOGGED BATCH " +
|
|
"UPDATE %s SET first = first + 1 WHERE userid = 2 AND url = 'http://bad.com'; " +
|
|
"UPDATE %s SET first = first + 1, second = second + 1 WHERE userid = 3 AND url = 'http://bar.com'; " +
|
|
"UPDATE %s SET first = first - 1, second = second - 1 WHERE userid = 4 AND url = 'http://bar.com'; " +
|
|
"UPDATE %s SET second = second + 1 WHERE userid = 5 AND url = 'http://baz.com'; " +
|
|
"APPLY BATCH; ")
|
|
assert_rows_ignoring_order(execute(cql, table, "SELECT userid, url, first, second, third FROM %s WHERE userid IN (2, 3, 4, 5)"),
|
|
[2, "http://bad.com", 1, None, None],
|
|
[3, "http://bar.com", 1, 1, None],
|
|
[4, "http://bar.com", -1, -1, None],
|
|
[5, "http://baz.com", None, 1, None])
|