Updates to casts
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/477c385d Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/477c385d Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/477c385d Branch: refs/heads/refactor-type Commit: 477c385d427483d4c2708449927f14268e53c311 Parents: 1cb97e3 Author: Jianqiao Zhu <[email protected]> Authored: Tue Oct 10 13:20:17 2017 -0500 Committer: Jianqiao Zhu <[email protected]> Committed: Wed Oct 11 13:37:54 2017 -0500 ---------------------------------------------------------------------- expressions/ExpressionFactories.cpp | 4 +- .../aggregation/AggregateFunctionAvg.cpp | 13 +- .../aggregation/AggregateFunctionSum.cpp | 4 +- .../aggregation/AggregationHandleAvg.cpp | 16 +- .../aggregation/AggregationHandleSum.cpp | 8 +- expressions/scalar/ScalarCaseExpression.cpp | 8 +- .../WindowAggregateFunctionAvg.cpp | 3 +- .../WindowAggregateFunctionSum.cpp | 2 +- .../WindowAggregationHandle.cpp | 4 +- .../WindowAggregationHandleAvg.cpp | 4 +- query_optimizer/expressions/CMakeLists.txt | 11 +- query_optimizer/expressions/Cast.cpp | 2 +- query_optimizer/resolver/Resolver.cpp | 80 ++- query_optimizer/rules/Partition.cpp | 2 +- .../rules/ReuseAggregateExpressions.cpp | 2 +- storage/SMAIndexSubBlock.cpp | 7 +- storage/WindowAggregationOperationState.cpp | 4 +- types/ArrayLit.hpp | 112 ++++ types/ArrayType.cpp | 30 +- types/ArrayType.hpp | 10 +- types/AsciiStringSuperType.hpp | 8 - types/BoolType.hpp | 2 +- types/CMakeLists.txt | 7 +- types/CharType.hpp | 2 +- types/DateType.hpp | 2 +- types/DatetimeIntervalType.hpp | 2 +- types/DatetimeType.hpp | 3 +- types/DoubleType.hpp | 2 +- types/FloatType.hpp | 2 +- types/IntType.hpp | 2 +- types/LongType.hpp | 2 +- types/MetaType-decl.hpp | 2 +- types/MetaType.cpp | 2 +- types/NullType.hpp | 2 +- types/NumericSuperType.hpp | 5 - types/TextType.hpp | 2 +- types/Type.cpp | 22 +- types/Type.hpp | 9 +- types/Type.proto | 4 +- types/TypeRegistrar.hpp | 16 +- types/TypeSynthesizer.hpp | 34 +- types/VarCharType.hpp | 2 +- types/YearMonthIntervalType.hpp | 2 +- types/containers/CMakeLists.txt | 1 + types/containers/ColumnVector.cpp | 43 +- types/containers/ColumnVector.hpp | 124 +++- types/containers/ColumnVectorUtil.hpp | 6 +- types/containers/ColumnVectorsValueAccessor.hpp | 41 +- types/operations/CMakeLists.txt | 5 +- types/operations/OperationFactory.cpp | 160 ++++- types/operations/OperationFactory.hpp | 138 ++-- .../ArithmeticBinaryFunctors.hpp | 2 +- .../AsciiStringBinaryFunctors.hpp | 24 +- .../BinaryOperationSynthesizer.hpp | 660 +++++++++++++++++++ .../BinaryOperationWrapper.hpp | 629 ------------------ .../operations/binary_operations/CMakeLists.txt | 15 +- .../binary_operations/CMathBinaryFunctors.hpp | 2 +- .../operations/comparisons/BasicComparison.hpp | 23 +- .../comparisons/LiteralComparators-inl.hpp | 10 +- .../ArithmeticUnaryFunctors.hpp | 2 +- .../AsciiStringUnaryFunctors.hpp | 2 +- .../operations/unary_operations/CMakeLists.txt | 29 +- .../unary_operations/CMathUnaryFunctors.hpp | 2 +- .../unary_operations/CastFunctorOverloads.hpp | 195 +++--- .../unary_operations/CastOperation.cpp | 6 +- .../unary_operations/CastOperation.hpp | 4 +- .../unary_operations/DateExtractOperation.cpp | 20 +- .../UnaryOperationSynthesizer.hpp | 273 ++++++++ .../unary_operations/UnaryOperationWrapper.hpp | 250 ------- types/operations/utility/CMakeLists.txt | 11 +- types/operations/utility/CastUtil.cpp | 66 ++ types/operations/utility/CastUtil.hpp | 50 ++ .../utility/OperationSynthesizeUtil.hpp | 184 +++++- utility/Cast.hpp | 7 +- utility/meta/Common.hpp | 20 +- utility/meta/TypeList.hpp | 32 +- utility/meta/TypeListMetaFunctions.hpp | 11 +- 77 files changed, 2168 insertions(+), 1341 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/ExpressionFactories.cpp ---------------------------------------------------------------------- diff --git a/expressions/ExpressionFactories.cpp b/expressions/ExpressionFactories.cpp index f8913ba..2dd5124 100644 --- a/expressions/ExpressionFactories.cpp +++ b/expressions/ExpressionFactories.cpp @@ -181,7 +181,7 @@ Scalar* ScalarFactory::ReconstructFromProto(const serialization::Scalar &proto, proto.GetExtension(serialization::ScalarUnaryExpression::op_signature)); return new ScalarUnaryExpression( op_signature, - OperationFactory::Instance().getUnaryOperation(op_signature), + OperationFactory::GetUnaryOperation(op_signature), ReconstructFromProto(proto.GetExtension(serialization::ScalarUnaryExpression::operand), database), std::make_shared<std::vector<TypedValue>>(std::move(static_arguments))); } @@ -199,7 +199,7 @@ Scalar* ScalarFactory::ReconstructFromProto(const serialization::Scalar &proto, proto.GetExtension(serialization::ScalarBinaryExpression::op_signature)); return new ScalarBinaryExpression( op_signature, - OperationFactory::Instance().getBinaryOperation(op_signature), + OperationFactory::GetBinaryOperation(op_signature), ReconstructFromProto( proto.GetExtension(serialization::ScalarBinaryExpression::left_operand), database), ReconstructFromProto( http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/aggregation/AggregateFunctionAvg.cpp ---------------------------------------------------------------------- diff --git a/expressions/aggregation/AggregateFunctionAvg.cpp b/expressions/aggregation/AggregateFunctionAvg.cpp index b2b99c7..3acdb5b 100644 --- a/expressions/aggregation/AggregateFunctionAvg.cpp +++ b/expressions/aggregation/AggregateFunctionAvg.cpp @@ -41,14 +41,11 @@ bool AggregateFunctionAvg::canApplyToTypes( // Argument must be addable and divisible. const Type &type = *argument_types.front(); - if (!OperationFactory::Instance() - .getBinaryOperation("+", {type.getTypeID(), type.getTypeID()}) - ->canApplyTo(type, type)) { + if (!OperationFactory::CanApplyAddOperation(type, type)) { return false; } - return OperationFactory::Instance() - .getBinaryOperation("/", {type.getTypeID(), kDouble}) - ->canApplyTo(type, TypeFactory::GetType(kDouble)); + return OperationFactory::CanApplyDivideOperation( + type, TypeFactory::GetType(kDouble)); } const Type* AggregateFunctionAvg::resultTypeForArgumentTypes( @@ -71,8 +68,8 @@ const Type* AggregateFunctionAvg::resultTypeForArgumentTypes( break; } - return OperationFactory::Instance() - .getBinaryOperation("/", {sum_type->getTypeID(), kDouble}) + return OperationFactory::GetDivideOperation( + sum_type->getTypeID(), kDouble) ->getResultType(*sum_type, TypeFactory::GetType(kDouble)); } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/aggregation/AggregateFunctionSum.cpp ---------------------------------------------------------------------- diff --git a/expressions/aggregation/AggregateFunctionSum.cpp b/expressions/aggregation/AggregateFunctionSum.cpp index 11b33c0..b8c94b3 100644 --- a/expressions/aggregation/AggregateFunctionSum.cpp +++ b/expressions/aggregation/AggregateFunctionSum.cpp @@ -41,9 +41,7 @@ bool AggregateFunctionSum::canApplyToTypes( // Argument must be addable. const Type &type = *argument_types.front(); - return OperationFactory::Instance() - .getBinaryOperation("+", {type.getTypeID(), type.getTypeID()}) - ->canApplyTo(type, type); + return OperationFactory::CanApplyAddOperation(type, type); } const Type* AggregateFunctionSum::resultTypeForArgumentTypes( http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/aggregation/AggregationHandleAvg.cpp ---------------------------------------------------------------------- diff --git a/expressions/aggregation/AggregationHandleAvg.cpp b/expressions/aggregation/AggregationHandleAvg.cpp index 1324fd8..6ec59c7 100644 --- a/expressions/aggregation/AggregationHandleAvg.cpp +++ b/expressions/aggregation/AggregationHandleAvg.cpp @@ -67,22 +67,22 @@ AggregationHandleAvg::AggregationHandleAvg(const Type &type) // Make operators to do arithmetic: // Add operator for summing argument values. - fast_add_operator_.reset(OperationFactory::Instance() - .getBinaryOperation("+", {type_precision_id, argument_type_.getTypeID()}) + fast_add_operator_.reset( + OperationFactory::GetAddOperation(type_precision_id, argument_type_.getTypeID()) ->makeUncheckedBinaryOperator(sum_type, argument_type_)); // Add operator for merging states. - merge_add_operator_.reset(OperationFactory::Instance() - .getBinaryOperation("+", {type_precision_id, type_precision_id}) + merge_add_operator_.reset( + OperationFactory::GetAddOperation(type_precision_id, type_precision_id) ->makeUncheckedBinaryOperator(sum_type, sum_type)); // Divide operator for dividing sum by count to get final average. - divide_operator_.reset(OperationFactory::Instance() - .getBinaryOperation("/", {type_precision_id, kDouble}) + divide_operator_.reset( + OperationFactory::GetDivideOperation(type_precision_id, kDouble) ->makeUncheckedBinaryOperator(sum_type, TypeFactory::GetType(kDouble))); // Result is nullable, because AVG() over 0 values (or all NULL values) is // NULL. - result_type_ = &OperationFactory::Instance() - .getBinaryOperation("/", {type_precision_id, kDouble}) + result_type_ = + &OperationFactory::GetDivideOperation(type_precision_id, kDouble) ->getResultType(sum_type, TypeFactory::GetType(kDouble)) ->getNullableVersion(); } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/aggregation/AggregationHandleSum.cpp ---------------------------------------------------------------------- diff --git a/expressions/aggregation/AggregationHandleSum.cpp b/expressions/aggregation/AggregationHandleSum.cpp index c7ee776..9fdbab7 100644 --- a/expressions/aggregation/AggregationHandleSum.cpp +++ b/expressions/aggregation/AggregationHandleSum.cpp @@ -66,12 +66,12 @@ AggregationHandleSum::AggregationHandleSum(const Type &type) // Make operators to do arithmetic: // Add operator for summing argument values. - fast_operator_.reset(OperationFactory::Instance() - .getBinaryOperation("+", {type_precision_id, argument_type_.getTypeID()}) + fast_operator_.reset( + OperationFactory::GetAddOperation(type_precision_id, argument_type_.getTypeID()) ->makeUncheckedBinaryOperator(sum_type, argument_type_)); // Add operator for merging states. - merge_operator_.reset(OperationFactory::Instance() - .getBinaryOperation("+", {type_precision_id, type_precision_id}) + merge_operator_.reset( + OperationFactory::GetAddOperation(type_precision_id, type_precision_id) ->makeUncheckedBinaryOperator(sum_type, sum_type)); // Result is nullable, because SUM() over 0 values (or all NULL values) is http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/scalar/ScalarCaseExpression.cpp ---------------------------------------------------------------------- diff --git a/expressions/scalar/ScalarCaseExpression.cpp b/expressions/scalar/ScalarCaseExpression.cpp index 6fd2c0f..4a0cc72 100644 --- a/expressions/scalar/ScalarCaseExpression.cpp +++ b/expressions/scalar/ScalarCaseExpression.cpp @@ -470,7 +470,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors( for (std::vector<std::unique_ptr<TupleIdSequence>>::size_type case_idx = 0; case_idx < case_matches.size(); ++case_idx) { - DCHECK(case_results[case_idx]->isNative()); + DCHECK(case_results[case_idx]->getImplementation() == ColumnVector::kNative); if (!case_matches[case_idx]->empty()) { MultiplexNativeColumnVector( source_sequence, @@ -481,7 +481,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors( } if (else_result != nullptr) { - DCHECK(else_result->isNative()); + DCHECK(else_result->getImplementation() == ColumnVector::kNative); DCHECK(!else_matches.empty()); MultiplexNativeColumnVector(source_sequence, else_matches, @@ -498,7 +498,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors( for (std::vector<std::unique_ptr<TupleIdSequence>>::size_type case_idx = 0; case_idx < case_matches.size(); ++case_idx) { - DCHECK(!case_results[case_idx]->isNative()); + DCHECK(case_results[case_idx]->getImplementation() == ColumnVector::kIndirect); if (!case_matches[case_idx]->empty()) { MultiplexIndirectColumnVector( source_sequence, @@ -509,7 +509,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors( } if (else_result != nullptr) { - DCHECK(!else_result->isNative()); + DCHECK(else_result->getImplementation() == ColumnVector::kIndirect); DCHECK(!else_matches.empty()); MultiplexIndirectColumnVector(source_sequence, else_matches, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp ---------------------------------------------------------------------- diff --git a/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp b/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp index a70a8bc..fcd737e 100644 --- a/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp +++ b/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp @@ -39,6 +39,7 @@ bool WindowAggregateFunctionAvg::canApplyToTypes( } // Argument must be addable and divisible. + // TODO(refactor-type): Fix this. // return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd) // .canApplyTo(*argument_types.front(), *argument_types.front()) && // BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide) @@ -66,7 +67,7 @@ const Type* WindowAggregateFunctionAvg::resultTypeForArgumentTypes( break; } -// TODO + // TODO(refactor-type): Fix this. // return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide) // .getResultType(*sum_type, TypeFactory::GetType(kDouble)); return nullptr; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/window_aggregation/WindowAggregateFunctionSum.cpp ---------------------------------------------------------------------- diff --git a/expressions/window_aggregation/WindowAggregateFunctionSum.cpp b/expressions/window_aggregation/WindowAggregateFunctionSum.cpp index e383c63..09bc4e9 100644 --- a/expressions/window_aggregation/WindowAggregateFunctionSum.cpp +++ b/expressions/window_aggregation/WindowAggregateFunctionSum.cpp @@ -39,7 +39,7 @@ bool WindowAggregateFunctionSum::canApplyToTypes( } // Argument must be addable. -// TODO + // TODO(refactor-type): Fix this. // return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd) // .canApplyTo(*argument_types.front(), *argument_types.front()); return false; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/window_aggregation/WindowAggregationHandle.cpp ---------------------------------------------------------------------- diff --git a/expressions/window_aggregation/WindowAggregationHandle.cpp b/expressions/window_aggregation/WindowAggregationHandle.cpp index 7621726..e327a4f 100644 --- a/expressions/window_aggregation/WindowAggregationHandle.cpp +++ b/expressions/window_aggregation/WindowAggregationHandle.cpp @@ -82,8 +82,8 @@ WindowAggregationHandle::WindowAggregationHandle( TypeFactory::GetUnifyingType(*first_order_key_type, long_type); range_add_operator_.reset( - OperationFactory::Instance().getBinaryOperation( - "+", {first_order_key_type->getTypeID(), kLong}, 0) + OperationFactory::GetAddOperation( + first_order_key_type->getTypeID(), kLong) ->makeUncheckedBinaryOperator(*first_order_key_type, long_type)); range_comparator_.reset( ComparisonFactory::GetComparison(ComparisonID::kLessOrEqual) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/expressions/window_aggregation/WindowAggregationHandleAvg.cpp ---------------------------------------------------------------------- diff --git a/expressions/window_aggregation/WindowAggregationHandleAvg.cpp b/expressions/window_aggregation/WindowAggregationHandleAvg.cpp index 3539d03..10272a9 100644 --- a/expressions/window_aggregation/WindowAggregationHandleAvg.cpp +++ b/expressions/window_aggregation/WindowAggregationHandleAvg.cpp @@ -69,7 +69,7 @@ WindowAggregationHandleAvg::WindowAggregationHandleAvg( sum_type_ = &(TypeFactory::GetType(type_id)); -// TODO + LOG(FATAL) << "TODO(refactor-type)"; // // Result is nullable, because AVG() over 0 values (or all NULL values) is // // NULL. // result_type_ @@ -98,7 +98,7 @@ ColumnVector* WindowAggregationHandleAvg::calculate( ColumnVectorsValueAccessor *tuple_accessor, const std::vector<ColumnVector*> &arguments) const { DCHECK_EQ(1u, arguments.size()); - DCHECK(arguments[0]->isNative()); + DCHECK(arguments[0]->getImplementation() == ColumnVector::kNative); DCHECK_EQ(static_cast<std::size_t>(tuple_accessor->getNumTuples()), static_cast<const NativeColumnVector*>(arguments[0])->size()); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/query_optimizer/expressions/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt index b51a0a8..889c450 100644 --- a/query_optimizer/expressions/CMakeLists.txt +++ b/query_optimizer/expressions/CMakeLists.txt @@ -113,8 +113,11 @@ target_link_libraries(quickstep_queryoptimizer_expressions_Cast quickstep_queryoptimizer_expressions_ExpressionType quickstep_queryoptimizer_expressions_PatternMatcher quickstep_queryoptimizer_expressions_Scalar + quickstep_types_MetaType quickstep_types_Type - quickstep_types_operations_unaryoperations_CastOperation + quickstep_types_operations_OperationFactory + quickstep_types_operations_OperationSignature + quickstep_types_operations_unaryoperations_UnaryOperation quickstep_utility_HashPair quickstep_utility_Macros) target_link_libraries(quickstep_queryoptimizer_expressions_CommonSubexpression @@ -255,6 +258,8 @@ target_link_libraries(quickstep_queryoptimizer_expressions_Scalar glog quickstep_queryoptimizer_expressions_ExprId quickstep_queryoptimizer_expressions_Expression + quickstep_types_GenericValue + quickstep_types_TypedValue quickstep_utility_HashError quickstep_utility_Macros) target_link_libraries(quickstep_queryoptimizer_expressions_ScalarLiteral @@ -267,8 +272,8 @@ target_link_libraries(quickstep_queryoptimizer_expressions_ScalarLiteral quickstep_queryoptimizer_expressions_ExpressionType quickstep_queryoptimizer_expressions_PatternMatcher quickstep_queryoptimizer_expressions_Scalar + quickstep_types_GenericValue quickstep_types_Type - quickstep_types_TypedValue quickstep_utility_HashPair quickstep_utility_Macros) target_link_libraries(quickstep_queryoptimizer_expressions_SearchedCase @@ -327,6 +332,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions_UnaryExpression quickstep_queryoptimizer_expressions_PatternMatcher quickstep_queryoptimizer_expressions_Scalar quickstep_queryoptimizer_expressions_ScalarLiteral + quickstep_types_GenericValue quickstep_types_operations_OperationSignature quickstep_types_operations_unaryoperations_UnaryOperation quickstep_utility_HashPair @@ -352,6 +358,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions quickstep_queryoptimizer_expressions_Alias quickstep_queryoptimizer_expressions_AttributeReference quickstep_queryoptimizer_expressions_BinaryExpression + quickstep_queryoptimizer_expressions_Cast quickstep_queryoptimizer_expressions_CommonSubexpression quickstep_queryoptimizer_expressions_ComparisonExpression quickstep_queryoptimizer_expressions_Exists http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/query_optimizer/expressions/Cast.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/expressions/Cast.cpp b/query_optimizer/expressions/Cast.cpp index 6b2015f..2315f92 100644 --- a/query_optimizer/expressions/Cast.cpp +++ b/query_optimizer/expressions/Cast.cpp @@ -61,7 +61,7 @@ ExpressionPtr Cast::copyWithNewChildren( OperationSignature::Create( "cast", {operand_->getValueType().getTypeID(), kMetaType}, 1); const UnaryOperationPtr cast_operation = - OperationFactory::Instance().getUnaryOperation(op_signature); + OperationFactory::GetUnaryOperation(op_signature); std::vector<TypedValue> meta_type_value = { GenericValue::CreateWithLiteral( http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/query_optimizer/resolver/Resolver.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp index 4ffb3eb..778aa77 100644 --- a/query_optimizer/resolver/Resolver.cpp +++ b/query_optimizer/resolver/Resolver.cpp @@ -1024,19 +1024,15 @@ L::LogicalPtr Resolver::resolveInsertSelection( cast_expressions.emplace_back(selection_attributes[aid]); } else { // TODO(jianqiao): implement Cast operation for non-numeric types. - if (destination_type.getSuperTypeID() == SuperTypeID::kNumeric && - selection_type.getSuperTypeID() == SuperTypeID::kNumeric && - destination_type.isSafelyCoercibleFrom(selection_type)) { + if (destination_type.isSafelyCoercibleFrom(selection_type)) { // Add cast operation -// const E::AttributeReferencePtr attr = selection_attributes[aid]; -// const E::ExpressionPtr cast_expr = -// E::Cast::Create(attr, destination_type); -// cast_expressions.emplace_back( -// E::Alias::Create(context_->nextExprId(), -// cast_expr, -// attr->attribute_name(), -// attr->attribute_alias())); - THROW_SQL_ERROR_AT(insert_statement.relation_name()) << "TODO: not handled"; + const E::AttributeReferencePtr attr = selection_attributes[aid]; + const E::ExpressionPtr cast_expr = E::Cast::Create(attr, destination_type); + cast_expressions.emplace_back( + E::Alias::Create(context_->nextExprId(), + cast_expr, + attr->attribute_name(), + attr->attribute_alias())); } else { THROW_SQL_ERROR_AT(insert_statement.relation_name()) << "The assigned value for the column " @@ -1169,9 +1165,8 @@ L::LogicalPtr Resolver::resolveUpdate( // Coerce the assignment expression if its Type is not equal to that of the // assigned attribute. if (!assignment_expression->getValueType().equals(attribute->getValueType())) { -// assignment_expression = -// E::Cast::Create(assignment_expression, attribute->getValueType()); - THROW_SQL_ERROR_AT(&assignment) << "TODO: not handled"; + assignment_expression = + E::Cast::Create(assignment_expression, attribute->getValueType()); } if (assignee_ids.find(attribute->id()) != assignee_ids.end()) { THROW_SQL_ERROR_AT(&assignment) << "Multiple assignments to the column " @@ -1655,12 +1650,11 @@ L::LogicalPtr Resolver::resolveSetOperations( if (possible_type.equals(current_type)) { cast_expressions.emplace_back(current_attr); } else { -// cast_expressions.emplace_back( -// E::Alias::Create(context_->nextExprId(), -// E::Cast::Create(current_attr, possible_type), -// current_attr->attribute_name(), -// current_attr->attribute_alias())); - LOG(FATAL) << "TODO: not handled"; + cast_expressions.emplace_back( + E::Alias::Create(context_->nextExprId(), + E::Cast::Create(current_attr, possible_type), + current_attr->attribute_name(), + current_attr->attribute_alias())); } } resolved_operations[opid] = L::Project::Create(resolved_operations[opid], cast_expressions); @@ -2558,11 +2552,19 @@ E::ScalarPtr Resolver::resolveExpression( case ParseExpression::kTypeCast: { const ParseTypeCast &parse_type_cast = static_cast<const ParseTypeCast&>(parse_expression); - return E::Cast::Create( + const E::ScalarPtr operand = resolveExpression(parse_type_cast.operand(), nullptr /* type_hint */, - expression_resolution_info), - resolveDataType(parse_type_cast.target_type())); + expression_resolution_info); + const Type &target_type = + resolveDataType(parse_type_cast.target_type()); + if (!OperationFactory::CanApplyCastOperation(operand->getValueType(), + target_type)) { + THROW_SQL_ERROR_AT(&parse_type_cast) + << "Cannot cast from " << operand->getValueType().getName() + << " type to " << target_type.getName() << " type"; + } + return E::Cast::Create(operand, target_type); } default: LOG(FATAL) << "Unknown scalar type: " @@ -2583,7 +2585,7 @@ E::ScalarPtr Resolver::resolveArray( return E::ScalarLiteral::Create( GenericValue::CreateWithLiteral( ArrayType::InstanceNonNullable({meta_null_type_value}), - ArrayLiteral())); + ArrayLit(NullType::InstanceNullable()))); } else { // Currently we only support homogeneous array with literal values. std::vector<E::ScalarLiteralPtr> literals; @@ -2620,9 +2622,9 @@ E::ScalarPtr Resolver::resolveArray( ArrayType::InstanceNonNullable({meta_element_type_value}); // NOTE(refactor-type): Possibly memory leak region, noexcept. - std::unique_ptr<ArrayLiteral> array_literal = std::make_unique<ArrayLiteral>(); + std::unique_ptr<ArrayLit> array_literal = std::make_unique<ArrayLit>(*element_type); for (const auto &literal : literals) { - array_literal->emplace_back( + array_literal->push_back( element_type->cloneValue(literal->value().getValue())); } return E::ScalarLiteral::Create( @@ -2718,15 +2720,13 @@ E::ScalarPtr Resolver::resolveSearchedCaseExpression( // Cast all the result expressions to the same type. for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) { if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) { -// conditional_result_expression = -// E::Cast::Create(conditional_result_expression, *result_data_type); - LOG(FATAL) << "TODO: not handled"; + conditional_result_expression = + E::Cast::Create(conditional_result_expression, *result_data_type); } } if (else_result_expression != nullptr && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) { -// else_result_expression = E::Cast::Create(else_result_expression, *result_data_type); - LOG(FATAL) << "TODO: not handled"; + else_result_expression = E::Cast::Create(else_result_expression, *result_data_type); } if (else_result_expression == nullptr) { @@ -2864,15 +2864,13 @@ E::ScalarPtr Resolver::resolveSimpleCaseExpression( // Cast all the result expressions to the same type. for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) { if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) { -// conditional_result_expression = -// E::Cast::Create(conditional_result_expression, *result_data_type); - LOG(FATAL) << "TODO: not handled"; + conditional_result_expression = + E::Cast::Create(conditional_result_expression, *result_data_type); } } if (else_result_expression != nullptr && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) { -// else_result_expression = E::Cast::Create(else_result_expression, *result_data_type); - LOG(FATAL) << "TODO: not handled"; + else_result_expression = E::Cast::Create(else_result_expression, *result_data_type); } if (else_result_expression == nullptr) { @@ -2916,7 +2914,7 @@ E::ScalarPtr Resolver::resolveScalarFunction( std::shared_ptr<const std::vector<GenericValue>> coerced_static_arguments; std::string message; const OperationSignaturePtr op_signature = - OperationFactory::Instance().resolveOperation( + OperationFactory::ResolveOperation( function_name, std::make_shared<const std::vector<const Type*>>(std::move(argument_types)), std::make_shared<const std::vector<GenericValue>>(std::move(static_arguments)), @@ -2936,8 +2934,7 @@ E::ScalarPtr Resolver::resolveScalarFunction( // TODO: add cast if neccessary. (void)coerced_argument_types; - const OperationPtr operation = - OperationFactory::Instance().getOperation(op_signature); + const OperationPtr operation = OperationFactory::GetOperation(op_signature); switch (operation->getOperationSuperTypeID()) { case Operation::kUnaryOperation: return E::UnaryExpression::Create( @@ -3008,8 +3005,7 @@ E::ScalarPtr Resolver::resolveFunctionCall( } } - if (OperationFactory::Instance().hasOperation(function_name, - resolved_arguments.size())) { + if (OperationFactory::HasOperation(function_name, resolved_arguments.size())) { E::ScalarPtr scalar = resolveScalarFunction(parse_function_call, function_name, resolved_arguments, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/query_optimizer/rules/Partition.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/rules/Partition.cpp b/query_optimizer/rules/Partition.cpp index d55d296..0e21b98 100644 --- a/query_optimizer/rules/Partition.cpp +++ b/query_optimizer/rules/Partition.cpp @@ -416,7 +416,7 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) { get<2>(avg_recompute_expression)->getValueType().getTypeID() }, 0); const BinaryOperationPtr divide_op = - OperationFactory::Instance().getBinaryOperation(op_sig); + OperationFactory::GetBinaryOperation(op_sig); const E::BinaryExpressionPtr new_avg_expr = E::BinaryExpression::Create(op_sig, divide_op, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/query_optimizer/rules/ReuseAggregateExpressions.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/rules/ReuseAggregateExpressions.cpp b/query_optimizer/rules/ReuseAggregateExpressions.cpp index d63715a..65832e7 100644 --- a/query_optimizer/rules/ReuseAggregateExpressions.cpp +++ b/query_optimizer/rules/ReuseAggregateExpressions.cpp @@ -324,7 +324,7 @@ P::PhysicalPtr ReuseAggregateExpressions::applyToNode( OperationSignature::Create("/", operand_tids, 0); const BinaryOperationPtr ÷_op = - OperationFactory::Instance().getBinaryOperation(op_sig); + OperationFactory::GetBinaryOperation(op_sig); const E::BinaryExpressionPtr avg_expr = E::BinaryExpression::Create(op_sig, divide_op, http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/storage/SMAIndexSubBlock.cpp ---------------------------------------------------------------------- diff --git a/storage/SMAIndexSubBlock.cpp b/storage/SMAIndexSubBlock.cpp index 5a8a747..2f7c474 100644 --- a/storage/SMAIndexSubBlock.cpp +++ b/storage/SMAIndexSubBlock.cpp @@ -358,10 +358,9 @@ SMAIndexSubBlock::SMAIndexSubBlock(const TupleStorageSubBlock &tuple_store, TypeID attr_sum_typeid = sma_internal::getTypeForSum(attr_typeid); if (add_operations_.elementIsNullAt(attr_typeid)) { add_operations_.replaceElement(attr_typeid, - OperationFactory::Instance().getBinaryOperation( - "+", {attr_typeid, attr_sum_typeid}) - ->makeUncheckedBinaryOperator(TypeFactory::GetType(attr_typeid), - TypeFactory::GetType(attr_sum_typeid))); + OperationFactory::GetAddOperation(attr_typeid, attr_sum_typeid) + ->makeUncheckedBinaryOperator(TypeFactory::GetType(attr_typeid), + TypeFactory::GetType(attr_sum_typeid))); } } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/storage/WindowAggregationOperationState.cpp ---------------------------------------------------------------------- diff --git a/storage/WindowAggregationOperationState.cpp b/storage/WindowAggregationOperationState.cpp index 30d91db..2b63a6c 100644 --- a/storage/WindowAggregationOperationState.cpp +++ b/storage/WindowAggregationOperationState.cpp @@ -261,7 +261,7 @@ void WindowAggregationOperationState::windowAggregateBlocks( for (std::size_t attr_id = 0; attr_id < attribute_vecs.size(); ++attr_id) { ColumnVector *attr_vec = attribute_vecs[attr_id]; - if (attr_vec->isNative()) { + if (attr_vec->getImplementation() == ColumnVector::kNative) { static_cast<NativeColumnVector*>(attr_vec)->appendTypedValue( tuple_accessor->getTypedValue(attr_id)); } else { @@ -274,7 +274,7 @@ void WindowAggregationOperationState::windowAggregateBlocks( argument_idx < argument_vecs.size(); ++argument_idx) { ColumnVector *argument = argument_vecs[argument_idx]; - if (argument->isNative()) { + if (argument->getImplementation() == ColumnVector::kNative) { static_cast<NativeColumnVector*>(argument)->appendTypedValue( argument_accessor->getTypedValue(argument_idx)); } else { http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/ArrayLit.hpp ---------------------------------------------------------------------- diff --git a/types/ArrayLit.hpp b/types/ArrayLit.hpp new file mode 100644 index 0000000..b5d3548 --- /dev/null +++ b/types/ArrayLit.hpp @@ -0,0 +1,112 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + **/ + +#ifndef QUICKSTEP_TYPES_ARRAY_LIT_HPP_ +#define QUICKSTEP_TYPES_ARRAY_LIT_HPP_ + +#include <cstddef> +#include <vector> + +#include "types/Type.hpp" + +#include "glog/logging.h" + +namespace quickstep { + +/** \addtogroup Types + * @{ + */ + +typedef void UntypedLiteral; + +class ArrayLit { + public: + using const_iterator = std::vector<UntypedLiteral*>::const_iterator; + + ArrayLit(const Type &type) + : type_(type) { + } + + ArrayLit(const ArrayLit &other) + : type_(other.type_) { + for (const UntypedLiteral *value :other.elements_) { + elements_.emplace_back(type_.cloneValue(value)); + } + } + + ArrayLit(ArrayLit &&other) + : type_(other.type_), + elements_(std::move(other.elements_)) { + } + + ~ArrayLit() { + clear(); + } + + void clear() { + for (UntypedLiteral *value : elements_) { + type_.destroyValue(value); + } + elements_.clear(); + } + + bool empty() const { + return elements_.empty(); + } + + std::size_t size() const { + return elements_.size(); + } + + + void push_back(UntypedLiteral *value) { + elements_.emplace_back(value); + } + + const UntypedLiteral* operator[](const std::size_t idx) const { + DCHECK_LT(idx, elements_.size()); + return elements_[idx]; + } + + const_iterator begin() const { + return elements_.begin(); + } + + const_iterator end() const { + return elements_.end(); + } + + const UntypedLiteral* front() const { + return elements_.front(); + } + + const UntypedLiteral* back() const { + return elements_.back(); + } + + private: + const Type &type_; + std::vector<UntypedLiteral*> elements_; +}; + +/** @} */ + +} // namespace quickstep + +#endif // QUICKSTEP_TYPES_NULL_LIT_HPP_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/ArrayType.cpp ---------------------------------------------------------------------- diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp index 765a1a0..8d8313f 100644 --- a/types/ArrayType.cpp +++ b/types/ArrayType.cpp @@ -22,6 +22,7 @@ #include <cstdlib> #include <string> +#include "types/ArrayLit.hpp" #include "types/Type.pb.h" #include "types/TypeID.hpp" @@ -39,6 +40,15 @@ std::string ArrayType::getName() const { return name; } +bool ArrayType::isCoercibleFrom(const Type &original_type) const { + if (original_type.getTypeID() != kArray) { + return false; + } + const Type &original_element_type = + static_cast<const ArrayType&>(original_type).element_type_; + return element_type_.isCoercibleFrom(original_element_type); +} + bool ArrayType::TypeParametersAreValid(const std::vector<GenericValue> ¶meters) { if (parameters.size() != 1u) { return false; @@ -52,13 +62,13 @@ bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs, if (!equals(rhs_type)) { return false; } - const ArrayLiteral &lhs_array = castValueToLiteral(lhs); - const ArrayLiteral &rhs_array = castValueToLiteral(rhs); + const ArrayLit &lhs_array = castValueToLiteral(lhs); + const ArrayLit &rhs_array = castValueToLiteral(rhs); if (lhs_array.size() != rhs_array.size()) { return false; } for (std::size_t i = 0; i < lhs_array.size(); ++i) { - if (!element_type_.checkValuesEqual(lhs_array.at(i), rhs_array.at(i))) { + if (!element_type_.checkValuesEqual(lhs_array[i], rhs_array[i])) { return false; } } @@ -66,8 +76,8 @@ bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs, } TypedValue ArrayType::marshallValue(const UntypedLiteral *value) const { - const ArrayLiteral &array = *static_cast<const ArrayLiteral*>(value); - serialization::ArrayLiteral proto; + const ArrayLit &array = *static_cast<const ArrayLit*>(value); + serialization::ArrayLit proto; for (const auto &element : array) { // TODO(refactor-type): Improve performance. TypedValue value = element_type_.marshallValue(element); @@ -81,12 +91,12 @@ TypedValue ArrayType::marshallValue(const UntypedLiteral *value) const { UntypedLiteral* ArrayType::unmarshallValue(const void *data, const std::size_t data_size) const { - std::unique_ptr<ArrayLiteral> array = std::make_unique<ArrayLiteral>(); - serialization::ArrayLiteral proto; + std::unique_ptr<ArrayLit> array = std::make_unique<ArrayLit>(element_type_); + serialization::ArrayLit proto; proto.ParseFromArray(data, data_size); for (int i = 0; i < proto.data_size(); ++i) { const std::string &element_data = proto.data(i); - array->emplace_back( + array->push_back( element_type_.unmarshallValue(element_data.c_str(), element_data.size())); } return array.release(); @@ -95,13 +105,13 @@ UntypedLiteral* ArrayType::unmarshallValue(const void *data, std::string ArrayType::printValueToString(const UntypedLiteral *value) const { DCHECK(value != nullptr); - const std::vector<UntypedLiteral*> &literals = castValueToLiteral(value); + const ArrayLit &literals = castValueToLiteral(value); std::string ret = "{"; if (!literals.empty()) { ret.append(element_type_.printValueToString(literals.front())); for (std::size_t i = 1; i < literals.size(); ++i) { ret.append(","); - ret.append(element_type_.printValueToString(literals.at(i))); + ret.append(element_type_.printValueToString(literals[i])); } } ret.append("}"); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/ArrayType.hpp ---------------------------------------------------------------------- diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp index 5eaff92..e79e389 100644 --- a/types/ArrayType.hpp +++ b/types/ArrayType.hpp @@ -39,7 +39,7 @@ class TypedValue; * @{ */ -class ArrayType : public TypeSynthesizer<kArray> { +class ArrayType final : public TypeSynthesizer<kArray> { public: int getPrintWidth() const override { return 32; @@ -47,6 +47,8 @@ class ArrayType : public TypeSynthesizer<kArray> { std::string getName() const override; + bool isCoercibleFrom(const Type &original_type) const override; + bool checkValuesEqual(const UntypedLiteral *lhs, const UntypedLiteral *rhs, const Type &rhs_type) const override; @@ -63,6 +65,10 @@ class ArrayType : public TypeSynthesizer<kArray> { return false; } + const Type &getElementType() const { + return element_type_; + } + static bool TypeParametersAreValid(const std::vector<GenericValue> ¶meters); private: @@ -73,7 +79,7 @@ class ArrayType : public TypeSynthesizer<kArray> { static const Type& ExtractType(const std::vector<GenericValue> ¶meters) { DCHECK(TypeParametersAreValid(parameters)); - return **static_cast<const MetaTypeLiteral*>(parameters.front().getValue()); + return **static_cast<const MetaTypeLit*>(parameters.front().getValue()); } const Type &element_type_; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/AsciiStringSuperType.hpp ---------------------------------------------------------------------- diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp index 7de550f..252a1a7 100644 --- a/types/AsciiStringSuperType.hpp +++ b/types/AsciiStringSuperType.hpp @@ -38,14 +38,6 @@ namespace quickstep { template <TypeID type_id> class AsciiStringSuperType : public TypeSynthesizer<type_id> { public: - bool isCoercibleFrom(const Type &original_type) const override { - if (original_type.isNullable() && !this->nullable_) { - return false; - } - return (original_type.getSuperTypeID() == SuperTypeID::kAsciiString) - || (original_type.getTypeID() == kNullType); - } - /** * @brief Get the character-length of this string type. * http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/BoolType.hpp ---------------------------------------------------------------------- diff --git a/types/BoolType.hpp b/types/BoolType.hpp index ed819ae..49fbfa3 100644 --- a/types/BoolType.hpp +++ b/types/BoolType.hpp @@ -41,7 +41,7 @@ class TypedValue; /** * @brief A type representing a 8-bit bool. **/ -class BoolType : public NumericSuperType<kBool> { +class BoolType final : public NumericSuperType<kBool> { public: int getPrintWidth() const override { // "true" or "false" http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt index 0ee4f26..271700b 100644 --- a/types/CMakeLists.txt +++ b/types/CMakeLists.txt @@ -32,6 +32,7 @@ QS_PROTOBUF_GENERATE_CPP(types_TypedValue_proto_srcs types_TypedValue_proto_hdrs QS_PROTOBUF_GENERATE_CPP(types_Type_proto_srcs types_Type_proto_hdrs Type.proto) # Declare micro-libs: +add_library(quickstep_types_ArrayLit ../empty_src.cpp ArrayLit.hpp) add_library(quickstep_types_ArrayType ArrayType.cpp ArrayType.hpp) add_library(quickstep_types_AsciiStringSuperType ../empty_src.cpp AsciiStringSuperType.hpp) add_library(quickstep_types_BoolType BoolType.cpp BoolType.hpp) @@ -185,6 +186,7 @@ target_link_libraries(quickstep_types_MetaType-decl quickstep_types_Type quickstep_types_TypeID quickstep_types_TypeSynthesizer + quickstep_types_TypedValue quickstep_utility_Macros) target_link_libraries(quickstep_types_NullType glog @@ -203,6 +205,7 @@ target_link_libraries(quickstep_types_NumericSuperType quickstep_utility_Macros quickstep_utility_meta_TMP) target_link_libraries(quickstep_types_NumericTypeSafeCoercibility + quickstep_types_TypeRegistrar quickstep_utility_meta_TMP) target_link_libraries(quickstep_types_NumericTypeUnifier quickstep_types_NumericTypeSafeCoercibility) @@ -228,7 +231,8 @@ target_link_libraries(quickstep_types_TypeFactory quickstep_types_TypeSynthesizer quickstep_types_TypeUtil quickstep_types_Type_proto - quickstep_utility_Macros) + quickstep_utility_Macros + quickstep_utility_StringUtil) target_link_libraries(quickstep_types_TypeFactory-decl glog quickstep_types_GenericValue @@ -254,6 +258,7 @@ target_link_libraries(quickstep_types_TypeSynthesizer quickstep_types_TypeRegistrar quickstep_types_TypedValue quickstep_types_Type_proto + quickstep_types_operations_utility_CastUtil quickstep_utility_HashPair quickstep_utility_Macros quickstep_utility_meta_Common) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/CharType.hpp ---------------------------------------------------------------------- diff --git a/types/CharType.hpp b/types/CharType.hpp index 3355243..cfd695e 100644 --- a/types/CharType.hpp +++ b/types/CharType.hpp @@ -43,7 +43,7 @@ namespace quickstep { * represented WITHOUT a null-terminator character. Any strings shorter * than the maximum length will have a null-terminator. **/ -class CharType : public AsciiStringSuperType<kChar> { +class CharType final : public AsciiStringSuperType<kChar> { public: bool isSafelyCoercibleFrom(const Type &original_type) const override; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/DateType.hpp ---------------------------------------------------------------------- diff --git a/types/DateType.hpp b/types/DateType.hpp index 1c9eaf9..b88bb82 100644 --- a/types/DateType.hpp +++ b/types/DateType.hpp @@ -41,7 +41,7 @@ class TypedValue; /** * @brief A type representing the date. **/ -class DateType : public TypeSynthesizer<kDate> { +class DateType final : public TypeSynthesizer<kDate> { public: int getPrintWidth() const override { return DateLit::kIsoChars; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/DatetimeIntervalType.hpp ---------------------------------------------------------------------- diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp index cb2534d..b80b2a7 100644 --- a/types/DatetimeIntervalType.hpp +++ b/types/DatetimeIntervalType.hpp @@ -41,7 +41,7 @@ namespace quickstep { /** * @brief A type representing the datetime interval. **/ -class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> { +class DatetimeIntervalType final : public TypeSynthesizer<kDatetimeInterval> { public: int getPrintWidth() const override { return DatetimeIntervalLit::kPrintingChars; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/DatetimeType.hpp ---------------------------------------------------------------------- diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp index d0ac1e2..dbad0e2 100644 --- a/types/DatetimeType.hpp +++ b/types/DatetimeType.hpp @@ -41,8 +41,7 @@ class TypedValue; /** * @brief A type representing the datetime. **/ -class DatetimeType - : public TypeSynthesizer<kDatetime> { +class DatetimeType final : public TypeSynthesizer<kDatetime> { public: int getPrintWidth() const override { return DatetimeLit::kIsoChars; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/DoubleType.hpp ---------------------------------------------------------------------- diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp index 6959817..3e906db 100644 --- a/types/DoubleType.hpp +++ b/types/DoubleType.hpp @@ -40,7 +40,7 @@ class TypedValue; /** * @brief A type representing a double-precision floating-point number. **/ -class DoubleType : public NumericSuperType<kDouble> { +class DoubleType final : public NumericSuperType<kDouble> { public: int getPrintWidth() const override { return kPrintWidth; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/FloatType.hpp ---------------------------------------------------------------------- diff --git a/types/FloatType.hpp b/types/FloatType.hpp index 3a7aa41..e9062e0 100644 --- a/types/FloatType.hpp +++ b/types/FloatType.hpp @@ -40,7 +40,7 @@ class TypedValue; /** * @brief A type representing a single-precision floating-point number. **/ -class FloatType : public NumericSuperType<kFloat> { +class FloatType final : public NumericSuperType<kFloat> { public: int getPrintWidth() const override { return kPrintWidth; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/IntType.hpp ---------------------------------------------------------------------- diff --git a/types/IntType.hpp b/types/IntType.hpp index eb5e5aa..7b42906 100644 --- a/types/IntType.hpp +++ b/types/IntType.hpp @@ -40,7 +40,7 @@ class TypedValue; /** * @brief A type representing a 32-bit integer. **/ -class IntType : public NumericSuperType<kInt> { +class IntType final : public NumericSuperType<kInt> { public: int getPrintWidth() const override { // Fully represented digits, single leading digit, and possible '-' http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/LongType.hpp ---------------------------------------------------------------------- diff --git a/types/LongType.hpp b/types/LongType.hpp index dc75310..3cd3fc0 100644 --- a/types/LongType.hpp +++ b/types/LongType.hpp @@ -41,7 +41,7 @@ class TypedValue; /** * @brief A type representing a 64-bit integer. **/ -class LongType : public NumericSuperType<kLong> { +class LongType final : public NumericSuperType<kLong> { public: // Fully represented digits, single leading digit, and possible '-' // character. http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/MetaType-decl.hpp ---------------------------------------------------------------------- diff --git a/types/MetaType-decl.hpp b/types/MetaType-decl.hpp index 80c5956..569c956 100644 --- a/types/MetaType-decl.hpp +++ b/types/MetaType-decl.hpp @@ -37,7 +37,7 @@ namespace quickstep { * @{ */ -class MetaType : public TypeSynthesizer<kMetaType> { +class MetaType final : public TypeSynthesizer<kMetaType> { public: int getPrintWidth() const override { return 16; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/MetaType.cpp ---------------------------------------------------------------------- diff --git a/types/MetaType.cpp b/types/MetaType.cpp index 16a86c2..f3da71b 100644 --- a/types/MetaType.cpp +++ b/types/MetaType.cpp @@ -51,7 +51,7 @@ UntypedLiteral* MetaType::unmarshallValue(const void *data, const std::size_t data_size) const { serialization::Type proto; proto.ParseFromArray(data, data_size); - return new MetaTypeLiteral(&TypeFactory::ReconstructFromProto(proto)); + return new MetaTypeLit(&TypeFactory::ReconstructFromProto(proto)); } std::string MetaType::printValueToString(const UntypedLiteral *value) const { http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/NullType.hpp ---------------------------------------------------------------------- diff --git a/types/NullType.hpp b/types/NullType.hpp index 1aa8a1c..ae448ea 100644 --- a/types/NullType.hpp +++ b/types/NullType.hpp @@ -49,7 +49,7 @@ class TypedValue; * a particular operation may accept. It is also assumed that applying * any operation to an argument of NullType always yields NULL values. **/ -class NullType : public TypeSynthesizer<kNullType> { +class NullType final : public TypeSynthesizer<kNullType> { public: static const NullType& InstanceNonNullable() { LOG(FATAL) << "Called NullType::InstanceNonNullable(), " http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/NumericSuperType.hpp ---------------------------------------------------------------------- diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp index f474d52..6a6ad96 100644 --- a/types/NumericSuperType.hpp +++ b/types/NumericSuperType.hpp @@ -53,11 +53,6 @@ class NumericSuperType : public TypeSynthesizer<type_id> { return it != safe_coerce_cache_.end(); } - bool isCoercibleFrom(const Type &original_type) const override { - QUICKSTEP_NULL_COERCIBILITY_CHECK(); - return (original_type.getSuperTypeID() == SuperTypeID::kNumeric); - } - TypedValue makeZeroValue() const override { return TypedValue(static_cast<typename TypeIDTrait<type_id>::cpptype>(0)); } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/TextType.hpp ---------------------------------------------------------------------- diff --git a/types/TextType.hpp b/types/TextType.hpp index 9ceea35..a1fc04e 100644 --- a/types/TextType.hpp +++ b/types/TextType.hpp @@ -36,7 +36,7 @@ namespace quickstep { * @{ */ -class TextType : public TypeSynthesizer<kText> { +class TextType final : public TypeSynthesizer<kText> { public: int getPrintWidth() const override { return 32; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/Type.cpp ---------------------------------------------------------------------- diff --git a/types/Type.cpp b/types/Type.cpp index 41780f8..cbfd8dd 100644 --- a/types/Type.cpp +++ b/types/Type.cpp @@ -28,10 +28,6 @@ namespace quickstep { -bool Type::isCoercibleFrom(const Type &original_type) const { - return isSafelyCoercibleFrom(original_type); -} - bool Type::isSafelyCoercibleFrom(const Type &original_type) const { if (original_type.isNullable() && !this->nullable_) { return false; @@ -79,20 +75,10 @@ TypedValue Type::coerceTypedValue(const TypedValue &original_value, UntypedLiteral* Type::coerceValue(const UntypedLiteral *original_value, const Type &original_type) const { - DCHECK(isCoercibleFrom(original_type)) - << "Can't coerce value of Type " << original_type.getName() - << " to Type " << getName(); - - if (original_type.getTypeID() == kNullType) { - return nullptr; - } - - DCHECK(equals(original_type) || equals(original_type.getNullableVersion())) - << "Base version of Type::coerceValue() called for a non-trivial " - << "coercion from Type " << original_type.getName() - << " to Type " << getName(); - - return cloneValue(original_value); + // TODO(refactor-type): Implement coerceValue based on CastFunctor. + TypedValue original_tv = original_type.marshallValue(original_value); + TypedValue target_tv = coerceTypedValue(original_tv, original_type); + return unmarshallTypedValue(target_tv); } } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/Type.hpp ---------------------------------------------------------------------- diff --git a/types/Type.hpp b/types/Type.hpp index e5d5528..0929bc7 100644 --- a/types/Type.hpp +++ b/types/Type.hpp @@ -126,6 +126,10 @@ class Type { return type_id_; } + inline MemoryLayout getMemoryLayout() const { + return memory_layout_; + } + /** * @brief Determine whether this Type allows NULL values. * @@ -223,7 +227,7 @@ class Type { * @param original_type The original Type for coercion to this Type. * @return true if coercion is supported, false otherwise. **/ - virtual bool isCoercibleFrom(const Type &original_type) const; + virtual bool isCoercibleFrom(const Type &original_type) const = 0; /** * @brief Determine whether data items of another type can be coerced (used @@ -431,11 +435,13 @@ class Type { protected: Type(const SuperTypeID super_type_id, const TypeID type_id, + const MemoryLayout memory_layout, const bool nullable, const std::size_t minimum_byte_length, const std::size_t maximum_byte_length) : super_type_id_(super_type_id), type_id_(type_id), + memory_layout_(memory_layout), nullable_(nullable), minimum_byte_length_(minimum_byte_length), maximum_byte_length_(maximum_byte_length) { @@ -443,6 +449,7 @@ class Type { const SuperTypeID super_type_id_; const TypeID type_id_; + const MemoryLayout memory_layout_; const bool nullable_; const std::size_t minimum_byte_length_; const std::size_t maximum_byte_length_; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/Type.proto ---------------------------------------------------------------------- diff --git a/types/Type.proto b/types/Type.proto index 8092953..5882b8c 100644 --- a/types/Type.proto +++ b/types/Type.proto @@ -35,6 +35,6 @@ message GenericValue { optional bytes data = 2; } -message ArrayLiteral { +message ArrayLit { repeated bytes data = 1; -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/TypeRegistrar.hpp ---------------------------------------------------------------------- diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp index bb6c40d..d72788b 100644 --- a/types/TypeRegistrar.hpp +++ b/types/TypeRegistrar.hpp @@ -43,13 +43,13 @@ namespace quickstep { class Type; class TypedValue; +class ArrayLit; using UntypedLiteral = void; -using ArrayLiteral = std::vector<UntypedLiteral*>; -using MetaTypeLiteral = const Type*; -using ParInlinePodLiteral = const void*; -using ParOutOfLinePodLiteral = TypedValue; +using MetaTypeLit = const Type*; +using ParInlinePodLit = const void*; +using ParOutOfLinePodLit = TypedValue; template <TypeID type_id> struct TypeIDTrait; @@ -85,15 +85,15 @@ REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval, REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval, SuperTypeID::kOther, kCxxInlinePod, YearMonthIntervalLit); REGISTER_TYPE(CharType, kChar, - SuperTypeID::kAsciiString, kParInlinePod, ParInlinePodLiteral); + SuperTypeID::kAsciiString, kParInlinePod, ParInlinePodLit); REGISTER_TYPE(VarCharType, kVarChar, - SuperTypeID::kAsciiString, kParOutOfLinePod, ParOutOfLinePodLiteral); + SuperTypeID::kAsciiString, kParOutOfLinePod, ParOutOfLinePodLit); REGISTER_TYPE(TextType, kText, SuperTypeID::kOther, kCxxGeneric, std::string); REGISTER_TYPE(ArrayType, kArray, - SuperTypeID::kOther, kCxxGeneric, ArrayLiteral); + SuperTypeID::kOther, kCxxGeneric, ArrayLit); REGISTER_TYPE(MetaType, kMetaType, - SuperTypeID::kOther, kCxxGeneric, MetaTypeLiteral); + SuperTypeID::kOther, kCxxGeneric, MetaTypeLit); REGISTER_TYPE(NullType, kNullType, SuperTypeID::kOther, kCxxInlinePod, NullLit); http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/TypeSynthesizer.hpp ---------------------------------------------------------------------- diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp index d69b1b4..23d072c 100644 --- a/types/TypeSynthesizer.hpp +++ b/types/TypeSynthesizer.hpp @@ -30,12 +30,15 @@ #include <unordered_map> #include <vector> +#include "types/ArrayLit.hpp" #include "types/GenericValue.hpp" #include "types/Type.hpp" #include "types/Type.pb.h" #include "types/TypeID.hpp" #include "types/TypeRegistrar.hpp" #include "types/TypedValue.hpp" +#include "types/operations/utility/CastUtil.hpp" +#include "utility/Cast.hpp" #include "utility/HashPair.hpp" #include "utility/Macros.hpp" #include "utility/meta/Common.hpp" @@ -90,6 +93,8 @@ class TypeSynthesizePolicy< bool checkValuesEqual(const UntypedLiteral *lhs, const UntypedLiteral *rhs, const Type &rhs_type) const override { + DCHECK(lhs != nullptr); + DCHECK(rhs != nullptr); // TODO(refactor-type): Operator == overloading. if (type_id_ != rhs_type.getTypeID()) { return false; @@ -110,15 +115,18 @@ class TypeSynthesizePolicy< } std::size_t hashValue(const UntypedLiteral *value) const override { + DCHECK(value != nullptr); return hashValueInl<sizeof(cpptype)>(value); } TypedValue marshallValue(const UntypedLiteral *value) const override { + DCHECK(value != nullptr); return makeValue(value, sizeof(cpptype)).ensureNotReference(); } UntypedLiteral* unmarshallValue(const void *data, const std::size_t length) const override { + DCHECK(data != nullptr); DCHECK_EQ(sizeof(cpptype), length); UntypedLiteral *value = std::malloc(sizeof(cpptype)); std::memcpy(value, data, sizeof(cpptype)); @@ -127,7 +135,7 @@ class TypeSynthesizePolicy< protected: explicit TypeSynthesizePolicy(const bool nullable) - : Type(Trait::kStaticSuperTypeID, type_id, nullable, + : Type(Trait::kStaticSuperTypeID, type_id, kCxxInlinePod, nullable, sizeof(cpptype), sizeof(cpptype)) {} inline const Type& getInstance(const bool nullable) const { @@ -216,6 +224,7 @@ class TypeSynthesizePolicy< std::size_t hashValue(const UntypedLiteral *value) const override { // TODO(refactor-type): Implementation. + DCHECK(value != nullptr); return TypedValue(type_id_, *static_cast<const cpptype*>(value), maximum_byte_length_).getHash(); @@ -224,6 +233,8 @@ class TypeSynthesizePolicy< bool checkValuesEqual(const UntypedLiteral *lhs, const UntypedLiteral *rhs, const Type &rhs_type) const override { + DCHECK(lhs != nullptr); + DCHECK(rhs != nullptr); if (!equals(rhs_type)) { return false; } @@ -254,6 +265,7 @@ class TypeSynthesizePolicy< UntypedLiteral* unmarshallValue(const void *data, const std::size_t length) const override { + DCHECK(data != nullptr); DCHECK_EQ(maximum_byte_length_, length); void *value = std::malloc(maximum_byte_length_); std::memcpy(value, data, length); @@ -265,7 +277,7 @@ class TypeSynthesizePolicy< const std::size_t minimum_byte_length, const std::size_t maximum_byte_length, const std::size_t length) - : Type(Trait::kStaticSuperTypeID, type_id, nullable, + : Type(Trait::kStaticSuperTypeID, type_id, kParInlinePod, nullable, minimum_byte_length, maximum_byte_length), length_(length) {} @@ -345,6 +357,7 @@ class TypeSynthesizePolicy< std::size_t hashValue(const UntypedLiteral *value) const override { // TODO(refactor-type): Better implementation. + DCHECK(value != nullptr); return static_cast<const TypedValue*>(value)->getHash(); } @@ -368,11 +381,13 @@ class TypeSynthesizePolicy< } TypedValue marshallValue(const UntypedLiteral *value) const override { + DCHECK(value != nullptr); return *static_cast<const TypedValue*>(value); } UntypedLiteral* unmarshallValue(const void *data, const std::size_t length) const override { + DCHECK(data != nullptr); TypedValue *value = new TypedValue(makeValue(data, length)); value->ensureNotReference(); return value; @@ -383,7 +398,7 @@ class TypeSynthesizePolicy< const std::size_t minimum_byte_length, const std::size_t maximum_byte_length, const std::size_t length) - : Type(Trait::kStaticSuperTypeID, type_id, nullable, + : Type(Trait::kStaticSuperTypeID, type_id, kParOutOfLinePod, nullable, minimum_byte_length, maximum_byte_length), length_(length) {} @@ -504,7 +519,7 @@ class TypeSynthesizePolicy< const std::size_t minimum_byte_length, const std::size_t maximum_byte_length, const std::vector<GenericValue> ¶meters) - : Type(Trait::kStaticSuperTypeID, type_id, nullable, + : Type(Trait::kStaticSuperTypeID, type_id, kCxxGeneric, nullable, minimum_byte_length, maximum_byte_length), parameters_(parameters) {} @@ -619,6 +634,11 @@ class TypeSynthesizer : public TypeSynthesizePolicy<type_id> { return SynthesizePolicy::getInstance(false); } + bool isCoercibleFrom(const Type &original_type) const override { + auto it = kCoercibleSourceTypeIDs.find(original_type.getTypeID()); + return it != kCoercibleSourceTypeIDs.end(); + }; + UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override { return SynthesizePolicy::unmarshallTypedValueInl(value); } @@ -680,6 +700,8 @@ class TypeSynthesizer : public TypeSynthesizePolicy<type_id> { private: template <TypeID, typename> friend class TypeSynthesizePolicy; + static const std::unordered_set<TypeID> kCoercibleSourceTypeIDs; + DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer); }; @@ -695,6 +717,10 @@ constexpr bool TypeSynthesizer<type_id>::kIsParPod; template <TypeID type_id> constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout; +template <TypeID type_id> +const std::unordered_set<TypeID> TypeSynthesizer<type_id>::kCoercibleSourceTypeIDs = + CastSTLContainer<std::unordered_set<TypeID>>( + CastUtil::GetCoercibleSourceTypeIDs(type_id)); #define QUICKSTEP_SYNTHESIZE_TYPE(type) \ template <TypeID, typename> friend class TypeSynthesizePolicy; \ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/VarCharType.hpp ---------------------------------------------------------------------- diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp index 0b16061..639d0fb 100644 --- a/types/VarCharType.hpp +++ b/types/VarCharType.hpp @@ -43,7 +43,7 @@ namespace quickstep { * character. This means that the VARCHAR(X) type requires from 1 to X+1 * bytes of storage, depending on string length. **/ -class VarCharType : public AsciiStringSuperType<kVarChar> { +class VarCharType final : public AsciiStringSuperType<kVarChar> { public: /** * @note Includes an extra byte for a terminating null character. http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/YearMonthIntervalType.hpp ---------------------------------------------------------------------- diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp index ee1eb97..c729411 100644 --- a/types/YearMonthIntervalType.hpp +++ b/types/YearMonthIntervalType.hpp @@ -40,7 +40,7 @@ namespace quickstep { /** * @brief A type representing the year-month interval. **/ -class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> { +class YearMonthIntervalType final : public TypeSynthesizer<kYearMonthInterval> { public: int getPrintWidth() const override { return YearMonthIntervalLit::kPrintingChars; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/containers/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/types/containers/CMakeLists.txt b/types/containers/CMakeLists.txt index 97841c2..675805a 100644 --- a/types/containers/CMakeLists.txt +++ b/types/containers/CMakeLists.txt @@ -29,6 +29,7 @@ add_library(quickstep_types_containers_Tuple_proto ${types_containers_Tuple_prot target_link_libraries(quickstep_types_containers_ColumnVector glog quickstep_types_Type + quickstep_types_TypeRegistrar quickstep_types_TypedValue quickstep_utility_BitVector quickstep_utility_Macros) http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/containers/ColumnVector.cpp ---------------------------------------------------------------------- diff --git a/types/containers/ColumnVector.cpp b/types/containers/ColumnVector.cpp index ef3587e..476accc 100644 --- a/types/containers/ColumnVector.cpp +++ b/types/containers/ColumnVector.cpp @@ -21,6 +21,12 @@ #include <cstddef> +#include "types/TypeID.hpp" +#include "types/TypeUtil.hpp" +#include "types/TypeRegistrar.hpp" +#include "types/TypeIDSelectors.hpp" +#include "utility/Macros.hpp" + namespace quickstep { class Type; @@ -30,19 +36,36 @@ ColumnVector* ColumnVector::MakeVectorOfValue( const Type &value_type, const TypedValue &value, const std::size_t num_copies) { - if (NativeColumnVector::UsableForType(value_type)) { - NativeColumnVector *result = new NativeColumnVector(value_type, num_copies); - result->fillWithValue(value); - return result; - } else { - IndirectColumnVector *result = new IndirectColumnVector(value_type, num_copies); - result->fillWithValue(value); - return result; + switch (value_type.getMemoryLayout()) { + case kCxxInlinePod: // Fall through + case kParInlinePod: { + NativeColumnVector *result = new NativeColumnVector(value_type, num_copies); + result->fillWithValue(value); + return result; + } + case kParOutOfLinePod: { + IndirectColumnVector *result = new IndirectColumnVector(value_type, num_copies); + result->fillWithValue(value); + return result; + } + case kCxxGeneric: { + // TODO(refactor-type): Omit non-supported types. + return InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxGeneric>>( + value_type.getTypeID(), + [&](auto tid) -> ColumnVector* { + using TypeClass = typename TypeIDTrait<decltype(tid)::value>::TypeClass; + GenericColumnVector<TypeClass> *result = + new GenericColumnVector<TypeClass>(value_type, num_copies); + result->fillWithValue(value); + return result; + }); + } } + QUICKSTEP_UNREACHABLE(); } -constexpr bool NativeColumnVector::kNative; +constexpr ColumnVector::Implementation NativeColumnVector::kImplementation; -constexpr bool IndirectColumnVector::kNative; +constexpr ColumnVector::Implementation IndirectColumnVector::kImplementation; } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/containers/ColumnVector.hpp ---------------------------------------------------------------------- diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp index d524ff5..18b8b86 100644 --- a/types/containers/ColumnVector.hpp +++ b/types/containers/ColumnVector.hpp @@ -28,6 +28,7 @@ #include <vector> #include "types/Type.hpp" +#include "types/TypeRegistrar.hpp" #include "types/TypedValue.hpp" #include "utility/BitVector.hpp" #include "utility/Macros.hpp" @@ -123,18 +124,6 @@ class ColumnVector { return implementation_; } - inline bool isNative() const { - return implementation_ == kNative; - } - - inline bool isIndrect() const { - return implementation_ == kIndirect; - } - - inline bool isGeneric() const { - return implementation_ == kGeneric; - } - /** * @brief Get the number of values in this ColumnVector. * @@ -142,6 +131,10 @@ class ColumnVector { **/ virtual std::size_t size() const = 0; + virtual TypedValue getTypedValueVirtual(const std::size_t position) const { + LOG(FATAL) << "Unexpected call to ColumnVector::getTypedValueVirtual()"; + } + protected: const Implementation implementation_; const Type &type_; @@ -155,7 +148,7 @@ class ColumnVector { **/ class NativeColumnVector : public ColumnVector { public: - static constexpr bool kNative = true; + static constexpr Implementation kImplementation = ColumnVector::kNative; /** * @brief Constructor for a NativeColumnVector which owns its own array of @@ -166,16 +159,13 @@ class NativeColumnVector : public ColumnVector { * NativeColumnVector will hold. **/ NativeColumnVector(const Type &type, const std::size_t reserved_length) - : ColumnVector(ColumnVector::kNative, type), + : ColumnVector(kImplementation, type), type_length_(type.maximumByteLength()), reserved_length_(reserved_length), values_(std::malloc(type.maximumByteLength() * reserved_length)), actual_length_(0u), null_bitmap_(type.isNullable() ? new BitVector<false>(reserved_length) : nullptr) { DCHECK(UsableForType(type_)); - if (null_bitmap_) { - null_bitmap_->clear(); - } } /** @@ -193,7 +183,8 @@ class NativeColumnVector : public ColumnVector { * IndirectColumnVector must be used instead. **/ static bool UsableForType(const Type &type) { - return !type.isVariableLength(); + return type.getMemoryLayout() == kCxxInlinePod || + type.getMemoryLayout() == kParInlinePod; } /** @@ -437,7 +428,7 @@ class NativeColumnVector : public ColumnVector { **/ class IndirectColumnVector : public ColumnVector { public: - static constexpr bool kNative = false; + static constexpr Implementation kImplementation = ColumnVector::kIndirect; /** * @brief Constructor. @@ -446,7 +437,7 @@ class IndirectColumnVector : public ColumnVector { * @param reserved_length The number of values to reserve space for. **/ IndirectColumnVector(const Type &type, const std::size_t reserved_length) - : ColumnVector(ColumnVector::kIndirect, type), + : ColumnVector(kImplementation, type), type_is_nullable_(type.isNullable()), reserved_length_(reserved_length) { values_.reserve(reserved_length); @@ -616,11 +607,102 @@ class IndirectColumnVector : public ColumnVector { DISALLOW_COPY_AND_ASSIGN(IndirectColumnVector); }; -class GenericColumnVector { +template <typename TypeClass> +class GenericColumnVector : public ColumnVector { + public: + static constexpr Implementation kImplementation = ColumnVector::kGeneric; + + using cpptype = typename TypeClass::cpptype; + + GenericColumnVector(const Type &type, const std::size_t reserved_length) + : ColumnVector(kImplementation, type), + type_(static_cast<const TypeClass&>(type)), + reserved_length_(reserved_length) { + DCHECK(TypeClass::kStaticTypeID == type.getTypeID()); + values_.reserve(reserved_length_); + if (type.isNullable()) { + null_bitmap_ = std::make_unique<BitVector<false>>(reserved_length_); + } + } + + static bool UsableForType(const Type &type) { + return type.getMemoryLayout() == kCxxGeneric; + } + + inline bool typeIsNullable() const { + return null_bitmap_.get() != nullptr; + } + inline std::size_t size() const override { + return values_.size(); + } + template <bool check_null = true> + inline cpptype& getLiteralValue(const std::size_t position) const { + DCHECK_LT(position, values_.size()); + return (check_null && null_bitmap_ && null_bitmap_->getBit(position)) + ? nullptr + : values_[position]; + } + + TypedValue getTypedValueVirtual(const std::size_t position) const override { + return getTypedValue(position); + } + + inline TypedValue getTypedValue(const std::size_t position) const { + DCHECK_LT(position, values_.size()); + // TODO(refactor-type): Implement marshallValueMaybeReference() to improve performance. + return (null_bitmap_ && null_bitmap_->getBit(position)) + ? type_.makeNullValue() + : type_.marshallValue(&values_[position]); + } + + inline void appendNullValue() { + DCHECK_LT(values_.size(), reserved_length_); + DCHECK(null_bitmap_); + null_bitmap_->setBit(values_.size(), true); + // TODO(refactor-type): Specialize nullable GenericColumnVector. + LOG(FATAL) << "Not implemented"; + } + + inline void fillWithNulls() { + DCHECK(null_bitmap_); + null_bitmap_->setBitRange(0, reserved_length_, true); + // TODO(refactor-type): Specialize nullable GenericColumnVector. + LOG(FATAL) << "Not implemented"; + } + + inline void fillWithValue(const TypedValue &value) { + std::unique_ptr<cpptype> cppvalue = std::unique_ptr<cpptype>( + static_cast<cpptype*>(type_.unmarshallTypedValue(value))); + for (std::size_t i = 0; i < reserved_length_; ++i) { + values_.emplace_back(*cppvalue); + } + } + + inline void appendLiteralValue(const cpptype &value) { + DCHECK_LT(values_.size(), reserved_length_); + values_.emplace_back(value); + } + + inline void appendLiteralValue(cpptype &&value) { + DCHECK_LT(values_.size(), reserved_length_); + values_.emplace_back(std::move(value)); + } + + private: + const TypeClass &type_; + const std::size_t reserved_length_; + + std::vector<cpptype> values_; + std::unique_ptr<BitVector<false>> null_bitmap_; + + DISALLOW_COPY_AND_ASSIGN(GenericColumnVector); }; +template <typename TypeClass> +constexpr ColumnVector::Implementation GenericColumnVector<TypeClass>::kImplementation; + /** @} */ } // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/containers/ColumnVectorUtil.hpp ---------------------------------------------------------------------- diff --git a/types/containers/ColumnVectorUtil.hpp b/types/containers/ColumnVectorUtil.hpp index 5a560a4..e241a21 100644 --- a/types/containers/ColumnVectorUtil.hpp +++ b/types/containers/ColumnVectorUtil.hpp @@ -22,6 +22,8 @@ #include "types/containers/ColumnVector.hpp" +#include "glog/logging.h" + namespace quickstep { /** \addtogroup Types @@ -43,9 +45,11 @@ namespace quickstep { template <typename FunctorT> auto InvokeOnColumnVector(const ColumnVector &column_vector, const FunctorT &functor) { - if (column_vector.isNative()) { + // TODO(refactor-type): + if (column_vector.getImplementation() == ColumnVector::kNative) { return functor(static_cast<const NativeColumnVector&>(column_vector)); } else { + DCHECK(column_vector.getImplementation() == ColumnVector::kIndirect); return functor(static_cast<const IndirectColumnVector&>(column_vector)); } } http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/containers/ColumnVectorsValueAccessor.hpp ---------------------------------------------------------------------- diff --git a/types/containers/ColumnVectorsValueAccessor.hpp b/types/containers/ColumnVectorsValueAccessor.hpp index 0ea6d50..bec232f 100644 --- a/types/containers/ColumnVectorsValueAccessor.hpp +++ b/types/containers/ColumnVectorsValueAccessor.hpp @@ -38,6 +38,7 @@ namespace quickstep { class TupleIdSequence; +typedef void UntypedLiteral; /** * @brief Implementation of ValueAccessor as a group of equal-length @@ -77,9 +78,8 @@ class ColumnVectorsValueAccessor : public ValueAccessor { // If this is not the first column to be added, make sure it is the same // length as the others. DCHECK(columns_.empty() || column->size() == column_length_); - DCHECK(column->isNative() || column->isIndrect()); - columns_.push_back(column); - column_native_.push_back(column->isNative()); + columns_.emplace_back(column); + column_impl_.emplace_back(column->getImplementation()); column_length_ = column->size(); } @@ -152,10 +152,15 @@ class ColumnVectorsValueAccessor : public ValueAccessor { const tuple_id tid) const { DCHECK(attributeIdInRange(attr_id)); DCHECK(tupleIdInRange(tid)); - if (column_native_[attr_id]) { - return static_cast<const NativeColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid); - } else { - return static_cast<const IndirectColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid); + // TODO(jianqiao): Implement specialized column accessors to improve performance. + switch (column_impl_[attr_id]) { + case ColumnVector::kNative: + return static_cast<const NativeColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid); + case ColumnVector::kIndirect: + return static_cast<const IndirectColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid); + default: + LOG(FATAL) << "Can not apply getUntypedValueAtAbsolutionPosition() to " + << "GenericColumnVector"; } } @@ -163,14 +168,18 @@ class ColumnVectorsValueAccessor : public ValueAccessor { const tuple_id tid) const { DCHECK(attributeIdInRange(attr_id)); DCHECK(tupleIdInRange(tid)); - if (column_native_[attr_id]) { - return static_cast<const NativeColumnVector&>(*columns_[attr_id]) - .getTypedValue(tid) - .makeReferenceToThis(); - } else { - return static_cast<const IndirectColumnVector&>(*columns_[attr_id]) - .getTypedValue(tid) - .makeReferenceToThis(); + // TODO(jianqiao): Implement specialized column accessors to improve performance. + switch (column_impl_[attr_id]) { + case ColumnVector::kNative: + return static_cast<const NativeColumnVector&>(*columns_[attr_id]) + .getTypedValue(tid) + .makeReferenceToThis(); + case ColumnVector::kIndirect: + return static_cast<const IndirectColumnVector&>(*columns_[attr_id]) + .getTypedValue(tid) + .makeReferenceToThis(); + case ColumnVector::kGeneric: + return columns_[attr_id]->getTypedValueVirtual(tid); } } @@ -305,7 +314,7 @@ class ColumnVectorsValueAccessor : public ValueAccessor { } std::vector<ColumnVectorPtr> columns_; - std::vector<bool> column_native_; + std::vector<ColumnVector::Implementation> column_impl_; std::size_t column_length_; std::size_t current_position_; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/477c385d/types/operations/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/types/operations/CMakeLists.txt b/types/operations/CMakeLists.txt index caf5f72..1e622dd 100644 --- a/types/operations/CMakeLists.txt +++ b/types/operations/CMakeLists.txt @@ -39,13 +39,12 @@ target_link_libraries(quickstep_types_operations_OperationFactory quickstep_types_TypeFactory quickstep_types_TypeID quickstep_types_TypeUtil - quickstep_types_TypedValue quickstep_types_operations_Operation quickstep_types_operations_OperationSignature quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctors quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors quickstep_types_operations_binaryoperations_BinaryOperation - quickstep_types_operations_binaryoperations_BinaryOperationWrapper + quickstep_types_operations_binaryoperations_BinaryOperationSynthesizer quickstep_types_operations_binaryoperations_CMathBinaryFunctors quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors @@ -54,7 +53,7 @@ target_link_libraries(quickstep_types_operations_OperationFactory quickstep_types_operations_unaryoperations_DateExtractOperation quickstep_types_operations_unaryoperations_SubstringOperation quickstep_types_operations_unaryoperations_UnaryOperation - quickstep_types_operations_unaryoperations_UnaryOperationWrapper + quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer quickstep_utility_HashPair quickstep_utility_Macros quickstep_utility_StringUtil)
