From 6f8b6aef17df84b85c14dec31f08061eb6da02e9 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 4 Aug 2021 11:08:25 +0300 Subject: [PATCH] cql3: type_cast: deinline some methods These methods will be converted to the expression variant, and it's impossible to do this while inlined due to #include cycles. In any case, deinlining is better. Since there is no type_cast.cc, and since they'll become part of expr_term call chain soon, they're moved there, even though it seems odd for this patch. It's a waste to create type_cast.cc just for those three functions. --- cql3/expr/term_expr.cc | 44 ++++++++++++++++++++++++++++++++++++++++++ cql3/type_cast.hh | 36 ++++------------------------------ 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/cql3/expr/term_expr.cc b/cql3/expr/term_expr.cc index e800d9c496..d6f9b93b07 100644 --- a/cql3/expr/term_expr.cc +++ b/cql3/expr/term_expr.cc @@ -21,6 +21,50 @@ #include "term_expr.hh" #include "cql3/functions/function_call.hh" +#include "cql3/type_cast.hh" + +namespace cql3 { + +sstring +type_cast::to_string() const { + return format("({}){}", _type, _term); +} + +lw_shared_ptr +type_cast::casted_spec_of(database& db, const sstring& keyspace, const column_specification& receiver) const { + return make_lw_shared(receiver.ks_name, receiver.cf_name, + ::make_shared(to_string(), true), _type->prepare(db, keyspace).get_type()); +} + +assignment_testable::test_result +type_cast::test_assignment(database& db, const sstring& keyspace, const column_specification& receiver) const { + try { + auto&& casted_type = _type->prepare(db, keyspace).get_type(); + if (receiver.type == casted_type) { + return assignment_testable::test_result::EXACT_MATCH; + } else if (receiver.type->is_value_compatible_with(*casted_type)) { + return assignment_testable::test_result::WEAKLY_ASSIGNABLE; + } else { + return assignment_testable::test_result::NOT_ASSIGNABLE; + } + } catch (exceptions::invalid_request_exception& e) { + abort(); + } +} + +shared_ptr +type_cast::prepare(database& db, const sstring& keyspace, const column_specification_or_tuple& receiver_) const { + auto& receiver = std::get>(receiver_); + if (!is_assignable(_term->test_assignment(db, keyspace, *casted_spec_of(db, keyspace, *receiver)))) { + throw exceptions::invalid_request_exception(format("Cannot cast value {} to type {}", _term, _type)); + } + if (!is_assignable(test_assignment(db, keyspace, *receiver))) { + throw exceptions::invalid_request_exception(format("Cannot assign value {} to {} of type {}", *this, receiver->name, receiver->type->as_cql3_type())); + } + return _term->prepare(db, keyspace, receiver); +} + +} // A term::raw that is implemented using an expression namespace cql3::expr { diff --git a/cql3/type_cast.hh b/cql3/type_cast.hh index 86fb00f9e6..693890f00c 100644 --- a/cql3/type_cast.hh +++ b/cql3/type_cast.hh @@ -52,41 +52,13 @@ public: type_cast(shared_ptr type, shared_ptr term) : _type(std::move(type)), _term(std::move(term)) { } - - virtual shared_ptr prepare(database& db, const sstring& keyspace, const column_specification_or_tuple& receiver_) const override { - auto& receiver = std::get>(receiver_); - if (!is_assignable(_term->test_assignment(db, keyspace, *casted_spec_of(db, keyspace, *receiver)))) { - throw exceptions::invalid_request_exception(format("Cannot cast value {} to type {}", _term, _type)); - } - if (!is_assignable(test_assignment(db, keyspace, *receiver))) { - throw exceptions::invalid_request_exception(format("Cannot assign value {} to {} of type {}", *this, receiver->name, receiver->type->as_cql3_type())); - } - return _term->prepare(db, keyspace, receiver); - } + virtual shared_ptr prepare(database& db, const sstring& keyspace, const column_specification_or_tuple& receiver_) const override; private: - lw_shared_ptr casted_spec_of(database& db, const sstring& keyspace, const column_specification& receiver) const { - return make_lw_shared(receiver.ks_name, receiver.cf_name, - ::make_shared(to_string(), true), _type->prepare(db, keyspace).get_type()); - } + lw_shared_ptr casted_spec_of(database& db, const sstring& keyspace, const column_specification& receiver) const; public: - virtual assignment_testable::test_result test_assignment(database& db, const sstring& keyspace, const column_specification& receiver) const override { - try { - auto&& casted_type = _type->prepare(db, keyspace).get_type(); - if (receiver.type == casted_type) { - return assignment_testable::test_result::EXACT_MATCH; - } else if (receiver.type->is_value_compatible_with(*casted_type)) { - return assignment_testable::test_result::WEAKLY_ASSIGNABLE; - } else { - return assignment_testable::test_result::NOT_ASSIGNABLE; - } - } catch (exceptions::invalid_request_exception& e) { - abort(); - } - } + virtual assignment_testable::test_result test_assignment(database& db, const sstring& keyspace, const column_specification& receiver) const override; - virtual sstring to_string() const override { - return format("({}){}", _type, _term); - } + virtual sstring to_string() const override; }; }