From d5748fd8955c508551c12c332295b9293d66984b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadwiszczak?= Date: Wed, 21 Jun 2023 13:04:58 +0200 Subject: [PATCH 1/3] cql3:statements:describe_statement: include UDT/UDF/UDA in generic describe So far generic describe (`DESC `) followed Cassandra implementation and it only described keyspace/table/view/index. This commit adds UDT/UDF/UDA to generic describe. Fixes: #14170 --- cql3/statements/describe_statement.cc | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/cql3/statements/describe_statement.cc b/cql3/statements/describe_statement.cc index 732483422284..942fe64c993c 100644 --- a/cql3/statements/describe_statement.cc +++ b/cql3/statements/describe_statement.cc @@ -659,6 +659,7 @@ std::vector> generic_describe_statement::get future>> generic_describe_statement::describe(cql3::query_processor& qp, const service::client_state& client_state) const { auto db = qp.db(); + auto& replica_db = db.real_database(); auto raw_ks = client_state.get_raw_keyspace(); auto ks_name = (_keyspace) ? *_keyspace : raw_ks; @@ -671,6 +672,12 @@ future>> generic_describe_statement::describe throw exceptions::invalid_request_exception(format("'{}' not found in keyspaces", _name)); } } + + auto ks = db.try_find_keyspace(ks_name); + if (!ks) { + throw exceptions::invalid_request_exception(format("'{}' not found in keyspaces", _name)); + } + auto ks_meta = ks->metadata(); auto tbl = db.try_find_table(ks_name, _name); if (tbl) { @@ -686,6 +693,32 @@ future>> generic_describe_statement::describe co_return serialize_descriptions({index(db, ks_name, _name, _with_internals)}); } + auto udt_meta = ks_meta->user_types(); + if (udt_meta.has_type(to_bytes(_name))) { + co_return serialize_descriptions({type(replica_db, ks_meta, _name)}); + } + + auto uf = functions::functions::find(functions::function_name(ks_name, _name)); + if (!uf.empty()) { + auto udfs = boost::copy_range>>(uf | boost::adaptors::transformed([] (const auto& f) { + return dynamic_pointer_cast(f.second); + }) | boost::adaptors::filtered([] (const auto& f) { + return f != nullptr; + })); + if (!udfs.empty()) { + co_return serialize_descriptions(co_await generate_descriptions(replica_db, udfs, true)); + } + + auto udas = boost::copy_range>>(uf | boost::adaptors::transformed([] (const auto& f) { + return dynamic_pointer_cast(f.second); + }) | boost::adaptors::filtered([] (const auto& f) { + return f != nullptr; + })); + if (!udas.empty()) { + co_return serialize_descriptions(co_await generate_descriptions(replica_db, udas, true)); + } + } + throw exceptions::invalid_request_exception(format("'{}' not found in keyspace '{}'", _name, ks_name)); } From 58eb7a45b70b27b7b450e013df75d088f9bf70e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadwiszczak?= Date: Fri, 23 Jun 2023 12:58:26 +0200 Subject: [PATCH 2/3] cql-pytest:test_describe: add test for generic UDT/UDF/UDA desc --- test/cql-pytest/test_describe.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/test/cql-pytest/test_describe.py b/test/cql-pytest/test_describe.py index f1c9894d293b..34398f8437f0 100644 --- a/test/cql-pytest/test_describe.py +++ b/test/cql-pytest/test_describe.py @@ -439,7 +439,16 @@ def test_index_desc_in_table_desc(cql, test_keyspace): assert create_idx_c in desc assert f"CREATE INDEX {tbl_name}_b_idx_1 ON {tbl}((a), b)" in desc -# Test that generic 'DESC' works properly. It should be able to describe keyspace, table. +# ----------------------------------------------------------------------------- +# "Generic describe" is a describe statement without specifying what kind of object +# you want to describe, so it only requires keyspace name(optionally) and object name. +# Genric describe should be exactly the same as normal describe, so for instannce: +# `DESC TABLE == DESC `. +# +# ScyllaDB looks for describing object in a following order: +# keyspace, table, view, index, UDT, UDF, UDA + +# Cassandra compatibility require us to be able generic describe: keyspace, table, view, index. def test_generic_desc(cql, random_seed): with new_random_keyspace(cql) as ks: with new_random_table(cql, ks) as t1, new_test_table(cql, ks, "a int primary key, b int, c int") as tbl: @@ -460,6 +469,27 @@ def test_generic_desc(cql, random_seed): assert generic_tbl == desc_tbl assert generic_idx == desc_idx +# We've extended generic describe to include user-defined objects: UDTs, UDFs and UDAs. +# Since Cassandra doesn't generic description of support user-defined objects, +# the test is `scylla_only`. +# Reproduces #14170 +def test_generic_desc_user_defined(scylla_only, cql, test_keyspace): + with new_random_type(cql, test_keyspace) as udt: + assert cql.execute(f"DESC {udt}") == cql.execute(f"DESC TYPE {udt}") + + with new_function(cql, test_keyspace, """ + (val1 int, val2 int) + RETURNS NULL ON NULL INPUT + RETURNS int + LANGUAGE lua + AS 'return val1 + val2' + """) as fn: + assert cql.execute(f"DESC {test_keyspace}.{fn}") == cql.execute(f"DESC FUNCTION {test_keyspace}.{fn}") + + with new_aggregate(cql, test_keyspace, f"(int) SFUNC {fn} STYPE int INITCOND 0") as aggr: + assert cql.execute(f"DESC {test_keyspace}.{aggr}") == cql.execute(f"DESC AGGREGATE {test_keyspace}.{aggr}") + + # Test that 'DESC FUNCTION'/'DESC AGGREGATE' doesn't show UDA/UDF and doesn't crash Scylla def test_desc_udf_uda(cql, test_keyspace): with new_function(cql, test_keyspace, "(a int, b int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE LUA AS 'return a+b'") as fn: From 2071ade171fa7676c84d2f3bfe7cb89cc71a5d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Jadwiszczak?= Date: Fri, 23 Jun 2023 13:41:37 +0200 Subject: [PATCH 3/3] docs:cql: add information about generic describe In our cql's documentation, there was no information that type can be omitted in a describe statement. Added this information along with the order of looking for the element. --- docs/cql/cqlsh.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/cql/cqlsh.rst b/docs/cql/cqlsh.rst index 3f988aa885a6..3ea5d40e64ce 100644 --- a/docs/cql/cqlsh.rst +++ b/docs/cql/cqlsh.rst @@ -380,6 +380,9 @@ dumping all or portions of the schema. In any of the commands, ``DESC`` may be used in place of ``DESCRIBE``. +You may also omit what you want to describe and just simply use ``DESCRIBE ``. This will look for the object + in a specific order: keyspace, table, view, index, user-defined type, user-defined function, user-defined aggregate. + The ``DESCRIBE CLUSTER`` command prints the cluster name and partitioner::