mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-19 16:15:07 +00:00
cql3: Move strict_is_not_null_in_views to cql_config
Move strict_is_not_null_in_views option from db::config to cql_config via new view_restrictions sub-struct. This improves separation of concerns by keeping view-specific validation policies with other CQL configuration. Update prepare_view() to take view_restrictions reference instead of reaching into db::config, and update all callsites to pass the sub-struct. Signed-off-by: Pavel Emelyanov <xemul@scylladb.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "restrictions/restrictions_config.hh"
|
||||
#include "cql3/restrictions/replication_restrictions.hh"
|
||||
#include "cql3/restrictions/twcs_restrictions.hh"
|
||||
#include "cql3/restrictions/view_restrictions.hh"
|
||||
#include "db/tri_mode_restriction.hh"
|
||||
#include "utils/updateable_value.hh"
|
||||
|
||||
@@ -24,6 +25,7 @@ struct cql_config {
|
||||
restrictions::restrictions_config restrictions;
|
||||
replication_restrictions replication_restrictions;
|
||||
twcs_restrictions twcs_restrictions;
|
||||
view_restrictions view_restrictions;
|
||||
utils::updateable_value<uint32_t> select_internal_page_size;
|
||||
utils::updateable_value<db::tri_mode_restriction> strict_allow_filtering;
|
||||
utils::updateable_value<bool> enable_parallelized_aggregation;
|
||||
@@ -35,6 +37,7 @@ struct cql_config {
|
||||
: restrictions(cfg)
|
||||
, replication_restrictions(cfg)
|
||||
, twcs_restrictions(cfg)
|
||||
, view_restrictions(cfg)
|
||||
, select_internal_page_size(cfg.select_internal_page_size)
|
||||
, strict_allow_filtering(cfg.strict_allow_filtering)
|
||||
, enable_parallelized_aggregation(cfg.enable_parallelized_aggregation)
|
||||
@@ -47,6 +50,7 @@ struct cql_config {
|
||||
: restrictions(restrictions::restrictions_config::default_tag{})
|
||||
, replication_restrictions(replication_restrictions::default_tag{})
|
||||
, twcs_restrictions(twcs_restrictions::default_tag{})
|
||||
, view_restrictions(view_restrictions::default_tag{})
|
||||
, select_internal_page_size(10000)
|
||||
, strict_allow_filtering(db::tri_mode_restriction(db::tri_mode_restriction_t::mode::WARN))
|
||||
, enable_parallelized_aggregation(true)
|
||||
|
||||
32
cql3/restrictions/view_restrictions.hh
Normal file
32
cql3/restrictions/view_restrictions.hh
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2019-present ScyllaDB
|
||||
*/
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.1
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "db/config.hh"
|
||||
#include "db/tri_mode_restriction.hh"
|
||||
#include "utils/updateable_value.hh"
|
||||
|
||||
namespace db { class config; }
|
||||
|
||||
namespace cql3 {
|
||||
|
||||
struct view_restrictions {
|
||||
utils::updateable_value<db::tri_mode_restriction> strict_is_not_null_in_views;
|
||||
|
||||
explicit view_restrictions(const db::config& cfg)
|
||||
: strict_is_not_null_in_views(cfg.strict_is_not_null_in_views)
|
||||
{}
|
||||
|
||||
struct default_tag{};
|
||||
view_restrictions(default_tag)
|
||||
: strict_is_not_null_in_views(db::tri_mode_restriction(db::tri_mode_restriction_t::mode::WARN))
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "db/view/view.hh"
|
||||
#include "service/migration_manager.hh"
|
||||
#include "replica/database.hh"
|
||||
#include "db/config.hh"
|
||||
#include "cql3/cql_config.hh"
|
||||
|
||||
namespace cql3 {
|
||||
@@ -107,7 +106,7 @@ static bool validate_primary_key(
|
||||
return new_non_pk_column;
|
||||
}
|
||||
|
||||
std::pair<view_ptr, cql3::cql_warnings_vec> create_view_statement::prepare_view(data_dictionary::database db, locator::token_metadata_ptr tmptr) const {
|
||||
std::pair<view_ptr, cql3::cql_warnings_vec> create_view_statement::prepare_view(data_dictionary::database db, locator::token_metadata_ptr tmptr, const view_restrictions& vr) const {
|
||||
// We need to make sure that:
|
||||
// - materialized view name is valid
|
||||
// - primary key includes all columns in base table's primary key
|
||||
@@ -325,7 +324,7 @@ std::pair<view_ptr, cql3::cql_warnings_vec> create_view_statement::prepare_view(
|
||||
}
|
||||
|
||||
if (!invalid_not_null_column_names.empty() &&
|
||||
db.get_config().strict_is_not_null_in_views() == db::tri_mode_restriction_t::mode::TRUE) {
|
||||
vr.strict_is_not_null_in_views() == db::tri_mode_restriction_t::mode::TRUE) {
|
||||
throw exceptions::invalid_request_exception(
|
||||
fmt::format("The IS NOT NULL restriction is allowed only columns which are part of the view's primary key,"
|
||||
" found columns: {}. The flag strict_is_not_null_in_views can be used to turn this error "
|
||||
@@ -334,7 +333,7 @@ std::pair<view_ptr, cql3::cql_warnings_vec> create_view_statement::prepare_view(
|
||||
}
|
||||
|
||||
if (!invalid_not_null_column_names.empty() &&
|
||||
db.get_config().strict_is_not_null_in_views() == db::tri_mode_restriction_t::mode::WARN) {
|
||||
vr.strict_is_not_null_in_views() == db::tri_mode_restriction_t::mode::WARN) {
|
||||
sstring warning_text = fmt::format(
|
||||
"The IS NOT NULL restriction is allowed only columns which are part of the view's primary key,"
|
||||
" found columns: {}. Restrictions on these columns will be silently ignored. "
|
||||
@@ -402,7 +401,7 @@ std::pair<view_ptr, cql3::cql_warnings_vec> create_view_statement::prepare_view(
|
||||
future<std::tuple<::shared_ptr<cql_transport::event::schema_change>, utils::chunked_vector<mutation>, cql3::cql_warnings_vec>>
|
||||
create_view_statement::prepare_schema_mutations(query_processor& qp, const query_options&, api::timestamp_type ts) const {
|
||||
utils::chunked_vector<mutation> m;
|
||||
auto [definition, warnings] = prepare_view(qp.db(), qp.proxy().get_token_metadata_ptr());
|
||||
auto [definition, warnings] = prepare_view(qp.db(), qp.proxy().get_token_metadata_ptr(), qp.get_cql_config().view_restrictions);
|
||||
try {
|
||||
m = co_await service::prepare_new_view_announcement(qp.proxy(), std::move(definition), ts);
|
||||
} catch (const exceptions::already_exists_exception& e) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
namespace cql3 {
|
||||
|
||||
class query_processor;
|
||||
struct view_restrictions;
|
||||
class relation;
|
||||
|
||||
namespace selection {
|
||||
@@ -48,7 +49,7 @@ public:
|
||||
std::vector<::shared_ptr<cql3::column_identifier::raw>> clustering_keys,
|
||||
bool if_not_exists);
|
||||
|
||||
std::pair<view_ptr, cql3::cql_warnings_vec> prepare_view(data_dictionary::database db, locator::token_metadata_ptr tmptr) const;
|
||||
std::pair<view_ptr, cql3::cql_warnings_vec> prepare_view(data_dictionary::database db, locator::token_metadata_ptr tmptr, const view_restrictions& vr) const;
|
||||
|
||||
auto& properties() {
|
||||
return _properties;
|
||||
|
||||
@@ -321,7 +321,7 @@ std::vector<schema_ptr> do_load_schemas(const db::config& cfg, std::string_view
|
||||
}
|
||||
real_db.tables.emplace_back(dd_impl, dd_impl.unwrap(ks), std::move(schema), true);
|
||||
} else if (auto p = dynamic_cast<cql3::statements::create_view_statement*>(statement)) {
|
||||
auto&& [view, warnings] = p->prepare_view(db, token_metadata.local().get());
|
||||
auto&& [view, warnings] = p->prepare_view(db, token_metadata.local().get(), cql3::default_cql_config.view_restrictions);
|
||||
auto it = std::find_if(real_db.tables.begin(), real_db.tables.end(), [&] (const table& t) { return t.schema->ks_name() == view->ks_name() && t.schema->cf_name() == view->cf_name(); });
|
||||
if (it != real_db.tables.end()) {
|
||||
continue; // view already exists
|
||||
|
||||
Reference in New Issue
Block a user