treewide: Return create statement optionally in describe functions

We add a new parameter in functions used to generate instances
of `cql3::description` for types related to situations where we
might not need a create statement. An example of such a scenario
could be `DESCRIBE TYPES`.
This commit is contained in:
Dawid Mędrek
2024-09-12 15:40:00 +02:00
parent 0702e93e32
commit 86722e4cea
11 changed files with 81 additions and 20 deletions

View File

@@ -9,6 +9,7 @@
#pragma once
#include <seastar/core/sstring.hh>
#include <seastar/util/bool_class.hh>
#include "bytes_fwd.hh"
@@ -19,6 +20,30 @@ using namespace seastar;
namespace cql3 {
/// Tag indicating whether a describe function should return a `cql3::description`
/// with a `create_statement` or not.
using with_create_statement = bool_class<struct with_create_statement_tag>;
/// An option type that functions generating instances of `cql3::description`
/// can be parameterized with.
///
/// In some cases, the user doesn't need a create statement, so producing it
/// is a waste of time. An example of that could be `DESCRIBE TYPES`.
///
/// In some other cases, we may want to produce either a less, or a more detailed
/// create statement depending on the context. An example of that is
/// `DESCRIBE SCHEMA [WITH INTERNALS]` that may print additional details of tables
/// when the `WITH INTERNALS` option is used.
///
/// Some entities can generate `cql3::description`s parameterized by those two
/// characteristics and this type embodies the choice of the user.
enum class describe_option {
NO_STMTS, /// Describe an entity, but don't generate a create statement.
STMTS, /// Describe an entity and generate a create statement.
STMTS_AND_INTERNALS /// Describe an entity and generate a create statement,
/// including internal details.
};
/// Type representing an entity that can be restored by performing
/// a SINGLE CQL query. It can correspond to a tangible object such as
/// a keyspace, a table, or a role, as well as to a more abstract concept

View File

@@ -9,6 +9,7 @@
*/
#include "bytes.hh"
#include "cql3/description.hh"
#include "types/types.hh"
#include "types/tuple.hh"
#include "cql3/functions/scalar_function.hh"
@@ -355,7 +356,12 @@ user_aggregate::user_aggregate(function_name fname, bytes_opt initcond, ::shared
bool user_aggregate::has_finalfunc() const { return _agg.state_to_result_function != nullptr; }
description user_aggregate::describe() const {
description user_aggregate::describe(with_create_statement with_stmt) const {
auto maybe_create_statement = std::invoke([&] -> std::optional<sstring> {
if (!with_stmt) {
return std::nullopt;
}
auto ks = cql3::util::maybe_quote(name().keyspace);
auto na = cql3::util::maybe_quote(name().name);
@@ -384,16 +390,19 @@ description user_aggregate::describe() const {
}
os << ";";
return std::move(os).str();
});
return description {
.keyspace = name().keyspace,
.type = "aggregate",
.name = name().name,
.create_statement = std::move(os).str()
.create_statement = std::move(maybe_create_statement)
};
}
std::ostream& user_aggregate::describe(std::ostream& os) const {
auto desc = describe();
auto desc = describe(with_create_statement::yes);
os << *desc.create_statement;
return os;
}

View File

@@ -27,7 +27,7 @@ public:
virtual sstring element_type() const override { return "aggregate"; }
virtual std::ostream& describe(std::ostream& os) const override;
description describe() const;
description describe(with_create_statement) const;
seastar::shared_ptr<scalar_function> sfunc() const {
return _agg.aggregation_function;

View File

@@ -7,6 +7,7 @@
*/
#include "user_function.hh"
#include "cql3/description.hh"
#include "cql3/util.hh"
#include "log.hh"
#include "lang/wasm.hh"
@@ -66,7 +67,12 @@ bytes_opt user_function::execute(std::span<const bytes_opt> parameters) {
});
}
description user_function::describe() const {
description user_function::describe(with_create_statement with_stmt) const {
auto maybe_create_statement = std::invoke([&] -> std::optional<sstring> {
if (!with_stmt) {
return std::nullopt;
}
auto ks = cql3::util::maybe_quote(name().keyspace);
auto na = cql3::util::maybe_quote(name().name);
@@ -93,16 +99,19 @@ description user_function::describe() const {
<< _body << "\n"
<< "$$;";
return std::move(os).str();
});
return description {
.keyspace = name().keyspace,
.type = "function",
.name = name().name,
.create_statement = std::move(os).str()
.create_statement = std::move(maybe_create_statement)
};
}
std::ostream& user_function::describe(std::ostream& os) const {
auto desc = describe();
auto desc = describe(with_create_statement::yes);
os << *desc.create_statement;
return os;
}

View File

@@ -67,7 +67,7 @@ public:
virtual sstring element_type() const override { return "function"; }
virtual std::ostream& describe(std::ostream& os) const override;
description describe() const;
description describe(with_create_statement) const;
};
}

View File

@@ -352,7 +352,12 @@ no_such_column_family::no_such_column_family(std::string_view ks_name, const tab
{
}
cql3::description keyspace_metadata::describe(const replica::database& db) const {
cql3::description keyspace_metadata::describe(const replica::database& db, cql3::with_create_statement with_create_statement) const {
auto maybe_create_statement = std::invoke([&] -> std::optional<sstring> {
if (!with_create_statement) {
return std::nullopt;
}
std::ostringstream os;
os << "CREATE KEYSPACE " << cql3::util::maybe_quote(_name)
@@ -376,16 +381,19 @@ cql3::description keyspace_metadata::describe(const replica::database& db) const
}
os << ";";
return std::move(os).str();
});
return cql3::description {
.keyspace = name(),
.type = "keyspace",
.name = name(),
.create_statement = std::move(os).str()
.create_statement = std::move(maybe_create_statement)
};
}
std::ostream& keyspace_metadata::describe(replica::database& db, std::ostream& os, bool with_internals) const {
auto desc = describe(db);
auto desc = describe(db, cql3::with_create_statement::yes);
os << *desc.create_statement;
return os;
}

View File

@@ -101,7 +101,7 @@ public:
virtual sstring element_type() const override { return "keyspace"; }
virtual std::ostream& describe(replica::database& db, std::ostream& os, bool with_internals) const override;
cql3::description describe(const replica::database& db) const;
cql3::description describe(const replica::database& db, cql3::with_create_statement) const;
};
}

View File

@@ -977,7 +977,7 @@ sstring schema::get_create_statement(const replica::database& db, bool with_inte
return std::move(os).str();
}
cql3::description schema::describe(const replica::database& db, bool with_internals) const {
cql3::description schema::describe(const replica::database& db, cql3::describe_option desc_opt) const {
const sstring type = std::invoke([&] {
if (is_view()) {
return is_index(db, view_info()->base_id(), *this)
@@ -991,12 +991,14 @@ cql3::description schema::describe(const replica::database& db, bool with_intern
.keyspace = ks_name(),
.type = std::move(type),
.name = cf_name(),
.create_statement = get_create_statement(db, with_internals)
.create_statement = desc_opt == cql3::describe_option::NO_STMTS
? std::nullopt
: std::make_optional(get_create_statement(db, desc_opt == cql3::describe_option::STMTS_AND_INTERNALS))
};
}
std::ostream& schema::describe(replica::database& db, std::ostream& os, bool with_internals) const {
auto desc = describe(db, with_internals);
auto desc = describe(db, with_internals ? cql3::describe_option::STMTS_AND_INTERNALS : cql3::describe_option::STMTS);
os << *desc.create_statement;
return os;
}

View File

@@ -921,7 +921,7 @@ public:
*/
virtual std::ostream& describe(replica::database& db, std::ostream& os, bool with_internals) const override;
cql3::description describe(const replica::database& db, bool with_internals) const;
cql3::description describe(const replica::database& db, cql3::describe_option) const;
// Generate ALTER TABLE/MATERIALIZED VIEW statement containing all properties with current values.
// The method cannot be used on index, as indexes don't support alter statement.

View File

@@ -3235,7 +3235,12 @@ sstring user_type_impl::get_name_as_cql_string() const {
return cql3::util::maybe_quote(get_name_as_string());
}
cql3::description user_type_impl::describe() const {
cql3::description user_type_impl::describe(cql3::with_create_statement with_create_statement) const {
auto maybe_create_statement = std::invoke([&] -> std::optional<sstring> {
if (!with_create_statement) {
return std::nullopt;
}
std::ostringstream os;
os << "CREATE TYPE " << cql3::util::maybe_quote(_keyspace) << "." << get_name_as_cql_string() << " (\n";
@@ -3248,16 +3253,19 @@ cql3::description user_type_impl::describe() const {
}
os << ");";
return std::move(os).str();
});
return cql3::description {
.keyspace = _keyspace,
.type = "type",
.name = get_name_as_string(),
.create_statement = std::move(os).str()
.create_statement = std::move(maybe_create_statement)
};
}
std::ostream& user_type_impl::describe(std::ostream& os) const {
auto desc = describe();
auto desc = describe(cql3::with_create_statement::yes);
os << *desc.create_statement;
return os;
}

View File

@@ -65,7 +65,7 @@ public:
virtual sstring element_type() const override { return "type"; }
virtual std::ostream& describe(std::ostream& os) const override;
cql3::description describe() const;
cql3::description describe(cql3::with_create_statement) const;
private:
static sstring make_name(sstring keyspace,