Files
scylladb/test/cqlpy/test_udf.py
Nadav Har'El 8c215141a1 test: rename "cql-pytest" to "cqlpy"
Python and Python developers don't like directory names to include a
minus sign, like "cql-pytest". In this patch we rename test/cql-pytest
to test/cqlpy, and also change a few references in other code (e.g., code
that used test/cql-pytest/run.py) and also references to this test suite
in documentation and comments.

Arguably, the word "test" was always redundant in test/cql-pytest, and
I want to leave the "py" in test/cqlpy to emphasize that it's Python-based
tests, contrasting with test/cql which are CQL-request-only approval
tests.

Fixes #20846

Signed-off-by: Nadav Har'El <nyh@scylladb.com>
2024-11-06 16:48:36 +02:00

68 lines
3.5 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2023-present ScyllaDB
#
# SPDX-License-Identifier: AGPL-3.0-or-later
#############################################################################
# Tests for user-defined functions (UDF)
#############################################################################
import pytest
from util import unique_name, new_function
from cassandra.protocol import InvalidRequest
# Unfortunately, while ScyllaDB and Cassandra support the same UDF
# feature, each supports a different choice of languages. In particular,
# Cassandra supports Java and ScyllaDB doesn't - but ScyllaDB supports
# Lua. The following fixture can be used to check if the server supports
# Java UDFs - and if it doesn't, the test should use Lua.
@pytest.fixture(scope="session")
def has_java_udf(cql, test_keyspace):
try:
with new_function(cql, test_keyspace, "(i int) CALLED ON NULL INPUT RETURNS int LANGUAGE java AS 'return 42;'"):
return True
except InvalidRequest as e:
# When the language "java" is not supported, Scylla prints the
# error message "Language 'java' is not supported". Cassandra
# isn't expected to fail here because it does support Java.
# Any other error here indicates an unexpected bug.
assert "Language 'java' is not supported" in str(e)
return False
# Test that if we have an overloaded function (i.e., two functions with the
# same name, just with different parameters), DROP FUNCTION requires
# disambiguating which function you want to drop. Without parameters, the
# DROP will be an error. On the other hand, when a function is not
# overloaded and has a unique name, it's not necessary to list the
# parameters in the DROP command.
def test_drop_overloaded_udf(cql, test_keyspace, has_java_udf):
if has_java_udf:
body1 = "(i int) CALLED ON NULL INPUT RETURNS bigint LANGUAGE java AS 'return 42L;'"
body2 = "(i int, j int) CALLED ON NULL INPUT RETURNS bigint LANGUAGE java AS 'return 42L;'"
else:
body1 = "(i int) CALLED ON NULL INPUT RETURNS bigint LANGUAGE lua AS 'return 42;'"
body2 = "(i int, j int) CALLED ON NULL INPUT RETURNS bigint LANGUAGE lua AS 'return 42;'"
args1 = "int"
args2 = "int, int"
# Create two different functions with the same name fun, but a
# different signature (different parameters):
fun = unique_name()
with new_function(cql, test_keyspace, body1, name=fun, args=args1):
with new_function(cql, test_keyspace, body2, name=fun, args=args2):
# Shouldn't be able to DROP "fun" without parameters, because
# it's ambiguous.
with pytest.raises(InvalidRequest, match="multiple function"):
cql.execute(f"DROP FUNCTION {test_keyspace}.{fun}")
# Should be ok to DROP one of the "fun" instances by specifying
# its parameters explicitly
cql.execute(f"DROP FUNCTION {test_keyspace}.{fun}({args2})")
# Now there's only one function left with that name, so it
# should be fine to drop "fun" without explicit parameters:
cql.execute(f"DROP FUNCTION {test_keyspace}.{fun}")
# The new_function() context manager will expect the functions
# to exist when it ends, to drop them. But we just dropped them.
# So let's recreate them to pacify new_function():
cql.execute(f"CREATE FUNCTION {test_keyspace}.{fun} {body1}")
cql.execute(f"CREATE FUNCTION {test_keyspace}.{fun} {body2}")