Files
scylladb/test/cqlpy/test_udf.py
Andrei Chekun 6c267bbc70 test.py: Make it test/cqlpy python module
Removed all path modification and migrated to python way of importing packages. This is another small step to the one pool cluster for better scheduling and better resource utilization.

Fixes: https://github.com/scylladb/scylladb/issues/21644

Closes scylladb/scylladb#21585
2024-12-01 18:26:17 +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}")