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; }; }