Continue the work
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/b6fd31fe Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/b6fd31fe Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/b6fd31fe Branch: refs/heads/refactor-type Commit: b6fd31fec0cd9b1a89eee1fe89af70b85df44bc5 Parents: a7031a3 Author: Jianqiao Zhu <[email protected]> Authored: Mon Oct 2 15:36:22 2017 -0500 Committer: Jianqiao Zhu <[email protected]> Committed: Wed Oct 11 13:37:54 2017 -0500 ---------------------------------------------------------------------- expressions/table_generator/GenerateSeries.hpp | 10 +- parser/ParseLiteralValue.cpp | 12 +- .../expressions/BinaryExpression.cpp | 14 +- .../expressions/BinaryExpression.hpp | 22 +- query_optimizer/expressions/Scalar.hpp | 14 + query_optimizer/expressions/ScalarLiteral.cpp | 16 +- query_optimizer/expressions/ScalarLiteral.hpp | 18 +- query_optimizer/expressions/UnaryExpression.cpp | 14 +- query_optimizer/expressions/UnaryExpression.hpp | 20 +- query_optimizer/resolver/Resolver.cpp | 45 ++-- relational_operators/TextScanOperator.cpp | 2 +- storage/SMAIndexSubBlock.cpp | 2 +- types/ArrayType.hpp | 4 +- types/BoolType.cpp | 4 +- types/BoolType.hpp | 4 +- types/CharType.cpp | 8 +- types/CharType.hpp | 8 +- types/DateType.cpp | 4 +- types/DateType.hpp | 4 +- types/DatetimeIntervalType.cpp | 4 +- types/DatetimeIntervalType.hpp | 4 +- types/DatetimeType.cpp | 4 +- types/DatetimeType.hpp | 4 +- types/DoubleType.cpp | 4 +- types/DoubleType.hpp | 4 +- types/FloatType.cpp | 4 +- types/FloatType.hpp | 4 +- types/GenericValue.hpp | 51 +++- types/IntType.cpp | 4 +- types/IntType.hpp | 4 +- types/LongType.cpp | 4 +- types/LongType.hpp | 4 +- types/MetaType.hpp | 4 +- types/NullType.hpp | 4 +- types/NumericSuperType.hpp | 4 +- types/Type.cpp | 4 +- types/Type.hpp | 38 +-- types/TypeSynthesizer.hpp | 257 ++++++++++++------- types/VarCharType.cpp | 8 +- types/VarCharType.hpp | 8 +- types/YearMonthIntervalType.cpp | 4 +- types/YearMonthIntervalType.hpp | 4 +- types/operations/OperationFactory.cpp | 52 ++-- types/operations/OperationFactory.hpp | 20 +- .../operations/comparisons/BasicComparison.hpp | 4 +- .../unary_operations/CastOperation.hpp | 2 +- 46 files changed, 413 insertions(+), 324 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/expressions/table_generator/GenerateSeries.hpp ---------------------------------------------------------------------- diff --git a/expressions/table_generator/GenerateSeries.hpp b/expressions/table_generator/GenerateSeries.hpp index d749810..19523f5 100644 --- a/expressions/table_generator/GenerateSeries.hpp +++ b/expressions/table_generator/GenerateSeries.hpp @@ -118,11 +118,11 @@ class GenerateSeries : public GeneratorFunction { DCHECK(args.size() == 2 || args.size() == 3); // Coerce all arguments to the unified type. - TypedValue start = type.coerceValue(args[0], *arg_types[0]); - TypedValue end = type.coerceValue(args[1], *arg_types[1]); - TypedValue step = - args.size() > 2 ? type.coerceValue(args[2], *arg_types[2]) - : type.coerceValue(TypedValue(1), TypeFactory::GetType(TypeID::kInt)); + TypedValue start = type.coerceTypedValue(args[0], *arg_types[0]); + TypedValue end = type.coerceTypedValue(args[1], *arg_types[1]); + TypedValue step = args.size() > 2 + ? type.coerceTypedValue(args[2], *arg_types[2]) + : type.coerceTypedValue(TypedValue(1), TypeFactory::GetType(TypeID::kInt)); // Check that step is not 0, and (end - start) / step is positive const GreaterComparison >_comparator = GreaterComparison::Instance(); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/parser/ParseLiteralValue.cpp ---------------------------------------------------------------------- diff --git a/parser/ParseLiteralValue.cpp b/parser/ParseLiteralValue.cpp index 04e8a55..caa21e3 100644 --- a/parser/ParseLiteralValue.cpp +++ b/parser/ParseLiteralValue.cpp @@ -88,14 +88,14 @@ TypedValue NumericParseLiteralValue::concretize( TypedValue parsed_value; if ((type_hint != nullptr) && (type_hint->getSuperTypeID() == SuperTypeID::kNumeric) - && (type_hint->parseValueFromString(numeric_string_, &parsed_value))) { + && (type_hint->parseTypedValueFromString(numeric_string_, &parsed_value))) { *concretized_type = &(type_hint->getNonNullableVersion()); return parsed_value; } if (float_like_) { *concretized_type = &DoubleType::InstanceNonNullable(); - CHECK((*concretized_type)->parseValueFromString(numeric_string_, &parsed_value)) + CHECK((*concretized_type)->parseTypedValueFromString(numeric_string_, &parsed_value)) << "Failed to parse double from numeric string \"" << numeric_string_ << "\""; return parsed_value; @@ -153,7 +153,7 @@ TypedValue StringParseLiteralValue::concretize(const Type *type_hint, if (explicit_type_ != nullptr) { if ((type_hint != nullptr) && (type_hint->isSafelyCoercibleFrom(*explicit_type_))) { *concretized_type = type_hint; - return type_hint->coerceValue(explicit_parsed_value_, *explicit_type_); + return type_hint->coerceTypedValue(explicit_parsed_value_, *explicit_type_); } else { *concretized_type = explicit_type_; return explicit_parsed_value_; @@ -161,12 +161,12 @@ TypedValue StringParseLiteralValue::concretize(const Type *type_hint, } else { TypedValue parsed_value; if ((type_hint != nullptr) - && (type_hint->parseValueFromString(value_->value(), &parsed_value))) { + && (type_hint->parseTypedValueFromString(value_->value(), &parsed_value))) { *concretized_type = &(type_hint->getNonNullableVersion()); return parsed_value; } else { *concretized_type = &VarCharType::InstanceNonNullable(value_->value().length()); - CHECK((*concretized_type)->parseValueFromString(value_->value(), &parsed_value)); + CHECK((*concretized_type)->parseTypedValueFromString(value_->value(), &parsed_value)); return parsed_value; } } @@ -189,7 +189,7 @@ std::string StringParseLiteralValue::generateName() const { bool StringParseLiteralValue::tryExplicitTypeParse() { DCHECK(explicit_type_ != nullptr); - return explicit_type_->parseValueFromString(value_->value(), &explicit_parsed_value_); + return explicit_type_->parseTypedValueFromString(value_->value(), &explicit_parsed_value_); } void StringParseLiteralValue::getFieldStringItems( http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/query_optimizer/expressions/BinaryExpression.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/BinaryExpression.cpp b/query_optimizer/expressions/BinaryExpression.cpp index 24fee40..634c189 100644 --- a/query_optimizer/expressions/BinaryExpression.cpp +++ b/query_optimizer/expressions/BinaryExpression.cpp @@ -58,8 +58,7 @@ ExpressionPtr BinaryExpression::copyWithNewChildren( operation_, std::static_pointer_cast<const Scalar>(new_children[0]), std::static_pointer_cast<const Scalar>(new_children[1]), - static_arguments_, - static_argument_types_); + static_arguments_); } std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() const { @@ -80,7 +79,7 @@ std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() c operation_, left_->concretize(substitution_map), right_->concretize(substitution_map), - static_arguments_); + static_arguments_cache_); } std::size_t BinaryExpression::computeHash() const { @@ -94,10 +93,8 @@ std::size_t BinaryExpression::computeHash() const { hash_code = CombineHashes(hash_code, left_hash); hash_code = CombineHashes(hash_code, right_hash); - for (const TypedValue &st_arg : *static_arguments_) { - if (!st_arg.isNull()) { - hash_code = CombineHashes(hash_code, st_arg.getHash()); - } + for (const GenericValue &st_arg : *static_arguments_) { + hash_code = CombineHashes(hash_code, st_arg.getHash()); } return hash_code; } @@ -147,8 +144,7 @@ void BinaryExpression::getFieldStringItems( container_child_fields->emplace_back(); for (std::size_t i = 0; i < static_arguments_->size(); ++i) { container_child_fields->back().emplace_back( - ScalarLiteral::Create(static_arguments_->at(i), - *static_argument_types_->at(i))); + ScalarLiteral::Create(static_arguments_->at(i))); } } } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/query_optimizer/expressions/BinaryExpression.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/BinaryExpression.hpp b/query_optimizer/expressions/BinaryExpression.hpp index 6ee6690..5e59e48 100644 --- a/query_optimizer/expressions/BinaryExpression.hpp +++ b/query_optimizer/expressions/BinaryExpression.hpp @@ -31,6 +31,7 @@ #include "query_optimizer/expressions/Expression.hpp" #include "query_optimizer/expressions/ExpressionType.hpp" #include "query_optimizer/expressions/Scalar.hpp" +#include "types/GenericValue.hpp" #include "types/operations/OperationSignature.hpp" #include "types/operations/binary_operations/BinaryOperation.hpp" #include "utility/Macros.hpp" @@ -101,15 +102,13 @@ class BinaryExpression : public Scalar { const BinaryOperationPtr &operation, const ScalarPtr &left, const ScalarPtr &right, - const std::shared_ptr<const std::vector<TypedValue>> &static_arguments, - const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) { + const std::shared_ptr<const std::vector<GenericValue>> &static_arguments) { return BinaryExpressionPtr( new BinaryExpression(op_signature, operation, left, right, - static_arguments, - static_argument_types)); + static_arguments)); } static BinaryExpressionPtr Create( @@ -122,8 +121,7 @@ class BinaryExpression : public Scalar { operation, left, right, - std::make_shared<const std::vector<TypedValue>>(), - std::make_shared<const std::vector<const Type*>>())); + std::make_shared<const std::vector<GenericValue>>())); } protected: @@ -142,17 +140,16 @@ class BinaryExpression : public Scalar { const BinaryOperationPtr &operation, const ScalarPtr &left, const ScalarPtr &right, - const std::shared_ptr<const std::vector<TypedValue>> &static_arguments, - const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) + const std::shared_ptr<const std::vector<GenericValue>> &static_arguments) : op_signature_(op_signature), operation_(operation), left_(left), right_(right), static_arguments_(static_arguments), - static_argument_types_(static_argument_types), + static_arguments_cache_(ToTypedValue(*static_arguments_)), result_type_(*(operation_->getResultType(left_->getValueType(), right_->getValueType(), - *static_arguments))) { + *static_arguments_cache_))) { addChild(left); addChild(right); } @@ -161,8 +158,9 @@ class BinaryExpression : public Scalar { const BinaryOperationPtr operation_; const ScalarPtr left_; const ScalarPtr right_; - const std::shared_ptr<const std::vector<TypedValue>> static_arguments_; - const std::shared_ptr<const std::vector<const Type*>> static_argument_types_; + const std::shared_ptr<const std::vector<GenericValue>> static_arguments_; + // TODO(refactor-type): Remove this. + const std::shared_ptr<const std::vector<TypedValue>> static_arguments_cache_; const Type &result_type_; DISALLOW_COPY_AND_ASSIGN(BinaryExpression); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/query_optimizer/expressions/Scalar.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/Scalar.hpp b/query_optimizer/expressions/Scalar.hpp index a163b21..23df7c1 100644 --- a/query_optimizer/expressions/Scalar.hpp +++ b/query_optimizer/expressions/Scalar.hpp @@ -29,6 +29,10 @@ #include "utility/HashError.hpp" #include "utility/Macros.hpp" +// TODO(refactor-type): Remove this. +#include "types/TypedValue.hpp" +#include "types/GenericValue.hpp" + namespace quickstep { class CatalogAttribute; @@ -107,6 +111,16 @@ class Scalar : public Expression { throw HashNotSupported("Unsupported computeHash() in " + getName()); } + // TODO(refactor-type): Remove this. + inline static std::shared_ptr<const std::vector<TypedValue>> ToTypedValue( + const std::vector<GenericValue> &input) { + std::vector<TypedValue> values; + for (const auto &item : input) { + values.emplace_back(item.toTypedValue()); + } + return std::make_shared<const std::vector<TypedValue>>(std::move(values)); + } + private: mutable std::unique_ptr<std::size_t> hash_cache_; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/query_optimizer/expressions/ScalarLiteral.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/ScalarLiteral.cpp b/query_optimizer/expressions/ScalarLiteral.cpp index 278e2cc..4dd7ba3 100644 --- a/query_optimizer/expressions/ScalarLiteral.cpp +++ b/query_optimizer/expressions/ScalarLiteral.cpp @@ -40,18 +40,18 @@ namespace optimizer { namespace expressions { const Type& ScalarLiteral::getValueType() const { - return value_type_; + return value_.getType(); } ExpressionPtr ScalarLiteral::copyWithNewChildren( const std::vector<ExpressionPtr> &new_children) const { DCHECK_EQ(new_children.size(), children().size()); - return ScalarLiteral::Create(value_, value_type_); + return ScalarLiteral::Create(value_); } ::quickstep::Scalar *ScalarLiteral::concretize( const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const { - return new ::quickstep::ScalarLiteral(value_, value_type_); + return new ::quickstep::ScalarLiteral(value_.toTypedValue(), value_.getType()); } std::size_t ScalarLiteral::computeHash() const { @@ -64,12 +64,8 @@ std::size_t ScalarLiteral::computeHash() const { bool ScalarLiteral::equals(const ScalarPtr &other) const { ScalarLiteralPtr lit; - if (SomeScalarLiteral::MatchesWithConditionalCast(other, &lit) && - value_type_.equals(lit->value_type_)) { - if (value_.isNull() || lit->value_.isNull()) { - return value_.isNull() && lit->value_.isNull(); - } - return value_.fastEqualCheck(lit->value_); + if (SomeScalarLiteral::MatchesWithConditionalCast(other, &lit)) { + return value_.equals(lit->value_); } return false; } @@ -85,7 +81,7 @@ void ScalarLiteral::getFieldStringItems( if (value_.isNull()) { inline_field_values->push_back("NULL"); } else { - inline_field_values->push_back(value_type_.printTypedValueToString(value_)); + inline_field_values->push_back(value_.toString()); } inline_field_names->push_back("type"); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/query_optimizer/expressions/ScalarLiteral.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/ScalarLiteral.hpp b/query_optimizer/expressions/ScalarLiteral.hpp index bff52bb..180ae39 100644 --- a/query_optimizer/expressions/ScalarLiteral.hpp +++ b/query_optimizer/expressions/ScalarLiteral.hpp @@ -32,7 +32,7 @@ #include "query_optimizer/expressions/Expression.hpp" #include "query_optimizer/expressions/ExpressionType.hpp" #include "query_optimizer/expressions/Scalar.hpp" -#include "types/TypedValue.hpp" +#include "types/GenericValue.hpp" #include "utility/Macros.hpp" namespace quickstep { @@ -70,7 +70,7 @@ class ScalarLiteral : public Scalar { /** * @return The literal value. */ - const TypedValue& value() const { return value_; } + const GenericValue& value() const { return value_; } ExpressionPtr copyWithNewChildren( const std::vector<ExpressionPtr> &new_children) const override; @@ -89,9 +89,8 @@ class ScalarLiteral : public Scalar { * @param literal_value The literal value. * @return An immutable ScalarLiteral with the given literal value. */ - static const ScalarLiteralPtr Create(const TypedValue &literal_value, - const Type &literal_value_type) { - return ScalarLiteralPtr(new ScalarLiteral(literal_value, literal_value_type)); + static const ScalarLiteralPtr Create(const GenericValue &literal_value) { + return ScalarLiteralPtr(new ScalarLiteral(literal_value)); } protected: @@ -106,13 +105,10 @@ class ScalarLiteral : public Scalar { std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override; private: - ScalarLiteral(const TypedValue &literal_value, - const Type &literal_value_type) - : value_(literal_value), - value_type_(literal_value_type) {} + ScalarLiteral(const GenericValue &literal_value) + : value_(literal_value) {} - const TypedValue value_; - const Type &value_type_; + const GenericValue &value_; DISALLOW_COPY_AND_ASSIGN(ScalarLiteral); }; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/query_optimizer/expressions/UnaryExpression.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/UnaryExpression.cpp b/query_optimizer/expressions/UnaryExpression.cpp index e1ad014..38cb65c 100644 --- a/query_optimizer/expressions/UnaryExpression.cpp +++ b/query_optimizer/expressions/UnaryExpression.cpp @@ -52,8 +52,7 @@ ExpressionPtr UnaryExpression::copyWithNewChildren( op_signature_, operation_, std::static_pointer_cast<const Scalar>(new_children[0]), - static_arguments_, - static_argument_types_); + static_arguments_); } ::quickstep::Scalar* UnaryExpression::concretize( @@ -62,16 +61,14 @@ ExpressionPtr UnaryExpression::copyWithNewChildren( op_signature_, operation_, operand_->concretize(substitution_map), - static_arguments_); + static_arguments_cache_); } std::size_t UnaryExpression::computeHash() const { std::size_t hash_code = CombineHashes(op_signature_->hash(), operand_->hash()); - for (const TypedValue &st_arg : *static_arguments_) { - if (!st_arg.isNull()) { - hash_code = CombineHashes(hash_code, st_arg.getHash()); - } + for (const GenericValue &st_arg : *static_arguments_) { + hash_code = CombineHashes(hash_code, st_arg.getHash()); } return hash_code; } @@ -107,8 +104,7 @@ void UnaryExpression::getFieldStringItems( container_child_fields->emplace_back(); for (std::size_t i = 0; i < static_arguments_->size(); ++i) { container_child_fields->back().emplace_back( - ScalarLiteral::Create(static_arguments_->at(i), - *static_argument_types_->at(i))); + ScalarLiteral::Create(static_arguments_->at(i))); } } } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/query_optimizer/expressions/UnaryExpression.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/UnaryExpression.hpp b/query_optimizer/expressions/UnaryExpression.hpp index bbb1841..9c3bf17 100644 --- a/query_optimizer/expressions/UnaryExpression.hpp +++ b/query_optimizer/expressions/UnaryExpression.hpp @@ -31,6 +31,7 @@ #include "query_optimizer/expressions/Expression.hpp" #include "query_optimizer/expressions/ExpressionType.hpp" #include "query_optimizer/expressions/Scalar.hpp" +#include "types/GenericValue.hpp" #include "types/operations/OperationSignature.hpp" #include "types/operations/unary_operations/UnaryOperation.hpp" #include "utility/Macros.hpp" @@ -101,14 +102,12 @@ class UnaryExpression : public Scalar { const OperationSignaturePtr &op_signature, const UnaryOperationPtr &operation, const ScalarPtr &operand, - const std::shared_ptr<const std::vector<TypedValue>> &static_arguments, - const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) { + const std::shared_ptr<const std::vector<GenericValue>> &static_arguments) { return UnaryExpressionPtr( new UnaryExpression(op_signature, operation, operand, - static_arguments, - static_argument_types)); + static_arguments)); } protected: @@ -126,22 +125,23 @@ class UnaryExpression : public Scalar { UnaryExpression(const OperationSignaturePtr &op_signature, const UnaryOperationPtr &operation, const ScalarPtr &operand, - const std::shared_ptr<const std::vector<TypedValue>> &static_arguments, - const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) + const std::shared_ptr<const std::vector<GenericValue>> &static_arguments) : op_signature_(op_signature), operation_(operation), operand_(operand), static_arguments_(static_arguments), - static_argument_types_(static_argument_types), - result_type_(*(operation_->getResultType(operand_->getValueType(), *static_arguments_))) { + static_arguments_cache_(ToTypedValue(*static_arguments_)), + result_type_(*(operation_->getResultType(operand_->getValueType(), + *static_arguments_cache_))) { addChild(operand); } const OperationSignaturePtr op_signature_; const UnaryOperationPtr operation_; const ScalarPtr operand_; - const std::shared_ptr<const std::vector<TypedValue>> static_arguments_; - const std::shared_ptr<const std::vector<const Type*>> static_argument_types_; + const std::shared_ptr<const std::vector<GenericValue>> static_arguments_; + // TODO(refactor-type): Remove this. + const std::shared_ptr<const std::vector<TypedValue>> static_arguments_cache_; const Type &result_type_; DISALLOW_COPY_AND_ASSIGN(UnaryExpression); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/query_optimizer/resolver/Resolver.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp index 230f7c5..2cd24bd 100644 --- a/query_optimizer/resolver/Resolver.cpp +++ b/query_optimizer/resolver/Resolver.cpp @@ -115,6 +115,7 @@ #include "query_optimizer/resolver/NameResolver.hpp" #include "storage/StorageBlockLayout.pb.h" #include "storage/StorageConstants.hpp" +#include "types/GenericValue.hpp" #include "types/IntType.hpp" #include "types/Type.hpp" #include "types/TypeFactory.hpp" @@ -1073,6 +1074,7 @@ L::LogicalPtr Resolver::resolveInsertTuple( std::vector<E::ScalarLiteralPtr> resolved_column_values; std::vector<E::AttributeReferencePtr>::size_type aid = 0; for (const ParseScalarLiteral &parse_literal_value : parse_column_values) { + const Type &attribute_type = relation_attributes[aid]->getValueType(); E::ScalarLiteralPtr resolved_literal_value; ExpressionResolutionInfo expr_resolution_info( name_resolver, @@ -1081,30 +1083,25 @@ L::LogicalPtr Resolver::resolveInsertTuple( // When resolving the literal, use the attribute's Type as a hint. CHECK(E::SomeScalarLiteral::MatchesWithConditionalCast( resolveExpression(parse_literal_value, - &(relation_attributes[aid]->getValueType()), + &attribute_type, &expr_resolution_info), &resolved_literal_value)); // Check that the resolved Type is safely coercible to the attribute's // Type. - if (!relation_attributes[aid]->getValueType().isSafelyCoercibleFrom( - resolved_literal_value->getValueType())) { + if (!attribute_type.isSafelyCoercibleFrom(resolved_literal_value->getValueType())) { THROW_SQL_ERROR_AT(&parse_literal_value) << "The assigned value for the column " << relation_attributes[aid]->attribute_name() << " has the type " << resolved_literal_value->getValueType().getName() << ", which cannot be safely coerced to the column's type " - << relation_attributes[aid]->getValueType().getName(); + << attribute_type.getName(); } // If the Type is not exactly right (but is safely coercible), coerce it. - if (!resolved_literal_value->getValueType().equals( - relation_attributes[aid]->getValueType())) { + if (!resolved_literal_value->getValueType().equals(attribute_type)) { resolved_literal_value = E::ScalarLiteral::Create( - relation_attributes[aid]->getValueType().coerceValue( - resolved_literal_value->value(), - resolved_literal_value->getValueType()), - relation_attributes[aid]->getValueType()); + resolved_literal_value->value().coerce(attribute_type)); } resolved_column_values.push_back(resolved_literal_value); @@ -1119,8 +1116,7 @@ L::LogicalPtr Resolver::resolveInsertTuple( } // Create a NULL value. resolved_column_values.push_back(E::ScalarLiteral::Create( - relation_attributes[aid]->getValueType().makeNullValue(), - relation_attributes[aid]->getValueType())); + GenericValue(relation_attributes[aid]->getValueType()))); ++aid; } @@ -2455,7 +2451,7 @@ E::ScalarPtr Resolver::resolveExpression( const Type *concrete_type = nullptr; TypedValue concrete = parse_literal_scalar.literal_value() ->concretize(type_hint, &concrete_type); - return E::ScalarLiteral::Create(std::move(concrete), *concrete_type); + return E::ScalarLiteral::Create(GenericValue(*concrete_type, concrete)); } case ParseExpression::kSearchedCaseExpression: { const ParseSearchedCaseExpression &parse_searched_case_expression = @@ -2510,7 +2506,6 @@ E::ScalarPtr Resolver::resolveArray( // // // Currently we only support homogeneous array with literal values. // } - LOG(FATAL) << "Not supported"; } @@ -2788,22 +2783,22 @@ E::ScalarPtr Resolver::resolveScalarFunction( argument_types.emplace_back(&argument->getValueType()); } - std::vector<TypedValue> static_arguments; + std::vector<GenericValue> static_arguments; for (std::size_t i = first_static_argument_position; i < arity; ++i) { static_arguments.emplace_back( std::static_pointer_cast<const E::ScalarLiteral>( resolved_arguments[i])->value()); - DCHECK(static_arguments.back().getTypeID() == argument_types[i]->getTypeID()); + DCHECK(static_arguments.back().getType().getTypeID() == argument_types[i]->getTypeID()); } std::shared_ptr<const std::vector<const Type*>> coerced_argument_types; - std::shared_ptr<const std::vector<TypedValue>> coerced_static_arguments; + std::shared_ptr<const std::vector<GenericValue>> coerced_static_arguments; std::string message; const OperationSignaturePtr op_signature = OperationFactory::Instance().resolveOperation( function_name, std::make_shared<const std::vector<const Type*>>(std::move(argument_types)), - std::make_shared<const std::vector<TypedValue>>(std::move(static_arguments)), + std::make_shared<const std::vector<GenericValue>>(std::move(static_arguments)), &coerced_argument_types, &coerced_static_arguments, &message); @@ -2818,11 +2813,7 @@ E::ScalarPtr Resolver::resolveScalarFunction( } // TODO: add cast if neccessary. - - const auto coerced_static_argument_types = - std::make_shared<const std::vector<const Type*>>( - coerced_argument_types->begin() + op_signature->getNonStaticArity(), - coerced_argument_types->end()); + (void)coerced_argument_types; const OperationPtr operation = OperationFactory::Instance().getOperation(op_signature); @@ -2832,16 +2823,14 @@ E::ScalarPtr Resolver::resolveScalarFunction( op_signature, std::static_pointer_cast<const UnaryOperation>(operation), resolved_arguments[0], - coerced_static_arguments, - coerced_static_argument_types); + coerced_static_arguments); case Operation::kBinaryOperation: return E::BinaryExpression::Create( op_signature, std::static_pointer_cast<const BinaryOperation>(operation), resolved_arguments[0], resolved_arguments[1], - coerced_static_arguments, - coerced_static_argument_types); + coerced_static_arguments); default: { const auto operation_id = static_cast<std::underlying_type_t<Operation::OperationSuperTypeID>>( @@ -3340,7 +3329,7 @@ void Resolver::rewriteIfOrdinalReference( if (E::SomeScalarLiteral::MatchesWithConditionalCast(*expression, &literal) && literal->getValueType().getTypeID() == kInt && !literal->value().isNull()) { - int position = literal->value().getLiteral<int>(); + int position = literal->value().getLiteral<kInt>(); if (position < 1 || position > static_cast<int>( select_list_info->select_list_expressions.size())) { http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/relational_operators/TextScanOperator.cpp ---------------------------------------------------------------------- diff --git a/relational_operators/TextScanOperator.cpp b/relational_operators/TextScanOperator.cpp index 66137d8..3885888 100644 --- a/relational_operators/TextScanOperator.cpp +++ b/relational_operators/TextScanOperator.cpp @@ -474,7 +474,7 @@ std::vector<TypedValue> TextScanWorkOrder::parseRow(const char **row_ptr, attribute_values.emplace_back(attr.getType().makeNullValue()); } else { attribute_values.emplace_back(); - if (!attr.getType().parseValueFromString(value_str, &(attribute_values.back()))) { + if (!attr.getType().parseTypedValueFromString(value_str, &(attribute_values.back()))) { // Do not abort if one of the row is faulty. *is_faulty = true; LOG(INFO) << "Failed to parse value."; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/storage/SMAIndexSubBlock.cpp ---------------------------------------------------------------------- diff --git a/storage/SMAIndexSubBlock.cpp b/storage/SMAIndexSubBlock.cpp index 96a744e..5a8a747 100644 --- a/storage/SMAIndexSubBlock.cpp +++ b/storage/SMAIndexSubBlock.cpp @@ -640,7 +640,7 @@ Selectivity SMAIndexSubBlock::getSelectivityForPredicate(const ComparisonPredica SMAPredicate *replacement = new SMAPredicate( sma_predicate->attribute, sma_predicate->comparison, - attribute_type.coerceValue(sma_predicate->literal, literal_type)); + attribute_type.coerceTypedValue(sma_predicate->literal, literal_type)); sma_predicate.reset(replacement); } else { // The literal type cannot be converted, so do not evaluate with the SMA. http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/ArrayType.hpp ---------------------------------------------------------------------- diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp index 1c66ed2..fe81c3e 100644 --- a/types/ArrayType.hpp +++ b/types/ArrayType.hpp @@ -46,8 +46,8 @@ class ArrayType : public TypeSynthesizer<kArray> { std::string printValueToString(const UntypedLiteral *value) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override { + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override { return false; } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/BoolType.cpp ---------------------------------------------------------------------- diff --git a/types/BoolType.cpp b/types/BoolType.cpp index 9680770..7687f06 100644 --- a/types/BoolType.cpp +++ b/types/BoolType.cpp @@ -47,8 +47,8 @@ void BoolType::printValueToFile(const UntypedLiteral *value, castValueToLiteral(value) ? "true" : "false"); } -bool BoolType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool BoolType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { const std::string lo_value = ToLower(value_string); if (lo_value == "true") { *value = TypedValue(true); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/BoolType.hpp ---------------------------------------------------------------------- diff --git a/types/BoolType.hpp b/types/BoolType.hpp index 2ba380a..ed819ae 100644 --- a/types/BoolType.hpp +++ b/types/BoolType.hpp @@ -54,8 +54,8 @@ class BoolType : public NumericSuperType<kBool> { FILE *file, const int padding = 0) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: explicit BoolType(const bool nullable) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/CharType.cpp ---------------------------------------------------------------------- diff --git a/types/CharType.cpp b/types/CharType.cpp index ea3d00e..eb3f64a 100644 --- a/types/CharType.cpp +++ b/types/CharType.cpp @@ -87,8 +87,8 @@ void CharType::printValueToFile(const UntypedLiteral *value, castValueToLiteral(value).getOutOfLineData()); } -bool CharType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool CharType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { if (value_string.length() > length_) { return false; } @@ -102,8 +102,8 @@ bool CharType::parseValueFromString(const std::string &value_string, return true; } -TypedValue CharType::coerceValue(const TypedValue &original_value, - const Type &original_type) const { +TypedValue CharType::coerceTypedValue(const TypedValue &original_value, + const Type &original_type) const { DCHECK(isCoercibleFrom(original_type)) << "Can't coerce value of Type " << original_type.getName() << " to Type " << getName(); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/CharType.hpp ---------------------------------------------------------------------- diff --git a/types/CharType.hpp b/types/CharType.hpp index 32b0c7a..81a32ff 100644 --- a/types/CharType.hpp +++ b/types/CharType.hpp @@ -59,11 +59,11 @@ class CharType : public AsciiStringSuperType<kChar> { FILE *file, const int padding = 0) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; - TypedValue coerceValue(const TypedValue &original_value, - const Type &original_type) const override; + TypedValue coerceTypedValue(const TypedValue &original_value, + const Type &original_type) const override; private: CharType(const bool nullable, const std::size_t length) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/DateType.cpp ---------------------------------------------------------------------- diff --git a/types/DateType.cpp b/types/DateType.cpp index dcd779d..a88b5bd 100644 --- a/types/DateType.cpp +++ b/types/DateType.cpp @@ -75,8 +75,8 @@ std::string DateType::printValueToString(const UntypedLiteral *value) const { return std::string(datebuf); } -bool DateType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool DateType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { std::int32_t year; std::uint32_t month, day; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/DateType.hpp ---------------------------------------------------------------------- diff --git a/types/DateType.hpp b/types/DateType.hpp index b7d1820..1c9eaf9 100644 --- a/types/DateType.hpp +++ b/types/DateType.hpp @@ -61,8 +61,8 @@ class DateType : public TypeSynthesizer<kDate> { * fail if there are any "extra" characters at the end of the string * after a parsable ISO-8601 date. **/ - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: explicit DateType(const bool nullable) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/DatetimeIntervalType.cpp ---------------------------------------------------------------------- diff --git a/types/DatetimeIntervalType.cpp b/types/DatetimeIntervalType.cpp index e419ce3..a4b2896 100644 --- a/types/DatetimeIntervalType.cpp +++ b/types/DatetimeIntervalType.cpp @@ -110,8 +110,8 @@ std::string DatetimeIntervalType::printValueToString(const UntypedLiteral *value return std::string(interval_buf); } -bool DatetimeIntervalType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool DatetimeIntervalType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { // Try simple-format parse first. std::int64_t count; std::string units; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/DatetimeIntervalType.hpp ---------------------------------------------------------------------- diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp index bf36609..cb2534d 100644 --- a/types/DatetimeIntervalType.hpp +++ b/types/DatetimeIntervalType.hpp @@ -53,8 +53,8 @@ class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> { return TypedValue(DatetimeIntervalLit{0}); } - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: explicit DatetimeIntervalType(const bool nullable) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/DatetimeType.cpp ---------------------------------------------------------------------- diff --git a/types/DatetimeType.cpp b/types/DatetimeType.cpp index 11ffae9..6d5fc2d 100644 --- a/types/DatetimeType.cpp +++ b/types/DatetimeType.cpp @@ -103,8 +103,8 @@ std::string DatetimeType::printValueToString(const UntypedLiteral *value) const return std::string(datebuf); } -bool DatetimeType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool DatetimeType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { int year; int month; int day; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/DatetimeType.hpp ---------------------------------------------------------------------- diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp index 924ff35..d0ac1e2 100644 --- a/types/DatetimeType.hpp +++ b/types/DatetimeType.hpp @@ -70,8 +70,8 @@ class DatetimeType * fail if there are any "extra" characters at the end of the string * after a parsable ISO-8601 date/time. **/ - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: explicit DatetimeType(const bool nullable) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/DoubleType.cpp ---------------------------------------------------------------------- diff --git a/types/DoubleType.cpp b/types/DoubleType.cpp index fb50957..8219955 100644 --- a/types/DoubleType.cpp +++ b/types/DoubleType.cpp @@ -66,8 +66,8 @@ void DoubleType::printValueToFile(const UntypedLiteral *value, castValueToLiteral(value)); } -bool DoubleType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool DoubleType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { double parsed_double; int read_chars; int matched = std::sscanf(value_string.c_str(), http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/DoubleType.hpp ---------------------------------------------------------------------- diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp index ddba4e3..6959817 100644 --- a/types/DoubleType.hpp +++ b/types/DoubleType.hpp @@ -52,8 +52,8 @@ class DoubleType : public NumericSuperType<kDouble> { FILE *file, const int padding = 0) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: static_assert((std::numeric_limits<double>::max_exponent10 < 1000) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/FloatType.cpp ---------------------------------------------------------------------- diff --git a/types/FloatType.cpp b/types/FloatType.cpp index ca741a6..5fcefc9 100644 --- a/types/FloatType.cpp +++ b/types/FloatType.cpp @@ -66,8 +66,8 @@ void FloatType::printValueToFile(const UntypedLiteral *value, castValueToLiteral(value)); } -bool FloatType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool FloatType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { float parsed_float; int read_chars; int matched = std::sscanf(value_string.c_str(), http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/FloatType.hpp ---------------------------------------------------------------------- diff --git a/types/FloatType.hpp b/types/FloatType.hpp index 68a636b..3a7aa41 100644 --- a/types/FloatType.hpp +++ b/types/FloatType.hpp @@ -52,8 +52,8 @@ class FloatType : public NumericSuperType<kFloat> { FILE *file, const int padding = 0) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: static_assert((std::numeric_limits<float>::max_exponent10 < 100) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/GenericValue.hpp ---------------------------------------------------------------------- diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp index 61529d6..1fcdcd6 100644 --- a/types/GenericValue.hpp +++ b/types/GenericValue.hpp @@ -26,8 +26,10 @@ #include <string> #include "types/Type.hpp" +#include "types/Type.pb.h" #include "types/TypeID.hpp" #include "types/TypeRegistrar.hpp" +#include "types/TypedValue.hpp" #include "utility/HashPair.hpp" #include "utility/Macros.hpp" @@ -41,16 +43,23 @@ namespace quickstep { class GenericValue { public: + GenericValue(const Type &type) + : type_(type), value_(nullptr), owns_(true) {} + GenericValue(const Type &type, const UntypedLiteral *value, const bool owns) : type_(type), value_(value), owns_(owns) {} + GenericValue(const Type &type, const TypedValue &value) + : type_(type), value_(type.unmarshallTypedValue(value)), owns_(true) {} + template <typename TypeClass> GenericValue(const TypeClass &type, const typename TypeClass::cpptype &value) : type_(type), value_(type.cloneValue(&value)), owns_(true) {} GenericValue(const GenericValue &other) : type_(other.type_), - value_(other.owns_ ? type_.cloneValue(other.value_) : other.value_), + value_((other.owns_ && !other.isNull()) ? type_.cloneValue(other.value_) + : other.value_), owns_(other.owns_) {} GenericValue(GenericValue &&other) @@ -61,11 +70,15 @@ class GenericValue { } ~GenericValue() { - if (owns_ && value_ != nullptr) { + if (owns_ && !isNull()) { type_.destroyValue(const_cast<void*>(value_)); } } + serialization::GenericValue getProto() const { + LOG(FATAL) << "Not implemented"; + } + inline bool isNull() const { DCHECK(value_ != nullptr || type_.isNullable()); return value_ == nullptr; @@ -86,23 +99,47 @@ class GenericValue { template <TypeID type_id> inline const typename TypeIDTrait<type_id>::cpptype& getLiteral() const { DCHECK_EQ(type_id, type_.getTypeID()); - return *static_cast<typename TypeIDTrait<type_id>::cpptype*>(value_); + return *static_cast<const typename TypeIDTrait<type_id>::cpptype*>(value_); } inline void ensureNotReference() { if (isReference()) { - value_ = type_.cloneValue(value_); + if (!isNull()) { + value_ = type_.cloneValue(value_); + } owns_ = true; } } + inline GenericValue makeReferenceToThis() const { + return GenericValue(type_, value_, false); + } + + inline bool equals(const GenericValue &other) const { + if (isNull() || other.isNull()) { + return isNull() && other.isNull(); + } + return type_.checkValuesEqual(value_, other.value_, other.type_); + } + inline bool operator==(const GenericValue &other) const { - return type_.equals(other.type_) && - type_.checkValuesEqual(value_, other.value_); + return equals(other); } inline std::size_t getHash() const { - return CombineHashes(type_.getHash(), type_.hashValue(value_)); + return isNull() ? 0 : type_.hashValue(value_); + } + + inline GenericValue coerce(const Type &other_type) const { + LOG(FATAL) << "Not implemented"; + } + + inline TypedValue toTypedValue() const { + return isNull() ? type_.makeNullValue() : type_.marshallValue(value_); + } + + inline std::string toString() const { + return isNull() ? "NULL" : type_.printValueToString(value_); } private: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/IntType.cpp ---------------------------------------------------------------------- diff --git a/types/IntType.cpp b/types/IntType.cpp index 8e3aff1..07db133 100644 --- a/types/IntType.cpp +++ b/types/IntType.cpp @@ -46,8 +46,8 @@ void IntType::printValueToFile(const UntypedLiteral *value, castValueToLiteral(value)); } -bool IntType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool IntType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { int parsed_int; int read_chars; int matched = std::sscanf(value_string.c_str(), http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/IntType.hpp ---------------------------------------------------------------------- diff --git a/types/IntType.hpp b/types/IntType.hpp index d83c257..eb5e5aa 100644 --- a/types/IntType.hpp +++ b/types/IntType.hpp @@ -54,8 +54,8 @@ class IntType : public NumericSuperType<kInt> { FILE *file, const int padding = 0) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: explicit IntType(const bool nullable) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/LongType.cpp ---------------------------------------------------------------------- diff --git a/types/LongType.cpp b/types/LongType.cpp index 82dce39..ffb9eb7 100644 --- a/types/LongType.cpp +++ b/types/LongType.cpp @@ -52,8 +52,8 @@ void LongType::printValueToFile(const UntypedLiteral *value, castValueToLiteral(value)); } -bool LongType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool LongType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { std::int64_t parsed_long; int read_chars; int matched = std::sscanf(value_string.c_str(), http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/LongType.hpp ---------------------------------------------------------------------- diff --git a/types/LongType.hpp b/types/LongType.hpp index 7561975..dc75310 100644 --- a/types/LongType.hpp +++ b/types/LongType.hpp @@ -55,8 +55,8 @@ class LongType : public NumericSuperType<kLong> { FILE *file, const int padding = 0) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: explicit LongType(const bool nullable) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/MetaType.hpp ---------------------------------------------------------------------- diff --git a/types/MetaType.hpp b/types/MetaType.hpp index 0c3952b..c046771 100644 --- a/types/MetaType.hpp +++ b/types/MetaType.hpp @@ -46,8 +46,8 @@ class MetaType : public TypeSynthesizer<kMetaType> { std::string printValueToString(const UntypedLiteral *value) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override { + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override { return false; } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/NullType.hpp ---------------------------------------------------------------------- diff --git a/types/NullType.hpp b/types/NullType.hpp index 8dd237e..1aa8a1c 100644 --- a/types/NullType.hpp +++ b/types/NullType.hpp @@ -79,8 +79,8 @@ class NullType : public TypeSynthesizer<kNullType> { LOG(FATAL) << "NullType is not printable"; } - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override { + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override { return false; } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/NumericSuperType.hpp ---------------------------------------------------------------------- diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp index 6576cbf..f474d52 100644 --- a/types/NumericSuperType.hpp +++ b/types/NumericSuperType.hpp @@ -62,8 +62,8 @@ class NumericSuperType : public TypeSynthesizer<type_id> { return TypedValue(static_cast<typename TypeIDTrait<type_id>::cpptype>(0)); } - TypedValue coerceValue(const TypedValue &original_value, - const Type &original_type) const override { + TypedValue coerceTypedValue(const TypedValue &original_value, + const Type &original_type) const override { if (original_type.getSuperTypeID() != SuperTypeID::kNumeric) { LOG(FATAL) << "Attempted to coerce Type " << original_type.getName() << " (not recognized as a numeric Type) to " << Type::getName(); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/Type.cpp ---------------------------------------------------------------------- diff --git a/types/Type.cpp b/types/Type.cpp index 34678c7..b0b781a 100644 --- a/types/Type.cpp +++ b/types/Type.cpp @@ -59,8 +59,8 @@ void Type::printValueToFile(const UntypedLiteral *value, std::fprintf(file, "%*s", padding, printValueToString(value).c_str()); } -TypedValue Type::coerceValue(const TypedValue &original_value, - const Type &original_type) const { +TypedValue Type::coerceTypedValue(const TypedValue &original_value, + const Type &original_type) const { DCHECK(isCoercibleFrom(original_type)) << "Can't coerce value of Type " << original_type.getName() << " to Type " << getName(); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/Type.hpp ---------------------------------------------------------------------- diff --git a/types/Type.hpp b/types/Type.hpp index 47f00e6..d4ed993 100644 --- a/types/Type.hpp +++ b/types/Type.hpp @@ -293,13 +293,13 @@ class Type { virtual std::string printValueToString(const UntypedLiteral *value) const = 0; + virtual std::string printTypedValueToString(const TypedValue &value) const = 0; + virtual void printValueToFile(const UntypedLiteral *value, FILE *file, const int padding = 0) const; - virtual std::string printTypedValueToString(const TypedValue &value) const = 0; - virtual void printTypedValueToFile(const TypedValue &value, FILE *file, const int padding = 0) const = 0; @@ -379,8 +379,8 @@ class Type { * @return true if value_string was successfully parsed and value was * written. false if value_string was not in the correct format. **/ - virtual bool parseValueFromString(const std::string &value_string, - TypedValue *value) const = 0; + virtual bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const = 0; /** * @brief Coerce a value of another Type to this Type. @@ -398,32 +398,32 @@ class Type { * @return A new TypedValue that represents original_value as an instance of * this Type. **/ - virtual TypedValue coerceValue(const TypedValue &original_value, - const Type &original_type) const; + virtual TypedValue coerceTypedValue(const TypedValue &original_value, + const Type &original_type) const; - virtual std::size_t getHash() const { - LOG(FATAL) << "Not implemented"; - } + virtual std::size_t getHash() const = 0; virtual bool checkValuesEqual(const UntypedLiteral *lhs, - const UntypedLiteral *rhs) const { + const UntypedLiteral *rhs, + const Type &rhs_type) const { LOG(FATAL) << "Not implemented"; } - virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const { - LOG(FATAL) << "Not implemented"; + inline bool checkValuesEqual(const UntypedLiteral *lhs, + const UntypedLiteral *rhs) const { + return checkValuesEqual(lhs, rhs, *this); } - virtual std::size_t hashValue(const UntypedLiteral *value) const { - LOG(FATAL) << "Not implemented"; - } + virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const = 0; + + virtual void destroyValue(UntypedLiteral *value) const = 0; - virtual void destroyValue(UntypedLiteral *value_ptr) const { + virtual std::size_t hashValue(const UntypedLiteral *value) const { LOG(FATAL) << "Not implemented"; } - virtual CharStream marshallValue(const UntypedLiteral *value) const { + virtual TypedValue marshallValue(const UntypedLiteral *value) const { LOG(FATAL) << "Not implemented"; } @@ -433,9 +433,9 @@ class Type { } - virtual UntypedLiteral* unmarshallValue(const TypedValue &value) const = 0; + virtual UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const = 0; - virtual UntypedLiteral* unmarshallValue(TypedValue &&value) const = 0; + virtual UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const = 0; protected: Type(const SuperTypeID super_type_id, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/TypeSynthesizer.hpp ---------------------------------------------------------------------- diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp index 7c39e47..08ab67a 100644 --- a/types/TypeSynthesizer.hpp +++ b/types/TypeSynthesizer.hpp @@ -22,6 +22,8 @@ #include <cstddef> #include <cstdio> +#include <cstdlib> +#include <cstring> #include <memory> #include <string> #include <type_traits> @@ -46,16 +48,16 @@ namespace quickstep { */ template <TypeID type_id, typename Enable = void> -class TypeInstancePolicy; +class TypeSynthesizePolicy; template <TypeID type_id> class TypeSynthesizer : public Type, - public TypeInstancePolicy<type_id> { + public TypeSynthesizePolicy<type_id> { private: using Trait = TypeIDTrait<type_id>; - using InstancePolicy = TypeInstancePolicy<type_id>; + using SynthesizePolicy = TypeSynthesizePolicy<type_id>; public: static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID; @@ -71,38 +73,41 @@ class TypeSynthesizer proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_)); proto.set_nullable(nullable_); - - InstancePolicy::fillProto(&proto); + SynthesizePolicy::mergeIntoProto(&proto); return proto; } const Type& getNullableVersion() const override { - return InstancePolicy::getInstance(true); + return SynthesizePolicy::getInstance(true); } const Type& getNonNullableVersion() const override { - return InstancePolicy::getInstance(false); + return SynthesizePolicy::getInstance(false); } - const cpptype& castValueToLiteral(const UntypedLiteral *value) const { - return *static_cast<const cpptype*>(value); + std::size_t getHash() const override { + return SynthesizePolicy::getHash(); } - cpptype& castValueToLiteral(UntypedLiteral *value) const { - return *static_cast<cpptype*>(value); + UntypedLiteral* cloneValue(const UntypedLiteral *value) const override { + return SynthesizePolicy::cloneValue(value); } - UntypedLiteral* unmarshallValue(const TypedValue &value) const override { - return unmarshallInternal<kMemoryLayout>(value); + void destroyValue(UntypedLiteral *value) const override { + return SynthesizePolicy::destroyValue(value); } - UntypedLiteral* unmarshallValue(TypedValue &&value) const override { - return unmarshallInternal<kMemoryLayout>(std::move(value)); + UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override { + return SynthesizePolicy::unmarshallTypedValue(value); + } + + UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const override { + return SynthesizePolicy::unmarshallTypedValue(std::move(value)); } std::string printTypedValueToString(const TypedValue &value) const override { - return invokeOnUnmarshalledValue<kMemoryLayout>( + return SynthesizePolicy::invokeOnUnmarshalledTypedValue( value, [&](const UntypedLiteral *value) -> std::string { return this->printValueToString(value); @@ -112,20 +117,28 @@ class TypeSynthesizer void printTypedValueToFile(const TypedValue &value, FILE *file, const int padding = 0) const override { - invokeOnUnmarshalledValue<kMemoryLayout>( + SynthesizePolicy::invokeOnUnmarshalledTypedValue( value, [&](const UntypedLiteral *value) -> void { this->printValueToFile(value, file, padding); }); } + const cpptype& castValueToLiteral(const UntypedLiteral *value) const { + return *static_cast<const cpptype*>(value); + } + + cpptype& castValueToLiteral(UntypedLiteral *value) const { + return *static_cast<cpptype*>(value); + } + protected: template <MemoryLayout layout = kMemoryLayout> explicit TypeSynthesizer(const bool nullable, std::enable_if_t<layout == kCxxInlinePod>* = 0) : Type(kStaticSuperTypeID, kStaticTypeID, nullable, sizeof(cpptype), sizeof(cpptype)), - TypeInstancePolicy<type_id>() { + TypeSynthesizePolicy<type_id>(this) { } template <MemoryLayout layout = kMemoryLayout> @@ -133,10 +146,11 @@ class TypeSynthesizer const std::size_t minimum_byte_length, const std::size_t maximum_byte_length, const std::size_t parameter, - std::enable_if_t<layout == kParInlinePod || layout == kParOutOfLinePod>* = 0) + std::enable_if_t<layout == kParInlinePod || + layout == kParOutOfLinePod>* = 0) : Type(kStaticSuperTypeID, kStaticTypeID, nullable, minimum_byte_length, maximum_byte_length), - TypeInstancePolicy<type_id>(parameter) { + TypeSynthesizePolicy<type_id>(this, parameter) { } template <MemoryLayout layout = kMemoryLayout> @@ -147,70 +161,11 @@ class TypeSynthesizer std::enable_if_t<layout == kCxxGeneric>* = 0) : Type(kStaticSuperTypeID, kStaticTypeID, nullable, minimum_byte_length, maximum_byte_length), - TypeInstancePolicy<type_id>(parameters) { + TypeSynthesizePolicy<type_id>(this, parameters) { } private: - template <MemoryLayout layout> - inline UntypedLiteral* unmarshallInternal( - const TypedValue &value, - std::enable_if_t<layout == kCxxInlinePod> * = 0) const { - return cloneValue(value.getDataPtr()); - } - - template <MemoryLayout layout> - inline UntypedLiteral* unmarshallInternal( - const TypedValue &value, - std::enable_if_t<layout == kParInlinePod || - layout == kParOutOfLinePod> * = 0) const { - return cloneValue(&value); - } - - template <MemoryLayout layout> - inline UntypedLiteral* unmarshallInternal( - TypedValue &&value, - std::enable_if_t<layout == kParInlinePod || - layout == kParOutOfLinePod> * = 0) const { - return new TypedValue(std::move(value)); - } - - template <MemoryLayout layout> - inline UntypedLiteral* unmarshallInternal( - const TypedValue &value, - std::enable_if_t<layout == kCxxGeneric> * = 0) const { - return Type::unmarshallValue(value.getOutOfLineData(), value.getDataSize()); - } - - - template <MemoryLayout layout, typename Functor> - inline auto invokeOnUnmarshalledValue( - const TypedValue &value, - const Functor &functor, - std::enable_if_t<layout == kCxxInlinePod> * = 0) const { - return functor(value.getDataPtr()); - } - - template <MemoryLayout layout, typename Functor> - inline auto invokeOnUnmarshalledValue( - const TypedValue &value, - const Functor &functor, - std::enable_if_t<layout == kParInlinePod || - layout == kParOutOfLinePod> * = 0) const { - return functor(&value); - } - - template <MemoryLayout layout, typename Functor> - inline auto invokeOnUnmarshalledValue( - const TypedValue &value, - const Functor &functor, - std::enable_if_t<layout == kCxxGeneric> * = 0) const { - std::unique_ptr<cpptype> literal( - static_cast<cpptype*>(Type::unmarshallValue(value.getOutOfLineData(), - value.getDataSize()))); - return functor(literal.get()); - } - - template <TypeID, typename> friend class TypeInstancePolicy; + template <TypeID, typename> friend class TypeSynthesizePolicy; DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer); }; @@ -229,12 +184,13 @@ constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout; template <TypeID type_id> -class TypeInstancePolicy< +class TypeSynthesizePolicy< type_id, std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> { private: using Trait = TypeIDTrait<type_id>; using TypeClass = typename Trait::TypeClass; + using cpptype = typename Trait::cpptype; public: static const TypeClass& InstanceNonNullable() { @@ -254,13 +210,40 @@ class TypeInstancePolicy< } protected: - TypeInstancePolicy() {} + explicit TypeSynthesizePolicy(const Type *base) + : base_(*base) {} inline const Type& getInstance(const bool nullable) const { return nullable ? InstanceNullable() : InstanceNonNullable(); } - inline void fillProto(serialization::Type *proto) const {} + inline void mergeIntoProto(serialization::Type *proto) const {} + + inline std::size_t getHash() const { + return static_cast<std::size_t>(base_.getTypeID()); + } + + inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const { + DCHECK(value != nullptr); + UntypedLiteral* clone = std::malloc(sizeof(cpptype)); + std::memcpy(clone, value, sizeof(cpptype)); + return clone; + } + + inline void destroyValue(UntypedLiteral *value) const { + DCHECK(value != nullptr); + std::free(value); + } + + inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const { + return base_.cloneValue(value.getDataPtr()); + } + + template <typename Functor> + inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value, + const Functor &functor) const { + return functor(value.getDataPtr()); + } private: template <bool nullable> @@ -268,16 +251,22 @@ class TypeInstancePolicy< static TypeClass instance(nullable); return instance; } + + const Type &base_; }; template <TypeID type_id> -class TypeInstancePolicy< +class TypeSynthesizePolicy< type_id, std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod || TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> { private: using Trait = TypeIDTrait<type_id>; using TypeClass = typename Trait::TypeClass; + using cpptype = typename Trait::cpptype; + + static_assert(std::is_same<cpptype, TypedValue>::value, + "Unexpected cpptype for paramerized PODs."); public: static const TypeClass& InstanceNonNullable(const std::size_t length) { @@ -301,8 +290,9 @@ class TypeInstancePolicy< } protected: - TypeInstancePolicy(const std::size_t length) - : length_(length) {} + TypeSynthesizePolicy(const Type *base, const std::size_t length) + : length_(length), + base_(*base) {} const std::size_t length_; @@ -310,10 +300,38 @@ class TypeInstancePolicy< return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_); } - inline void fillProto(serialization::Type *proto) const { + inline void mergeIntoProto(serialization::Type *proto) const { proto->set_length(length_); } + inline std::size_t getHash() const { + return CombineHashes(static_cast<std::size_t>(base_.getTypeID()), length_); + } + + inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const { + DCHECK(value != nullptr); + return new TypedValue(*static_cast<const TypedValue*>(value)); + } + + inline void destroyValue(UntypedLiteral *value) const { + DCHECK(value != nullptr); + delete static_cast<TypedValue*>(value); + } + + inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const { + return base_.cloneValue(&value); + } + + inline UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const { + return new TypedValue(std::move(value)); + } + + template <typename Functor> + inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value, + const Functor &functor) const { + return functor(&value); + } + private: template <bool nullable> inline static const TypeClass& InstanceInternal(const std::size_t length) { @@ -325,15 +343,18 @@ class TypeInstancePolicy< } return *(imit->second); } + + const Type &base_; }; template <TypeID type_id> -class TypeInstancePolicy< +class TypeSynthesizePolicy< type_id, std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> { private: using Trait = TypeIDTrait<type_id>; using TypeClass = typename Trait::TypeClass; + using cpptype = typename Trait::cpptype; public: static const TypeClass& InstanceNonNullable( @@ -361,29 +382,67 @@ class TypeInstancePolicy< } protected: - TypeInstancePolicy(const std::vector<GenericValue> ¶meters) - : parameters_(parameters) {} - - const std::vector<GenericValue> parameters_; + TypeSynthesizePolicy(const Type *base, + const std::vector<GenericValue> ¶meters) + : parameters_(parameters), + base_(*base) {} inline const Type& getInstance(const bool nullable) const { return nullable ? InstanceNullable(parameters_) : InstanceNonNullable(parameters_); } - inline void fillProto(serialization::Type *proto) const { - LOG(FATAL) << "TODO"; + inline void mergeIntoProto(serialization::Type *proto) const { + for (const auto ¶m : parameters_) { + proto->add_parameters()->MergeFrom(param.getProto()); + } + } + + inline std::size_t getHash() const { + return CombineHashes(static_cast<std::size_t>(base_.getTypeID()), + ParametersHasher::ComputeHash(parameters_)); + } + + inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const { + DCHECK(value != nullptr); + return new cpptype(*static_cast<const cpptype*>(value)); + } + + inline void destroyValue(UntypedLiteral *value) const { + DCHECK(value != nullptr); + delete static_cast<cpptype*>(value); } + inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const { + return base_.unmarshallValue(value.getOutOfLineData(), value.getDataSize()); + } + + template <typename Functor> + inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value, + const Functor &functor) const { + std::unique_ptr<typename Trait::cpptype> literal( + static_cast<typename Trait::cpptype*>( + base_.unmarshallValue(value.getOutOfLineData(), + value.getDataSize()))); + return functor(literal.get()); + } + + const std::vector<GenericValue> parameters_; + private: struct ParametersHasher { - inline std::size_t operator()(const std::vector<GenericValue> ¶meters) const { + inline static std::size_t ComputeHash( + const std::vector<GenericValue> ¶meters) { std::size_t hash_code = 0; for (const GenericValue &value : parameters) { hash_code = CombineHashes(hash_code, value.getHash()); } return hash_code; } + inline std::size_t operator()( + const std::vector<GenericValue> ¶meters) const { + return ComputeHash(parameters); + } }; template <typename T> @@ -412,16 +471,18 @@ class TypeInstancePolicy< auto imit = instance_map.find(parameters); if (imit == instance_map.end()) { std::unique_ptr<TypeClass> instance( - TypeInstancePolicy<type_id>::template CreateInstance<TypeClass>( + TypeSynthesizePolicy<type_id>::template CreateInstance<TypeClass>( nullable, parameters)); imit = instance_map.emplace(parameters, std::move(instance)).first; } return *(imit->second); } + + const Type &base_; }; #define QUICKSTEP_SYNTHESIZE_TYPE(type) \ - template <TypeID, typename> friend class TypeInstancePolicy; \ + template <TypeID, typename> friend class TypeSynthesizePolicy; \ DISALLOW_COPY_AND_ASSIGN(type) /** @} */ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/VarCharType.cpp ---------------------------------------------------------------------- diff --git a/types/VarCharType.cpp b/types/VarCharType.cpp index f0f677d..6f5f9fb 100644 --- a/types/VarCharType.cpp +++ b/types/VarCharType.cpp @@ -103,8 +103,8 @@ void VarCharType::printValueToFile(const UntypedLiteral *value, static_cast<const char*>(castValueToLiteral(value).getOutOfLineData())); } -bool VarCharType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool VarCharType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { if (value_string.length() > length_) { return false; } @@ -114,8 +114,8 @@ bool VarCharType::parseValueFromString(const std::string &value_string, return true; } -TypedValue VarCharType::coerceValue(const TypedValue &original_value, - const Type &original_type) const { +TypedValue VarCharType::coerceTypedValue(const TypedValue &original_value, + const Type &original_type) const { DCHECK(isCoercibleFrom(original_type)) << "Can't coerce value of Type " << original_type.getName() << " to Type " << getName(); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/VarCharType.hpp ---------------------------------------------------------------------- diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp index 47a2874..0b16061 100644 --- a/types/VarCharType.hpp +++ b/types/VarCharType.hpp @@ -66,11 +66,11 @@ class VarCharType : public AsciiStringSuperType<kVarChar> { FILE *file, const int padding = 0) const override; - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; - TypedValue coerceValue(const TypedValue &original_value, - const Type &original_type) const override; + TypedValue coerceTypedValue(const TypedValue &original_value, + const Type &original_type) const override; private: VarCharType(const bool nullable, const std::size_t length) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/YearMonthIntervalType.cpp ---------------------------------------------------------------------- diff --git a/types/YearMonthIntervalType.cpp b/types/YearMonthIntervalType.cpp index b395dff..f266bf1 100644 --- a/types/YearMonthIntervalType.cpp +++ b/types/YearMonthIntervalType.cpp @@ -116,8 +116,8 @@ std::string YearMonthIntervalType::printValueToString(const UntypedLiteral *valu return std::string(interval_buf); } -bool YearMonthIntervalType::parseValueFromString(const std::string &value_string, - TypedValue *value) const { +bool YearMonthIntervalType::parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const { // Try simple-format parse first. std::int64_t count; std::string units; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/YearMonthIntervalType.hpp ---------------------------------------------------------------------- diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp index ab06911..ee1eb97 100644 --- a/types/YearMonthIntervalType.hpp +++ b/types/YearMonthIntervalType.hpp @@ -52,8 +52,8 @@ class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> { return TypedValue(YearMonthIntervalLit{0}); } - bool parseValueFromString(const std::string &value_string, - TypedValue *value) const override; + bool parseTypedValueFromString(const std::string &value_string, + TypedValue *value) const override; private: explicit YearMonthIntervalType(const bool nullable) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/b6fd31fe/types/operations/OperationFactory.cpp ---------------------------------------------------------------------- diff --git a/types/operations/OperationFactory.cpp b/types/operations/OperationFactory.cpp index 531318b..253a75d 100644 --- a/types/operations/OperationFactory.cpp +++ b/types/operations/OperationFactory.cpp @@ -24,11 +24,11 @@ #include <string> #include <vector> +#include "types/GenericValue.hpp" #include "types/Type.hpp" #include "types/TypeFactory.hpp" #include "types/TypeID.hpp" #include "types/TypeUtil.hpp" -#include "types/TypedValue.hpp" #include "types/operations/Operation.hpp" #include "types/operations/OperationSignature.hpp" #include "types/operations/binary_operations/ArithmeticBinaryOperations.hpp" @@ -68,6 +68,16 @@ struct FunctorPackDispatcher { } }; +// TODO(refactor-type): Remove this. +inline static std::shared_ptr<const std::vector<TypedValue>> ToTypedValue( + const std::vector<GenericValue> &input) { + std::vector<TypedValue> values; + for (const auto &item : input) { + values.emplace_back(item.toTypedValue()); + } + return std::make_shared<const std::vector<TypedValue>>(std::move(values)); +} + } // namespace OperationFactory::OperationFactory() { @@ -87,9 +97,9 @@ OperationFactory::OperationFactory() { OperationSignaturePtr OperationFactory::resolveOperation( const std::string &operation_name, const std::shared_ptr<const std::vector<const Type*>> &argument_types, - const std::shared_ptr<const std::vector<TypedValue>> &static_arguments, + const std::shared_ptr<const std::vector<GenericValue>> &static_arguments, std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types, - std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments, + std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments, std::string *message) const { const std::string lower_case_name = ToLower(operation_name); const std::size_t arity = argument_types->size(); @@ -151,8 +161,8 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMa const PartialSignatureIndex &secondary_index, const std::vector<TypeID> &argument_type_ids, const std::vector<const Type*> &argument_types, - const std::vector<TypedValue> &static_arguments, - std::shared_ptr<const std::vector<TypedValue>> *partial_static_arguments, + const std::vector<GenericValue> &static_arguments, + std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments, OperationSignaturePtr *resolved_op_signature, std::string *message) const { const std::size_t max_num_static_arguments = static_arguments.size(); @@ -163,15 +173,15 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMa const OperationSignaturePtr op_signature = it->second; const OperationPtr operation = getOperation(op_signature); - *partial_static_arguments = - std::make_shared<const std::vector<TypedValue>>( + *coerced_static_arguments = + std::make_shared<const std::vector<GenericValue>>( static_arguments.begin() + (max_num_static_arguments - op_signature->getNumStaticArguments()), static_arguments.end()); if (canApplyOperationTo(operation, argument_types, - **partial_static_arguments, + **coerced_static_arguments, message)) { *resolved_op_signature = op_signature; return ResolveStatus::kSuccess; @@ -187,9 +197,9 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp const PartialSignatureIndex &secondary_index, const std::vector<TypeID> &argument_type_ids, const std::vector<const Type*> &argument_types, - const std::vector<TypedValue> &static_arguments, + const std::vector<GenericValue> &static_arguments, std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types, - std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments, + std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments, OperationSignaturePtr *resolved_op_signature, std::string *message) const { const std::size_t arity = argument_types.size(); @@ -211,18 +221,16 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp } // Coerce static arguments - std::vector<const Type*> coerced_static_arg_types; - std::vector<TypedValue> coerced_static_args; + std::vector<GenericValue> coerced_static_args; bool is_coercible = true; for (std::size_t i = num_non_static_arguments; i < arity; ++i) { const Type &arg_type = *argument_types.at(i); - const TypedValue &arg_value = + const GenericValue &arg_value = static_arguments.at(i - first_static_argument_position); const TypeID &expected_type_id = expected_type_ids.at(i); if (arg_type.getTypeID() == expected_type_id) { - coerced_static_arg_types.emplace_back(&arg_type); coerced_static_args.emplace_back(arg_value); } else { const Type *expected_type = nullptr; @@ -240,9 +248,7 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp } if (expected_type != nullptr && expected_type->isSafelyCoercibleFrom(arg_type)) { - coerced_static_arg_types.emplace_back(expected_type); - coerced_static_args.emplace_back( - expected_type->coerceValue(arg_value, arg_type)); + coerced_static_args.emplace_back(arg_value.coerce(*expected_type)); } else { is_coercible = false; break; @@ -254,8 +260,8 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp std::vector<const Type*> coerced_arg_types( argument_types.begin(), argument_types.begin() + num_non_static_arguments); - for (const Type *type : coerced_static_arg_types) { - coerced_arg_types.emplace_back(type); + for (const auto &value : coerced_static_args) { + coerced_arg_types.emplace_back(&value.getType()); } const OperationPtr operation = getOperation(it->second); @@ -266,7 +272,7 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp *coerced_argument_types = std::make_shared<const std::vector<const Type*>>(std::move(coerced_arg_types)); *coerced_static_arguments = - std::make_shared<const std::vector<TypedValue>>(std::move(coerced_static_args)); + std::make_shared<const std::vector<GenericValue>>(std::move(coerced_static_args)); *resolved_op_signature = it->second; return ResolveStatus::kSuccess; } @@ -281,14 +287,14 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp bool OperationFactory::canApplyOperationTo( const OperationPtr operation, const std::vector<const Type*> &argument_types, - const std::vector<TypedValue> &static_arguments, + const std::vector<GenericValue> &static_arguments, std::string *message) const { switch (operation->getOperationSuperTypeID()) { case Operation::kUnaryOperation: { const UnaryOperationPtr unary_operation = std::static_pointer_cast<const UnaryOperation>(operation); return unary_operation->canApplyTo(*argument_types[0], - static_arguments, + *ToTypedValue(static_arguments), message); } case Operation::kBinaryOperation: { @@ -296,7 +302,7 @@ bool OperationFactory::canApplyOperationTo( std::static_pointer_cast<const BinaryOperation>(operation); return binary_operation->canApplyTo(*argument_types[0], *argument_types[1], - static_arguments, + *ToTypedValue(static_arguments), message); } default: {
