Files
scylladb/test/cql-pytest/test_native_functions.py
Botond Dénes 098baaef48 Merge 'cql: add missing functions for the COUNTER column type' from Nadav Har'El
We have had support for COUNTER columns for quite some time now, but some functionality was left unimplemented - various internal and CQL functions resulted in "unimplemented" messages when used, and the goal of this series is to fix those issues. The primary goal was to add the missing support for CASTing counters to other types in CQL (issue #14501), but we also add the missing CQL  `counterasblob()` and `blobascounter()` functions (issue #14742).

As usual, the series includes extensive functional tests for these features, and one pre-existing test for CAST that used to fail now begins to pass.

Fixes #14501
Fixes #14742

Closes #14745

* github.com:scylladb/scylladb:
  test/cql-pytest: test confirming that casting to counter doesn't work
  cql: support casting of counter to other types
  cql: implement missing counterasblob() and blobascounter() functions
  cql: implement missing type functions for "counters" type

(cherry picked from commit a637ddd09c)
2023-08-13 14:53:48 +03:00

75 lines
3.9 KiB
Python

# Copyright 2023-present ScyllaDB
#
# SPDX-License-Identifier: AGPL-3.0-or-later
###############################################################################
# Tests for various native (built-in) scalar functions that can be used in
# various SELECT, INSERT or UPDATE requests. Note we also have tests for
# some of these functions in many other test files. For example, the tests
# for the cast() function are in test_cast_data.py.
###############################################################################
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):
with new_test_table(cql, test_keyspace, "p int, i int, g bigint, b blob, s text, t timestamp, u timeuuid, PRIMARY KEY (p)") as table:
yield table
# Check that a function that can take a column name as a parameter, can also
# take a constant. This feature is barely useful for WHERE clauses, and
# even less useful for selectors, but should be allowed for both.
# Reproduces #12607.
@pytest.mark.xfail(reason="issue #12607")
def test_constant_function_parameter(cql, table1):
p = unique_key_int()
cql.execute(f"INSERT INTO {table1} (p, b) VALUES ({p}, 0x03)")
assert [(p,)] == list(cql.execute(f"SELECT p FROM {table1} WHERE p={p} AND b=tinyintAsBlob(3) ALLOW FILTERING"))
assert [(b'\x04',)] == list(cql.execute(f"SELECT tinyintAsBlob(4) FROM {table1} WHERE p={p}"))
# According to the documentation, "The `minTimeuuid` function takes a
# `timestamp` value t, either a timestamp or a date string.". But although
# both cases are supported with constant parameters in WHERE restrictions,
# in a *selector* (the first part of the SELECT, saying what to select), it
# turns out that ONLY a timestamp column is allowed. Although this is
# undocumented behavior, both Cassandra and Scylla share it so we deem it
# correct.
def test_selector_mintimeuuid(cql, table1):
p = unique_key_int()
cql.execute(f"INSERT INTO {table1} (p, s, t, i) VALUES ({p}, '2013-02-02 10:00+0000', 123, 456)")
# We just check this works, not what the value is:
cql.execute(f"SELECT mintimeuuid(t) FROM {table1} WHERE p={p}")
# This doesn't work - despite the documentation, in a selector a
# date string is not supported by mintimeuuid.
with pytest.raises(InvalidRequest, match='of type timestamp'):
cql.execute(f"SELECT mintimeuuid(s) FROM {table1} WHERE p={p}")
# Other integer types also don't work, it must be a timestamp:
with pytest.raises(InvalidRequest, match='of type timestamp'):
cql.execute(f"SELECT mintimeuuid(i) FROM {table1} WHERE p={p}")
# Cassandra allows the implicit (and wrong!) casting of a bigint returned
# by writetime() to the timestamp type required by mintimeuuid(). Scylla
# doesn't. I'm not sure which behavior we should consider correct, but it's
# useful to have a test that demonstrates this incompatibility.
# Reproduces #14319.
@pytest.mark.xfail(reason="issue #14319")
def test_selector_mintimeuuid_64bit(cql, table1):
p = unique_key_int()
cql.execute(f"INSERT INTO {table1} (p, g) VALUES ({p}, 123)")
cql.execute(f"SELECT mintimeuuid(g) FROM {table1} WHERE p={p}")
cql.execute(f"SELECT mintimeuuid(writetime(g)) FROM {table1} WHERE p={p}")
# blobasbigint() must insist to receive a properly-sized (8-byte) blob.
# If it accepts a shorter blob (e.g., 4 bytes) and returns that to the driver,
# it will confuse the driver (the driver will expect to read 8 bytes for the
# bigint but will get only 4).
def test_blobas_wrong_size(cql, table1):
p = unique_key_int()
cql.execute(f"INSERT INTO {table1} (p, i) VALUES ({p}, 123)")
# Cassandra and Scylla print: "In call to function system.blobasbigint,
# value 0x0000007b is not a valid binary representation for type bigint".
with pytest.raises(InvalidRequest, match='blobasbigint'):
cql.execute(f"SELECT blobasbigint(intasblob(i)) FROM {table1} WHERE p={p}")