You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2017/03/14 14:55:29 UTC
[6/8] incubator-quickstep git commit: Updates
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index 18a3aa0..02f090e 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -185,7 +185,7 @@ extern int quickstep_yydebug;
union YYSTYPE
{
-#line 117 "../SqlParser.ypp" /* yacc.c:1915 */
+#line 114 "../SqlParser.ypp" /* yacc.c:1915 */
quickstep::ParseString *string_value_;
@@ -257,7 +257,7 @@ union YYSTYPE
const quickstep::Comparison *comparison_;
quickstep::ParseString *unary_operation_;
- const quickstep::BinaryOperation *binary_operation_;
+ quickstep::ParseString *binary_operation_;
quickstep::ParseFunctionCall *function_call_;
quickstep::PtrList<quickstep::ParseExpression> *expression_list_;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/LogicalGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/LogicalGenerator.cpp b/query_optimizer/LogicalGenerator.cpp
index 49481d3..940b728 100644
--- a/query_optimizer/LogicalGenerator.cpp
+++ b/query_optimizer/LogicalGenerator.cpp
@@ -51,7 +51,8 @@ L::LogicalPtr LogicalGenerator::generatePlan(
const CatalogDatabase &catalog_database,
const ParseStatement &parse_statement) {
resolver::Resolver resolver(catalog_database, optimizer_context_);
- DVLOG(4) << "Parse tree:\n" << parse_statement.toString();
+// DVLOG(4) << "Parse tree:\n" << parse_statement.toString();
+ std::cerr << "Parse tree:\n" << parse_statement.toString();
logical_plan_ = resolver.resolve(parse_statement);
std::cerr << "Initial logical plan:\n" << logical_plan_->toString();
// exit(0);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/expressions/BinaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/BinaryExpression.cpp b/query_optimizer/expressions/BinaryExpression.cpp
index 446dd55..2178e2e 100644
--- a/query_optimizer/expressions/BinaryExpression.cpp
+++ b/query_optimizer/expressions/BinaryExpression.cpp
@@ -29,8 +29,8 @@
#include "query_optimizer/expressions/ExprId.hpp"
#include "query_optimizer/expressions/Expression.hpp"
#include "query_optimizer/expressions/PatternMatcher.hpp"
+#include "query_optimizer/expressions/ScalarLiteral.hpp"
#include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
#include "glog/logging.h"
@@ -41,37 +41,8 @@ class Type;
namespace optimizer {
namespace expressions {
-BinaryExpression::BinaryExpression(const BinaryOperation &operation,
- const ScalarPtr &left,
- const ScalarPtr &right)
- : operation_(operation), left_(left), right_(right) {
- DCHECK(operation_.canApplyToTypes(left_->getValueType(),
- right_->getValueType()))
- << toString();
- addChild(left_);
- addChild(right_);
-}
-
std::string BinaryExpression::getName() const {
- switch (operation_.getBinaryOperationID()) {
- case BinaryOperationID::kAdd:
- return "Add";
- case BinaryOperationID::kSubtract:
- return "Subtract";
- case BinaryOperationID::kMultiply:
- return "Multiply";
- case BinaryOperationID::kDivide:
- return "Divide";
- case BinaryOperationID::kModulo:
- return "Modulo";
- default:
- LOG(FATAL) << "Unknown binary operation";
- }
-}
-
-const Type &BinaryExpression::getValueType() const {
- return *operation_.resultTypeForArgumentTypes(left_->getValueType(),
- right_->getValueType());
+ return op_signature_->getName();
}
ExpressionPtr BinaryExpression::copyWithNewChildren(
@@ -80,9 +51,12 @@ ExpressionPtr BinaryExpression::copyWithNewChildren(
DCHECK(SomeScalar::Matches(new_children[0]));
DCHECK(SomeScalar::Matches(new_children[1]));
return BinaryExpression::Create(
+ op_signature_,
operation_,
std::static_pointer_cast<const Scalar>(new_children[0]),
- std::static_pointer_cast<const Scalar>(new_children[1]));
+ std::static_pointer_cast<const Scalar>(new_children[1]),
+ static_arguments_,
+ static_argument_types_);
}
std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() const {
@@ -99,9 +73,11 @@ std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() c
::quickstep::Scalar *BinaryExpression::concretize(
const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
return new ::quickstep::ScalarBinaryExpression(
+ op_signature_,
operation_,
left_->concretize(substitution_map),
- right_->concretize(substitution_map));
+ right_->concretize(substitution_map),
+ static_arguments_);
}
void BinaryExpression::getFieldStringItems(
@@ -111,8 +87,26 @@ void BinaryExpression::getFieldStringItems(
std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
std::vector<std::string> *container_child_field_names,
std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
- container_child_field_names->push_back("");
- container_child_fields->push_back({left_, right_});
+ inline_field_names->emplace_back("op_signature");
+ inline_field_values->emplace_back(op_signature_->toString());
+
+ inline_field_names->emplace_back("result_type");
+ inline_field_values->emplace_back(result_type_.getName());
+
+ non_container_child_field_names->emplace_back("left_operand");
+ non_container_child_fields->emplace_back(left_);
+ non_container_child_field_names->emplace_back("right_operand");
+ non_container_child_fields->emplace_back(right_);
+
+ if (!static_arguments_->empty()) {
+ container_child_field_names->emplace_back("static_arguments");
+ 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)));
+ }
+ }
}
} // namespace expressions
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/expressions/BinaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/BinaryExpression.hpp b/query_optimizer/expressions/BinaryExpression.hpp
index 9b11ed1..9692dff 100644
--- a/query_optimizer/expressions/BinaryExpression.hpp
+++ b/query_optimizer/expressions/BinaryExpression.hpp
@@ -31,6 +31,8 @@
#include "query_optimizer/expressions/Expression.hpp"
#include "query_optimizer/expressions/ExpressionType.hpp"
#include "query_optimizer/expressions/Scalar.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/binary_operations/BinaryOperation.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
@@ -61,7 +63,9 @@ class BinaryExpression : public Scalar {
std::string getName() const override;
- const Type& getValueType() const override;
+ const Type& getValueType() const override {
+ return result_type_;
+ }
bool isConstant() const override {
return left_->isConstant() && right_->isConstant();
@@ -70,7 +74,7 @@ class BinaryExpression : public Scalar {
/**
* @return The binary operation.
*/
- const BinaryOperation& operation() const { return operation_; }
+ const BinaryOperationPtr& operation() const { return operation_; }
/**
* @return The left operand.
@@ -90,10 +94,20 @@ class BinaryExpression : public Scalar {
::quickstep::Scalar* concretize(
const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const override;
- static BinaryExpressionPtr Create(const BinaryOperation &operation,
- const ScalarPtr &left,
- const ScalarPtr &right) {
- return BinaryExpressionPtr(new BinaryExpression(operation, left, right));
+ static BinaryExpressionPtr Create(
+ const OperationSignaturePtr &op_signature,
+ 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) {
+ return BinaryExpressionPtr(
+ new BinaryExpression(op_signature,
+ operation,
+ left,
+ right,
+ static_arguments,
+ static_argument_types));
}
protected:
@@ -106,14 +120,32 @@ class BinaryExpression : public Scalar {
std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
private:
- BinaryExpression(const BinaryOperation &operation,
+ BinaryExpression(const OperationSignaturePtr &op_signature,
+ const BinaryOperationPtr &operation,
const ScalarPtr &left,
- const ScalarPtr &right);
-
- const BinaryOperation &operation_;
+ 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)
+ : op_signature_(op_signature),
+ operation_(operation),
+ left_(left),
+ right_(right),
+ static_arguments_(static_arguments),
+ static_argument_types_(static_argument_types),
+ result_type_(*(operation_->getResultType(left_->getValueType(),
+ right_->getValueType(),
+ *static_arguments))) {
+ addChild(left);
+ addChild(right);
+ }
- ScalarPtr left_;
- ScalarPtr right_;
+ const OperationSignaturePtr op_signature_;
+ 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 Type &result_type_;
DISALLOW_COPY_AND_ASSIGN(BinaryExpression);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index d7ce686..086636c 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -89,8 +89,9 @@ target_link_libraries(quickstep_queryoptimizer_expressions_BinaryExpression
quickstep_queryoptimizer_expressions_ExpressionType
quickstep_queryoptimizer_expressions_PatternMatcher
quickstep_queryoptimizer_expressions_Scalar
+ quickstep_queryoptimizer_expressions_ScalarLiteral
+ quickstep_types_operations_OperationSignature
quickstep_types_operations_binaryoperations_BinaryOperation
- quickstep_types_operations_binaryoperations_BinaryOperationID
quickstep_utility_Macros)
target_link_libraries(quickstep_queryoptimizer_expressions_Cast
glog
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/expressions/UnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.cpp b/query_optimizer/expressions/UnaryExpression.cpp
index d7bde71..6780802 100644
--- a/query_optimizer/expressions/UnaryExpression.cpp
+++ b/query_optimizer/expressions/UnaryExpression.cpp
@@ -39,7 +39,7 @@ namespace optimizer {
namespace expressions {
std::string UnaryExpression::getName() const {
- return operation_->getName();
+ return op_signature_->getName();
}
ExpressionPtr UnaryExpression::copyWithNewChildren(
@@ -73,6 +73,9 @@ void UnaryExpression::getFieldStringItems(
inline_field_names->emplace_back("op_signature");
inline_field_values->emplace_back(op_signature_->toString());
+ inline_field_names->emplace_back("result_type");
+ inline_field_values->emplace_back(result_type_.getName());
+
non_container_child_field_names->emplace_back("operand");
non_container_child_fields->emplace_back(operand_);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/expressions/UnaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.hpp b/query_optimizer/expressions/UnaryExpression.hpp
index c08519f..e742990 100644
--- a/query_optimizer/expressions/UnaryExpression.hpp
+++ b/query_optimizer/expressions/UnaryExpression.hpp
@@ -129,7 +129,6 @@ class UnaryExpression : public Scalar {
static_arguments_(static_arguments),
static_argument_types_(static_argument_types),
result_type_(*(operation_->getResultType(operand_->getValueType(), *static_arguments_))) {
- DCHECK(operation_->canApplyTo(operand_->getValueType(), *static_arguments)) << toString();
addChild(operand);
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/resolver/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index 27497a2..be33972 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -124,13 +124,13 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
quickstep_types_TypeUtil
quickstep_types_TypedValue
quickstep_types_TypeFactory
+ quickstep_types_operations_OperationFactory
quickstep_types_operations_OperationSignature
quickstep_types_operations_binaryoperations_BinaryOperation
quickstep_types_operations_comparisons_Comparison
quickstep_types_operations_comparisons_ComparisonFactory
quickstep_types_operations_comparisons_ComparisonID
quickstep_types_operations_unaryoperations_UnaryOperation
- quickstep_types_operations_unaryoperations_UnaryOperationFactory
quickstep_utility_Macros
quickstep_utility_PtrList
quickstep_utility_PtrVector
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 1741409..892c183 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -22,6 +22,7 @@
#include <algorithm>
#include <map>
#include <memory>
+#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -118,13 +119,13 @@
#include "types/TypeFactory.hpp"
#include "types/TypeUtil.hpp"
#include "types/TypedValue.hpp"
+#include "types/operations/OperationFactory.hpp"
#include "types/operations/OperationSignature.hpp"
#include "types/operations/binary_operations/BinaryOperation.hpp"
#include "types/operations/comparisons/Comparison.hpp"
#include "types/operations/comparisons/ComparisonFactory.hpp"
#include "types/operations/comparisons/ComparisonID.hpp"
#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationFactory.hpp"
#include "utility/PtrList.hpp"
#include "utility/PtrVector.hpp"
#include "utility/SqlError.hpp"
@@ -2120,109 +2121,6 @@ E::ScalarPtr Resolver::resolveExpression(
parse_attribute_scalar.attr_name(),
parse_attribute_scalar.rel_name());
}
- case ParseExpression::kBinaryExpression: {
- const ParseBinaryExpression &parse_binary_scalar =
- static_cast<const ParseBinaryExpression&>(parse_expression);
-
- std::pair<const Type*, const Type*> argument_type_hints
- = parse_binary_scalar.op().pushDownTypeHint(type_hint);
-
- ExpressionResolutionInfo left_resolution_info(
- *expression_resolution_info);
- E::ScalarPtr left_argument = resolveExpression(
- *parse_binary_scalar.left_operand(),
- argument_type_hints.first,
- &left_resolution_info);
-
- ExpressionResolutionInfo right_resolution_info(
- *expression_resolution_info);
- E::ScalarPtr right_argument = resolveExpression(
- *parse_binary_scalar.right_operand(),
- argument_type_hints.second,
- &right_resolution_info);
-
- if (left_resolution_info.hasAggregate()) {
- expression_resolution_info->parse_aggregate_expression =
- left_resolution_info.parse_aggregate_expression;
- } else if (right_resolution_info.hasAggregate()) {
- expression_resolution_info->parse_aggregate_expression =
- right_resolution_info.parse_aggregate_expression;
- }
-
- // Check if either argument is a NULL literal of an unknown type.
- const bool left_is_nulltype = (left_argument->getValueType().getTypeID() == kNullType);
- const bool right_is_nulltype = (right_argument->getValueType().getTypeID() == kNullType);
-
- // If either argument is a NULL of unknown type, we try to resolve the
- // type of this BinaryExpression as follows:
- //
- // 1. If there is only one possible result type for the expression
- // based on what is known about its argument types, then the
- // result is a NULL of that type.
- // 2. Otherwise, if there is a type hint for the BinaryExpression's
- // result, and if it is a plausible result type based on what we
- // know about argument types, then the result is a NULL of the
- // hint type.
- // 3. Otherwise, check if the BinaryExpression can plausibly be
- // applied to the known argument types at all. If so, then the
- // result is a NULL of unknown type (i.e. NullType).
- // 4. If all of the above steps fail, then the BinaryExpression is
- // not possibly applicable to the given arguments.
- //
- // NOTE(chasseur): Step #3 above does not completely capture knowledge
- // about the result type of a BinaryExpression with one or more unknown
- // arguments. For instance, DivideBinaryOperation can never return a
- // DateTime or any string type, so even if we do not know its specific
- // return type, we do know that there are some restrictions on what it
- // may be. However, NullType is implicitly convertable to ANY Type, so
- // such restrictions could be violated if a parent node in the expression
- // tree converts a value of NullType to something that it shouldn't be.
- if (left_is_nulltype || right_is_nulltype) {
- const Type *fixed_result_type
- = parse_binary_scalar.op().resultTypeForPartialArgumentTypes(
- left_is_nulltype ? nullptr : &(left_argument->getValueType()),
- right_is_nulltype ? nullptr : &(right_argument->getValueType()));
- if (fixed_result_type != nullptr) {
- return E::ScalarLiteral::Create(fixed_result_type->makeNullValue(),
- *fixed_result_type);
- }
-
- if (type_hint != nullptr) {
- const Type &nullable_type_hint = type_hint->getNullableVersion();
- if (parse_binary_scalar.op().partialTypeSignatureIsPlausible(
- &nullable_type_hint,
- left_is_nulltype ? nullptr : &(left_argument->getValueType()),
- right_is_nulltype ? nullptr : &(right_argument->getValueType()))) {
- return E::ScalarLiteral::Create(nullable_type_hint.makeNullValue(),
- nullable_type_hint);
- }
- }
-
- if (parse_binary_scalar.op().partialTypeSignatureIsPlausible(
- nullptr,
- left_is_nulltype ? nullptr : &(left_argument->getValueType()),
- right_is_nulltype ? nullptr : &(right_argument->getValueType()))) {
- const Type &null_type = TypeFactory::GetType(kNullType, true);
- return E::ScalarLiteral::Create(null_type.makeNullValue(),
- null_type);
- }
-
- // If nothing above worked, fall through to canApplyToTypes() below,
- // which should fail.
- }
-
- if (!parse_binary_scalar.op().canApplyToTypes(left_argument->getValueType(),
- right_argument->getValueType())) {
- THROW_SQL_ERROR_AT(&parse_binary_scalar)
- << "Can not apply binary operation \"" << parse_binary_scalar.op().getName()
- << "\" to arguments of types " << left_argument->getValueType().getName()
- << " and " << right_argument->getValueType().getName();
- }
-
- return E::BinaryExpression::Create(parse_binary_scalar.op(),
- left_argument,
- right_argument);
- }
case ParseExpression::kScalarLiteral: {
const ParseScalarLiteral &parse_literal_scalar =
static_cast<const ParseScalarLiteral&>(parse_expression);
@@ -2525,118 +2423,77 @@ E::ScalarPtr Resolver::resolveScalarFunction(
const std::vector<E::ScalarPtr> &resolved_arguments,
ExpressionResolutionInfo *expression_resolution_info) {
const std::size_t arity = resolved_arguments.size();
-
std::vector<const Type*> argument_types;
- std::vector<TypeID> argument_type_ids;
std::size_t first_static_argument_position = 0;
for (std::size_t i = 0; i < arity; ++i) {
const E::ScalarPtr &argument = resolved_arguments[i];
if (argument->getExpressionType() != E::ExpressionType::kScalarLiteral) {
first_static_argument_position = i + 1;
}
-
- const Type &type = argument->getValueType();
- argument_types.emplace_back(&type);
- argument_type_ids.emplace_back(type.getTypeID());
+ argument_types.emplace_back(&argument->getValueType());
}
- std::vector<TypedValue> maximal_static_arguments;
+ std::vector<TypedValue> static_arguments;
for (std::size_t i = first_static_argument_position; i < arity; ++i) {
- maximal_static_arguments.emplace_back(
+ static_arguments.emplace_back(
std::static_pointer_cast<const E::ScalarLiteral>(
resolved_arguments[i])->value());
- DCHECK(maximal_static_arguments.back().getTypeID() == argument_type_ids[i]);
- }
- const std::size_t max_num_static_arguments = maximal_static_arguments.size();
-
- const UnaryOperationFactory &factory = UnaryOperationFactory::Instance();
-
- // First, check exact matching of name + non static types, possibly safe
- // coercion of static arguments.
- const auto &op_sig_candidates = factory.getUnaryOperations(function_name, arity);
- for (const OperationSignaturePtr &op_sig : op_sig_candidates) {
- const std::size_t op_num_static_arguments = op_sig->getNumStaticArguments();
- if (op_num_static_arguments > max_num_static_arguments) {
- continue;
- }
-
- bool is_match = true;
- for (std::size_t i = 0; i < arity - op_num_static_arguments; ++i) {
- if (op_sig->getArgumentTypeIDs().at(i) != argument_type_ids[i]) {
- is_match = false;
- break;
- }
- }
- if (!is_match) {
- continue;
- }
-
- std::vector<TypedValue> coerced_static_arguments;
- std::vector<const Type*> coerced_static_argument_types;
- bool is_coercible = true;
- for (std::size_t i = arity - op_num_static_arguments; i < arity; ++i) {
- const Type &arg_type = *argument_types.at(i);
- const TypedValue &arg_value =
- maximal_static_arguments.at(i - first_static_argument_position);
- const TypeID expected_type_id = op_sig->getArgumentTypeIDs().at(i);
- if (arg_type.getTypeID() == expected_type_id) {
- coerced_static_arguments.emplace_back(arg_value);
- coerced_static_argument_types.emplace_back(&arg_type);
- } else {
- const Type *expected_type = nullptr;
- if (TypeUtil::IsParameterized(expected_type_id)) {
- // TODO: refactor type system to make this coercion extensible.
- if (expected_type_id == kChar && arg_type.getTypeID() == kVarChar) {
- expected_type = &TypeFactory::GetType(
- expected_type_id, arg_type.maximumByteLength() - 1);
- } else if (expected_type_id == kVarChar && arg_type.getTypeID() == kChar) {
- expected_type = &TypeFactory::GetType(
- expected_type_id, arg_type.maximumByteLength() + 1);
- }
- } else {
- expected_type = &TypeFactory::GetType(expected_type_id);
- }
- if (expected_type != nullptr && expected_type->isSafelyCoercibleFrom(arg_type)) {
- coerced_static_arguments.emplace_back(
- expected_type->coerceValue(arg_value, arg_type));
- coerced_static_argument_types.emplace_back(expected_type);
- } else {
- is_coercible = false;
- break;
- }
- }
- }
- if (!is_coercible) {
- continue;
- }
-
- // TODO: switch on operation non-static arity here.
- CHECK_EQ(1u, arity - op_num_static_arguments);
-
- const UnaryOperationPtr op = factory.getUnaryOperation(op_sig);
- const auto static_arguments =
- std::make_shared<const std::vector<TypedValue>>(
- std::move(coerced_static_arguments));
- const auto static_argument_types =
- std::make_shared<const std::vector<const Type*>>(
- std::move(coerced_static_argument_types));
-
- std::string message;
- if (op->canApplyTo(*argument_types.front(), *static_arguments, &message)) {
- return E::UnaryExpression::Create(op_sig,
- op,
- resolved_arguments.front(),
- static_arguments,
- static_argument_types);
- } else {
+ DCHECK(static_arguments.back().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::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)),
+ &coerced_argument_types,
+ &coerced_static_arguments,
+ &message);
+
+ if (op_signature == nullptr) {
+ if (message.empty()) {
THROW_SQL_ERROR_AT(&parse_function_call) << message;
+ } else {
+ THROW_SQL_ERROR_AT(&parse_function_call)
+ << "Cannot resolve scalar function " << function_name;
+ }
+ }
+
+ // 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());
+
+ const OperationPtr operation =
+ OperationFactory::Instance().getOperation(op_signature);
+ switch (operation->getOperationSuperTypeID()) {
+ case Operation::kUnaryOperation:
+ return E::UnaryExpression::Create(
+ op_signature,
+ std::static_pointer_cast<const UnaryOperation>(operation),
+ resolved_arguments[0],
+ coerced_static_arguments,
+ coerced_static_argument_types);
+ 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);
+ default: {
+ const auto operation_id =
+ static_cast<std::underlying_type_t<Operation::OperationSuperTypeID>>(
+ operation->getOperationSuperTypeID());
+ LOG(FATAL) << "Unknown opeation super type id: " << operation_id;
}
}
-
- THROW_SQL_ERROR_AT(&parse_function_call)
- << "Cannot resolve scalar function";
-
- return nullptr;
}
// TODO(chasseur): For now this only handles resolving aggregate functions. In
@@ -2686,8 +2543,8 @@ E::ScalarPtr Resolver::resolveFunctionCall(
}
}
- if (UnaryOperationFactory::Instance().hasUnaryOperation(function_name,
- resolved_arguments.size())) {
+ if (OperationFactory::Instance().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/4005df6e/query_optimizer/rules/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/tests/CMakeLists.txt b/query_optimizer/rules/tests/CMakeLists.txt
index 0d913e2..cdb5fe6 100644
--- a/query_optimizer/rules/tests/CMakeLists.txt
+++ b/query_optimizer/rules/tests/CMakeLists.txt
@@ -85,7 +85,6 @@ target_link_libraries(quickstep_queryoptimizer_rules_tests
quickstep_queryoptimizer_rules_tests_RuleTest
quickstep_types_operations_binaryoperations_BinaryOperation
quickstep_types_operations_binaryoperations_BinaryOperationFactory
- quickstep_types_operations_binaryoperations_BinaryOperationID
quickstep_types_operations_comparisons_Comparison
quickstep_types_operations_comparisons_ComparisonFactory
quickstep_types_operations_comparisons_ComparisonID
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/strategy/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/strategy/tests/CMakeLists.txt b/query_optimizer/strategy/tests/CMakeLists.txt
index 97675f0..1a60344 100644
--- a/query_optimizer/strategy/tests/CMakeLists.txt
+++ b/query_optimizer/strategy/tests/CMakeLists.txt
@@ -74,7 +74,6 @@ target_link_libraries(quickstep_queryoptimizer_strategy_tests
quickstep_types_TypeID
quickstep_types_operations_binaryoperations_BinaryOperation
quickstep_types_operations_binaryoperations_BinaryOperationFactory
- quickstep_types_operations_binaryoperations_BinaryOperationID
quickstep_types_operations_comparisons_Comparison
quickstep_types_operations_comparisons_ComparisonFactory
quickstep_types_operations_comparisons_ComparisonID
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/CMakeLists.txt b/query_optimizer/tests/CMakeLists.txt
index 5ef1d0a..4357c6a 100644
--- a/query_optimizer/tests/CMakeLists.txt
+++ b/query_optimizer/tests/CMakeLists.txt
@@ -51,7 +51,6 @@ target_link_libraries(quickstep_queryoptimizer_tests_OptimizerTest
quickstep_types_TypeID
quickstep_types_operations_binaryoperations_BinaryOperation
quickstep_types_operations_binaryoperations_BinaryOperationFactory
- quickstep_types_operations_binaryoperations_BinaryOperationID
quickstep_types_operations_comparisons_Comparison
quickstep_types_operations_comparisons_ComparisonFactory
quickstep_types_operations_comparisons_ComparisonID
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/query_optimizer/tests/OptimizerTest.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/OptimizerTest.cpp b/query_optimizer/tests/OptimizerTest.cpp
index 7eb7a11..36436c0 100644
--- a/query_optimizer/tests/OptimizerTest.cpp
+++ b/query_optimizer/tests/OptimizerTest.cpp
@@ -44,7 +44,6 @@
#include "types/TypeID.hpp"
#include "types/operations/binary_operations/BinaryOperation.hpp"
#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
#include "types/operations/comparisons/Comparison.hpp"
#include "types/operations/comparisons/ComparisonFactory.hpp"
#include "types/operations/comparisons/ComparisonID.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/relational_operators/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/relational_operators/CMakeLists.txt b/relational_operators/CMakeLists.txt
index 1693ec2..8ba00b0 100644
--- a/relational_operators/CMakeLists.txt
+++ b/relational_operators/CMakeLists.txt
@@ -663,7 +663,6 @@ target_link_libraries(AggregationOperator_unittest
quickstep_types_TypedValue
quickstep_types_containers_Tuple
quickstep_types_operations_binaryoperations_BinaryOperationFactory
- quickstep_types_operations_binaryoperations_BinaryOperationID
quickstep_types_operations_comparisons_ComparisonFactory
quickstep_types_operations_comparisons_ComparisonID
quickstep_utility_Macros
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/storage/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/storage/CMakeLists.txt b/storage/CMakeLists.txt
index 8b68150..7789881 100644
--- a/storage/CMakeLists.txt
+++ b/storage/CMakeLists.txt
@@ -863,7 +863,6 @@ target_link_libraries(quickstep_storage_SMAIndexSubBlock
quickstep_types_TypedValue
quickstep_types_operations_binaryoperations_BinaryOperation
quickstep_types_operations_binaryoperations_BinaryOperationFactory
- quickstep_types_operations_binaryoperations_BinaryOperationID
quickstep_types_operations_comparisons_Comparison
quickstep_types_operations_comparisons_ComparisonFactory
quickstep_types_operations_comparisons_ComparisonID
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/storage/SMAIndexSubBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/SMAIndexSubBlock.cpp b/storage/SMAIndexSubBlock.cpp
index 3b3b879..fda8c30 100644
--- a/storage/SMAIndexSubBlock.cpp
+++ b/storage/SMAIndexSubBlock.cpp
@@ -46,7 +46,6 @@
#include "types/TypedValue.hpp"
#include "types/operations/binary_operations/BinaryOperation.hpp"
#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
#include "types/operations/comparisons/Comparison.hpp"
#include "types/operations/comparisons/ComparisonFactory.hpp"
#include "types/operations/comparisons/ComparisonID.hpp"
@@ -360,8 +359,8 @@ SMAIndexSubBlock::SMAIndexSubBlock(const TupleStorageSubBlock &tuple_store,
if (add_operations_.elementIsNullAt(attr_typeid)) {
add_operations_.replaceElement(attr_typeid,
BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
- .makeUncheckedBinaryOperatorForTypes(TypeFactory::GetType(attr_typeid),
- TypeFactory::GetType(attr_sum_typeid)));
+ .makeUncheckedBinaryOperator(TypeFactory::GetType(attr_typeid),
+ TypeFactory::GetType(attr_sum_typeid)));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 1fac11a..0c7ee07 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -49,7 +49,6 @@ add_library(quickstep_types_NullType ../empty_src.cpp NullType.hpp)
add_library(quickstep_types_NumericSuperType ../empty_src.cpp NumericSuperType.hpp)
add_library(quickstep_types_NumericTypeUnifier ../empty_src.cpp NumericTypeUnifier.hpp)
add_library(quickstep_types_Type Type.cpp Type.hpp)
-add_library(quickstep_types_TypeConcept ../empty_src.cpp TypeConcept.hpp)
add_library(quickstep_types_TypeErrors ../empty_src.cpp TypeErrors.hpp)
add_library(quickstep_types_TypeFactory TypeFactory.cpp TypeFactory.hpp)
add_library(quickstep_types_TypeID TypeID.cpp TypeID.hpp)
@@ -167,8 +166,6 @@ target_link_libraries(quickstep_types_Type
quickstep_types_TypeID
quickstep_types_TypedValue
quickstep_utility_Macros)
-target_link_libraries(quickstep_types_TypeConcept
- glog)
target_link_libraries(quickstep_types_TypeFactory
glog
quickstep_types_CharType
@@ -204,7 +201,8 @@ target_link_libraries(quickstep_types_TypeUtil
quickstep_types_Type_proto
quickstep_types_VarCharType
quickstep_types_YearMonthIntervalType
- quickstep_utility_Macros)
+ quickstep_utility_Macros
+ quickstep_utility_TemplateUtil)
target_link_libraries(quickstep_types_TypedValue
farmhash
glog
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index ceb24b6..77f028a 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -55,7 +55,7 @@ class NumericSuperType : public TypeConcept<type_id, false, kNativeEmbedded, Cpp
}
protected:
- NumericSuperType(const bool nullable)
+ explicit NumericSuperType(const bool nullable)
: TypeConcept<type_id, false, kNativeEmbedded, CppType>(
Type::kNumeric, type_id, nullable, sizeof(CppType), sizeof(CppType)) {
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index afc46eb..066b2b5 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -485,7 +485,7 @@ class TypeConcept : public Type {
protected:
template <typename ...ArgTypes>
- TypeConcept(ArgTypes &&...args)
+ explicit TypeConcept(ArgTypes &&...args)
: Type(std::forward<ArgTypes>(args)...) {}
private:
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
index fe55952..6c58ef1 100644
--- a/types/TypeUtil.hpp
+++ b/types/TypeUtil.hpp
@@ -138,7 +138,6 @@ inline auto InvokeOnTypeID(const TypeID type_id,
std::integral_constant<TypeID, type_id>, FunctorT>::Invoke(functor)
switch (type_id) {
-
REGISTER_TYPE_ID(kInt);
REGISTER_TYPE_ID(kLong);
REGISTER_TYPE_ID(kFloat);
@@ -150,7 +149,6 @@ inline auto InvokeOnTypeID(const TypeID type_id,
REGISTER_TYPE_ID(kChar);
REGISTER_TYPE_ID(kVarChar);
REGISTER_TYPE_ID(kNullType);
-
default:
FATAL_ERROR("Unrecognized TypeID in InvokeOnTypeID()");
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/containers/ColumnVector.cpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.cpp b/types/containers/ColumnVector.cpp
index dfc0fae..ef3587e 100644
--- a/types/containers/ColumnVector.cpp
+++ b/types/containers/ColumnVector.cpp
@@ -41,4 +41,8 @@ ColumnVector* ColumnVector::MakeVectorOfValue(
}
}
+constexpr bool NativeColumnVector::kNative;
+
+constexpr bool IndirectColumnVector::kNative;
+
} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/containers/ColumnVector.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp
index f0a2cd5..5d11098 100644
--- a/types/containers/ColumnVector.hpp
+++ b/types/containers/ColumnVector.hpp
@@ -119,6 +119,8 @@ class ColumnVector {
**/
class NativeColumnVector : public ColumnVector {
public:
+ static constexpr bool kNative = true;
+
/**
* @brief Constructor for a NativeColumnVector which owns its own array of
* values.
@@ -400,6 +402,8 @@ class NativeColumnVector : public ColumnVector {
**/
class IndirectColumnVector : public ColumnVector {
public:
+ static constexpr bool kNative = false;
+
/**
* @brief Constructor.
*
@@ -494,7 +498,7 @@ class IndirectColumnVector : public ColumnVector {
* @param value A value to append to this NativeColumnVector.
**/
inline void appendTypedValue(TypedValue &&value) {
- DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+ DCHECK(value.isPlausibleInstanceOf(type_.getSignature())) << type_.getName();
DCHECK_LT(values_.size(), reserved_length_);
values_.emplace_back(std::move(value));
}
@@ -505,6 +509,10 @@ class IndirectColumnVector : public ColumnVector {
values_.emplace_back(type_.makeNullValue());
}
+ inline void fillWithNulls() {
+ fillWithValue(type_.makeNullValue());
+ }
+
/**
* @brief Fill this entire ColumnVector with copies of value.
*
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/CMakeLists.txt b/types/operations/CMakeLists.txt
index 6d38d80..baaaf55 100644
--- a/types/operations/CMakeLists.txt
+++ b/types/operations/CMakeLists.txt
@@ -25,12 +25,41 @@ QS_PROTOBUF_GENERATE_CPP(types_operations_Operation_proto_srcs
# Declare micro-libs:
add_library(quickstep_types_operations_Operation Operation.cpp Operation.hpp)
+add_library(quickstep_types_operations_OperationFactory OperationFactory.cpp OperationFactory.hpp)
+add_library(quickstep_types_operations_OperationUtil ../../empty_src.cpp OperationUtil.hpp)
add_library(quickstep_types_operations_OperationSignature OperationSignature.cpp OperationSignature.hpp)
add_library(quickstep_types_operations_Operation_proto ${types_operations_Operation_proto_srcs})
# Link dependencies:
target_link_libraries(quickstep_types_operations_Operation
+ quickstep_types_operations_OperationSignature
quickstep_utility_Macros)
+target_link_libraries(quickstep_types_operations_OperationFactory
+ quickstep_types_Type
+ quickstep_types_TypeFactory
+ quickstep_types_TypeID
+ quickstep_types_TypeUtil
+ quickstep_types_TypedValue
+ quickstep_types_operations_Operation
+ quickstep_types_operations_OperationSignature
+ quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
+ quickstep_types_operations_binaryoperations_BinaryOperation
+ quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+ quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+ quickstep_types_operations_unaryoperations_CMathUnaryOperations
+ quickstep_types_operations_unaryoperations_CastOperation
+ quickstep_types_operations_unaryoperations_DateExtractOperation
+ quickstep_types_operations_unaryoperations_SubstringOperation
+ quickstep_types_operations_unaryoperations_UnaryOperation
+ quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+ quickstep_utility_HashPair
+ quickstep_utility_Macros
+ quickstep_utility_StringUtil)
+target_link_libraries(quickstep_types_operations_OperationUtil
+ quickstep_catalog_CatalogTypedefs
+ quickstep_types_Type
+ quickstep_types_TypedValue
+ quickstep_types_containers_ColumnVector)
target_link_libraries(quickstep_types_operations_OperationSignature
quickstep_types_TypeID
quickstep_types_Type_proto
@@ -46,6 +75,8 @@ target_link_libraries(quickstep_types_operations_Operation_proto
add_library(quickstep_types_operations ../../empty_src.cpp)
target_link_libraries(quickstep_types_operations
quickstep_types_operations_Operation
+ quickstep_types_operations_OperationFactory
+ quickstep_types_operations_OperationUtil
quickstep_types_operations_OperationSignature
quickstep_types_operations_Operation_proto
quickstep_types_operations_binaryoperations
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/Operation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/Operation.hpp b/types/operations/Operation.hpp
index ad7c868..6da0f4c 100644
--- a/types/operations/Operation.hpp
+++ b/types/operations/Operation.hpp
@@ -23,6 +23,7 @@
#include <string>
#include <vector>
+#include "types/operations/OperationSignature.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
@@ -31,6 +32,9 @@ namespace quickstep {
* @{
*/
+class Operation;
+typedef std::shared_ptr<const Operation> OperationPtr;
+
/**
* @brief An operation which can be applied to typed values. Each exact
* concrete Operation is a singleton.
@@ -87,6 +91,10 @@ class Operation {
return "NoShortName";
}
+ virtual std::vector<OperationSignaturePtr> getSignatures() const {
+ return {};
+ }
+
/**
* @brief Determine whether this Operation is exactly the same as another.
* @note Because all exact operations are singletons, a simple pointer
@@ -101,7 +109,7 @@ class Operation {
}
protected:
- Operation(const OperationSuperTypeID super_type_id)
+ explicit Operation(const OperationSuperTypeID super_type_id)
: super_type_id_(super_type_id) {
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/Operation.proto
----------------------------------------------------------------------
diff --git a/types/operations/Operation.proto b/types/operations/Operation.proto
index 006b07c..da2a282 100644
--- a/types/operations/Operation.proto
+++ b/types/operations/Operation.proto
@@ -44,15 +44,3 @@ message OperationSignature {
repeated TypeID argument_type_ids = 2;
required uint32 num_static_arguments = 3;
}
-
-message BinaryOperation {
- enum BinaryOperationID {
- ADD = 0;
- SUBTRACT = 1;
- MULTIPLY = 2;
- DIVIDE = 3;
- MODULO = 4;
- }
-
- required BinaryOperationID operation_id = 1;
-}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/OperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.cpp b/types/operations/OperationFactory.cpp
new file mode 100644
index 0000000..5743cfc
--- /dev/null
+++ b/types/operations/OperationFactory.cpp
@@ -0,0 +1,358 @@
+/**
+ * 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.
+ **/
+
+#include "types/operations/OperationFactory.hpp"
+
+#include <list>
+#include <memory>
+#include <string>
+#include <vector>
+
+#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"
+#include "types/operations/binary_operations/AsciiStringBinaryOperations.hpp"
+#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp"
+#include "types/operations/unary_operations/AsciiStringUnaryOperations.hpp"
+#include "types/operations/unary_operations/CMathUnaryOperations.hpp"
+#include "types/operations/unary_operations/CastOperation.hpp"
+#include "types/operations/unary_operations/DateExtractOperation.hpp"
+#include "types/operations/unary_operations/SubstringOperation.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "utility/StringUtil.hpp"
+
+namespace quickstep {
+
+namespace {
+
+struct FunctorPackDispatcher {
+ template <typename FunctorT>
+ inline static std::list<OperationPtr> Generate(
+ std::enable_if_t<FunctorT::kOperationSuperTypeID == Operation::kUnaryOperation>* = 0) {
+ return { std::make_shared<const UnaryOperationWrapper<FunctorT>>() };
+ }
+
+ template <typename FunctorT>
+ inline static std::list<OperationPtr> Generate(
+ std::enable_if_t<FunctorT::kOperationSuperTypeID == Operation::kBinaryOperation>* = 0) {
+ return { std::make_shared<const BinaryOperationWrapper<FunctorT>>() };
+ }
+
+ template <typename FunctorT>
+ inline static std::list<OperationPtr> Generate(
+ decltype(FunctorT::template GenerateOperations<FunctorPackDispatcher>())* = 0) {
+ return FunctorT::template GenerateOperations<FunctorPackDispatcher>();
+ }
+};
+
+} // namespace
+
+OperationFactory::OperationFactory() {
+ registerOperation<CastOperation>();
+ registerOperation<DateExtractOperation>();
+ registerOperation<SubstringOperation>();
+
+ registerFunctorPack<ArithmeticUnaryFunctorPack>();
+ registerFunctorPack<AsciiStringUnaryFunctorPack>();
+ registerFunctorPack<CMathUnaryFunctorPack>();
+
+ registerFunctorPack<ArithmeticBinaryFunctorPack>();
+ registerFunctorPack<AsciiStringBinaryFunctorPack>();
+}
+
+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,
+ std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+ std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+ std::string *message) const {
+ const std::string lower_case_name = ToLower(operation_name);
+ const std::size_t arity = argument_types->size();
+ const auto &indices_it =
+ primary_index_.find(std::make_pair(lower_case_name, arity));
+
+ if (indices_it == primary_index_.end()) {
+ *message = "Unrecognized function " + operation_name
+ + " with " + std::to_string(arity) + " arguments";
+ }
+
+ ResolveStatus status;
+ OperationSignaturePtr op_signature = nullptr;
+ const auto &secondary_indices = indices_it->second;
+
+ std::vector<TypeID> argument_type_ids;
+ for (const auto *type : *argument_types) {
+ argument_type_ids.emplace_back(type->getTypeID());
+ }
+
+ // First, try full exact matching.
+ status = resolveOperationWithFullTypeMatch(secondary_indices.full_match_index,
+ argument_type_ids,
+ *argument_types,
+ *static_arguments,
+ coerced_static_arguments,
+ &op_signature,
+ message);
+ if (status == ResolveStatus::kSuccess) {
+ DCHECK(op_signature != nullptr);
+ *coerced_argument_types = argument_types;
+ return op_signature;
+ } else if (status == ResolveStatus::kError) {
+ return nullptr;
+ }
+
+ // Otherwise, try partial (non-static arguments) exact matching.
+ status = resolveOperationWithPartialTypeMatch(secondary_indices.non_static_match_index,
+ argument_type_ids,
+ *argument_types,
+ *static_arguments,
+ coerced_argument_types,
+ coerced_static_arguments,
+ &op_signature,
+ message);
+ if (status == ResolveStatus::kSuccess) {
+ DCHECK(op_signature != nullptr);
+ return op_signature;
+ } else if (status == ResolveStatus::kError) {
+ return nullptr;
+ }
+
+ // TODO
+ *message = "Cannot resolve function " + operation_name;
+ return nullptr;
+}
+
+OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMatch(
+ const FullSignatureIndex &full_match_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,
+ OperationSignaturePtr *resolved_op_signature,
+ std::string *message) const {
+ const std::size_t max_num_static_arguments = static_arguments.size();
+ auto it = full_match_index.lower_bound(
+ std::make_pair(&argument_type_ids, max_num_static_arguments));
+
+ if (it != full_match_index.end() && *it->first.first == argument_type_ids) {
+ const OperationSignaturePtr op_signature = it->second;
+ const OperationPtr operation = getOperation(op_signature);
+
+ *partial_static_arguments =
+ std::make_shared<const std::vector<TypedValue>>(
+ static_arguments.begin()
+ + (max_num_static_arguments - op_signature->getNumStaticArguments()),
+ static_arguments.end());
+
+ if (canApplyOperationTo(operation,
+ argument_types,
+ **partial_static_arguments,
+ message)) {
+ *resolved_op_signature = op_signature;
+ return ResolveStatus::kSuccess;
+ } else {
+ return ResolveStatus::kError;
+ }
+ }
+
+ return ResolveStatus::kNotFound;
+}
+
+OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTypeMatch(
+ const PartialSignatureIndex &non_static_match_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<const Type*>> *coerced_argument_types,
+ std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+ OperationSignaturePtr *resolved_op_signature,
+ std::string *message) const {
+ const std::size_t arity = argument_types.size();
+ const std::size_t max_num_static_arguments = static_arguments.size();
+ const std::size_t first_static_argument_position = arity - max_num_static_arguments;
+
+ auto it = non_static_match_index.lower_bound(
+ std::make_pair(&argument_type_ids, max_num_static_arguments));
+ while (it != non_static_match_index.end()) {
+ const std::vector<TypeID> &expected_type_ids = *it->first.first;
+ DCHECK_GE(expected_type_ids.size(), it->first.second);
+ const std::size_t num_non_static_arguments =
+ expected_type_ids.size() - it->first.second;
+
+ if (!std::equal(expected_type_ids.begin(),
+ expected_type_ids.begin() + num_non_static_arguments,
+ argument_type_ids.begin())) {
+ break;
+ }
+
+ // Coerce static arguments
+ std::vector<const Type*> coerced_static_arg_types;
+ std::vector<TypedValue> 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 =
+ 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;
+ if (TypeUtil::IsParameterized(expected_type_id)) {
+ // TODO: refactor type system to make this coercion extensible.
+ if (expected_type_id == kChar && arg_type.getTypeID() == kVarChar) {
+ expected_type = &TypeFactory::GetType(
+ expected_type_id, arg_type.maximumByteLength() - 1);
+ } else if (expected_type_id == kVarChar && arg_type.getTypeID() == kChar) {
+ expected_type = &TypeFactory::GetType(
+ expected_type_id, arg_type.maximumByteLength() + 1);
+ }
+ } else {
+ expected_type = &TypeFactory::GetType(expected_type_id);
+ }
+
+ 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));
+ } else {
+ is_coercible = false;
+ break;
+ }
+ }
+ }
+
+ if (is_coercible) {
+ 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);
+ }
+
+ const OperationPtr operation = getOperation(it->second);
+ if (canApplyOperationTo(operation,
+ coerced_arg_types,
+ coerced_static_args,
+ message)) {
+ *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));
+ *resolved_op_signature = it->second;
+ return ResolveStatus::kSuccess;
+ }
+ }
+
+ ++it;
+ }
+
+ return ResolveStatus::kNotFound;
+}
+
+bool OperationFactory::canApplyOperationTo(
+ const OperationPtr operation,
+ const std::vector<const Type*> &argument_types,
+ const std::vector<TypedValue> &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,
+ message);
+ }
+ case Operation::kBinaryOperation: {
+ const BinaryOperationPtr binary_operation =
+ std::static_pointer_cast<const BinaryOperation>(operation);
+ return binary_operation->canApplyTo(*argument_types[0],
+ *argument_types[1],
+ static_arguments,
+ message);
+ }
+ default: {
+ const auto operation_id =
+ static_cast<std::underlying_type_t<Operation::OperationSuperTypeID>>(
+ operation->getOperationSuperTypeID());
+ LOG(FATAL) << "Unknown opeation super type id: " << operation_id;
+ }
+ }
+}
+
+
+const OperationFactory& OperationFactory::Instance() {
+ static OperationFactory instance;
+ return instance;
+}
+
+template <typename OperationT>
+void OperationFactory::registerOperation() {
+ registerOperationInternal(std::make_shared<const OperationT>());
+}
+
+template <typename FunctorPackT>
+void OperationFactory::registerFunctorPack() {
+ for (const OperationPtr &operation :
+ FunctorPackT::template GenerateOperations<FunctorPackDispatcher>()) {
+ registerOperationInternal(operation);
+ }
+}
+
+void OperationFactory::registerOperationInternal(const OperationPtr &operation) {
+ DCHECK(operation->getOperationSuperTypeID() == Operation::kUnaryOperation ||
+ operation->getOperationSuperTypeID() == Operation::kBinaryOperation);
+
+ for (const OperationSignaturePtr op_sig_orig : operation->getSignatures()) {
+ DCHECK(operation->getOperationSuperTypeID() != Operation::kUnaryOperation ||
+ op_sig_orig->getNonStaticArity() == 1u);
+ DCHECK(operation->getOperationSuperTypeID() != Operation::kBinaryOperation ||
+ op_sig_orig->getNonStaticArity() == 2u);
+
+ const OperationSignaturePtr op_sig =
+ OperationSignature::Create(ToLower(op_sig_orig->getName()),
+ op_sig_orig->getArgumentTypeIDs(),
+ op_sig_orig->getNumStaticArguments());
+
+ // TODO: print error message for collision
+ operations_.emplace(op_sig, operation);
+
+ OperationSecondaryIndices &indices =
+ primary_index_[std::make_pair(op_sig->getName(), op_sig->getArity())];
+ const SignatureReference sig_ref =
+ std::make_pair(&op_sig->getArgumentTypeIDs(),
+ op_sig->getNumStaticArguments());
+ indices.full_match_index.emplace(sig_ref, op_sig);
+ indices.non_static_match_index.emplace(sig_ref, op_sig);
+ indices.signatures.emplace(op_sig);
+ }
+}
+
+
+} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/OperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.hpp b/types/operations/OperationFactory.hpp
new file mode 100644
index 0000000..5a73cbd
--- /dev/null
+++ b/types/operations/OperationFactory.hpp
@@ -0,0 +1,205 @@
+/**
+ * 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_OPERATIONS_OPERATION_FACTORY_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_FACTORY_HPP_
+
+#include <memory>
+#include <set>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/operations/Operation.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/binary_operations/BinaryOperation.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/HashPair.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class Type;
+
+/** \addtogroup Types
+ * @{
+ */
+
+class OperationFactory {
+ public:
+ static const OperationFactory& Instance();
+
+ inline bool hasOperation(const std::string &operation_name,
+ const std::size_t arity) const {
+ const auto indices_it =
+ primary_index_.find(std::make_pair(operation_name, arity));
+ return indices_it != primary_index_.end();
+ }
+
+ inline OperationPtr getOperation(const OperationSignaturePtr &op_signature) const {
+ DCHECK(operations_.find(op_signature) != operations_.end());
+ return operations_.at(op_signature);
+ }
+
+ inline UnaryOperationPtr getUnaryOperation(
+ const OperationSignaturePtr &op_signature) const {
+ const OperationPtr operation = getOperation(op_signature);
+ DCHECK(operation->getOperationSuperTypeID() == Operation::kUnaryOperation);
+ return std::static_pointer_cast<const UnaryOperation>(operation);
+ }
+
+ inline BinaryOperationPtr getBinaryOperation(
+ const OperationSignaturePtr &op_signature) const {
+ const OperationPtr operation = getOperation(op_signature);
+ DCHECK(operation->getOperationSuperTypeID() == Operation::kBinaryOperation);
+ return std::static_pointer_cast<const BinaryOperation>(operation);
+ }
+
+ OperationSignaturePtr 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,
+ std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+ std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+ std::string *message) const;
+
+ private:
+ OperationFactory();
+
+ template <typename OperationT>
+ void registerOperation();
+
+ template <typename FunctorPackT>
+ void registerFunctorPack();
+
+ void registerOperationInternal(const OperationPtr &operation);
+
+ using SignatureReference = std::pair<const std::vector<TypeID>*, std::size_t>;
+
+ struct FullSignatureLess {
+ inline bool operator()(const SignatureReference &lhs,
+ const SignatureReference &rhs) const {
+ int cmp_code = static_cast<int>(lhs.first->size())
+ - static_cast<int>(lhs.first->size());
+ if (cmp_code != 0) {
+ return cmp_code < 0;
+ }
+ for (std::size_t i = 0; i < lhs.first->size(); ++i) {
+ cmp_code = static_cast<int>(lhs.first->at(i))
+ - static_cast<int>(rhs.first->at(i));
+ if (cmp_code != 0) {
+ return cmp_code < 0;
+ }
+ }
+ return lhs.second > rhs.second;
+ }
+ };
+ using FullSignatureIndex = std::map<SignatureReference,
+ OperationSignaturePtr,
+ FullSignatureLess>;
+
+ struct PartialSignatureLess {
+ inline bool operator()(const SignatureReference &lhs,
+ const SignatureReference &rhs) const {
+ const std::size_t l_arity = lhs.first->size() - lhs.second;
+ const std::size_t r_arity = rhs.first->size() - rhs.second;
+ int cmp_code = static_cast<int>(l_arity) - static_cast<int>(r_arity);
+ if (cmp_code != 0) {
+ return cmp_code < 0;
+ }
+ for (std::size_t i = 0; i < l_arity; ++i) {
+ cmp_code = static_cast<int>(lhs.first->at(i))
+ - static_cast<int>(rhs.first->at(i));
+ if (cmp_code != 0) {
+ return cmp_code < 0;
+ }
+ }
+ return lhs.second > rhs.second;
+ }
+ };
+ using PartialSignatureIndex = std::map<SignatureReference,
+ OperationSignaturePtr,
+ PartialSignatureLess>;
+
+ struct OperationSecondaryIndices {
+ std::set<OperationSignaturePtr> signatures;
+ FullSignatureIndex full_match_index;
+ PartialSignatureIndex non_static_match_index;
+ };
+
+ enum class ResolveStatus {
+ kSuccess = 0,
+ kError,
+ kNotFound
+ };
+
+ ResolveStatus resolveOperationWithFullTypeMatch(
+ const FullSignatureIndex &full_match_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>> *trimmed_static_arguments,
+ OperationSignaturePtr *resolved_op_signature,
+ std::string *message) const;
+
+ ResolveStatus resolveOperationWithPartialTypeMatch(
+ const PartialSignatureIndex &non_static_match_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<const Type*>> *coerced_argument_types,
+ std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+ OperationSignaturePtr *resolved_op_signature,
+ std::string *message) const;
+
+// ResolveStatus resolveOperationGeneric(
+// const std::set<OperationSignaturePtr> signatures,
+// 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<const Type*>> *coerced_argument_types,
+// std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+// OperationSignaturePtr *op_signature,
+// std::string *message) const;
+
+ bool canApplyOperationTo(const OperationPtr operation,
+ const std::vector<const Type*> &argument_types,
+ const std::vector<TypedValue> &static_arguments,
+ std::string *message) const;
+
+ std::unordered_map<OperationSignaturePtr,
+ OperationPtr,
+ OperationSignatureHash,
+ OperationSignatureEqual> operations_;
+
+ std::unordered_map<std::pair<std::string, std::size_t>,
+ OperationSecondaryIndices> primary_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(OperationFactory);
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_OPERATIONS_OPERATION_FACTORY_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/OperationSignature.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationSignature.hpp b/types/operations/OperationSignature.hpp
index 7020e50..b326aef 100644
--- a/types/operations/OperationSignature.hpp
+++ b/types/operations/OperationSignature.hpp
@@ -86,7 +86,7 @@ class OperationSignature {
}
cmp_code = static_cast<int>(num_static_arguments_ - r.num_static_arguments_);
if (cmp_code != 0) {
- return cmp_code < 0;
+ return cmp_code > 0;
}
for (std::size_t i = 0; i < getArity(); ++i) {
const auto l_tid =
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4005df6e/types/operations/OperationUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationUtil.hpp b/types/operations/OperationUtil.hpp
new file mode 100644
index 0000000..076dc0c
--- /dev/null
+++ b/types/operations/OperationUtil.hpp
@@ -0,0 +1,334 @@
+/**
+ * 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_OPERATIONS_OPERATION_UTIL_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTIL_HPP_
+
+#include <cstddef>
+#include <list>
+#include <string>
+#include <type_traits>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "types/Type.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+template <typename FunctorT, typename ...SpecArgs>
+struct FunctorSpecializer {
+ template <bool specialize = (sizeof...(SpecArgs) != 0),
+ typename EnableT = void>
+ struct Implementation;
+
+ typedef Implementation<> type;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool specialize>
+struct FunctorSpecializer<FunctorT, SpecArgs...>
+ ::Implementation<specialize, std::enable_if_t<specialize>> {
+ template <typename ...FuncArgs>
+ inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) {
+ return functor.template apply<SpecArgs...>(std::forward<FuncArgs>(args)...);
+ }
+ typedef FunctorT FunctorType;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool specialize>
+struct FunctorSpecializer<FunctorT, SpecArgs...>
+ ::Implementation<specialize, std::enable_if_t<!specialize>> {
+ template <typename ...FuncArgs>
+ inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) {
+ return functor.apply(std::forward<FuncArgs>(args)...);
+ }
+ typedef FunctorT FunctorType;
+};
+
+template <typename ColumnVectorT>
+struct ColumnVectorValueAccessor {
+ explicit ColumnVectorValueAccessor(const ColumnVectorT &column_vector_in)
+ : column_vector(column_vector_in),
+ length(column_vector.size()) {}
+
+ inline void beginIteration() {
+ pos = static_cast<std::size_t>(-1);
+ }
+
+ inline bool next() {
+ return (++pos) < length;
+ }
+
+ inline std::size_t getNumTuples() const {
+ return length;
+ }
+
+ template <bool nullable>
+ inline const void* getUntypedValue(const attribute_id) const {
+ return column_vector.template getUntypedValue<nullable>(pos);
+ }
+
+ inline TypedValue getTypedValue(const attribute_id) const {
+ return column_vector.getTypedValue(pos);
+ }
+
+ const ColumnVectorT &column_vector;
+ const std::size_t length;
+ std::size_t pos;
+};
+
+template <typename FuncSpec, typename T, typename EnableT = void>
+struct Codegen;
+
+template <typename FuncSpec, typename T>
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kNativeEmbedded>> {
+ using ColumnVectorType = NativeColumnVector;
+ using FunctorSpecializer = FuncSpec;
+
+ using NativeType = typename T::cpptype;
+ using NativeTypeConst = const typename T::cpptype;
+ using NativeTypeConstRef = const NativeType&;
+ using NativeTypeConstPtr = const NativeType*;
+
+ template <typename ArgumentGen>
+ inline static TypedValue ApplyUnaryTypedValue(
+ typename ArgumentGen::NativeTypeConstRef argument,
+ const Type &result_type,
+ const typename FuncSpec::FunctorType &functor) {
+ return TypedValue(FuncSpec::Invoke(functor, argument));
+ }
+
+ template <typename ArgumentGen>
+ inline static void ApplyUnaryColumnVector(
+ const typename ArgumentGen::NativeTypeConstRef argument,
+ const typename FuncSpec::FunctorType &functor,
+ ColumnVectorType *cv) {
+ *static_cast<NativeType *>(cv->getPtrForDirectWrite()) =
+ FuncSpec::Invoke(functor, argument);
+ }
+
+ template <typename LeftGen, typename RightGen>
+ inline static TypedValue ApplyBinaryTypedValue(
+ typename LeftGen::NativeTypeConstRef left,
+ typename RightGen::NativeTypeConstRef right,
+ const Type &result_type,
+ const typename FuncSpec::FunctorType &functor) {
+ return TypedValue(FuncSpec::Invoke(functor, left, right));
+ }
+
+ template <typename LeftGen, typename RightGen>
+ inline static void ApplyBinaryColumnVector(
+ const typename LeftGen::NativeTypeConstRef left,
+ const typename RightGen::NativeTypeConstRef right,
+ const typename FuncSpec::FunctorType &functor,
+ ColumnVectorType *cv) {
+ *static_cast<NativeType *>(cv->getPtrForDirectWrite()) =
+ FuncSpec::Invoke(functor, left, right);
+ }
+
+ template <bool nullable, typename AccessorT>
+ inline static NativeTypeConstPtr GetValuePtr(
+ const AccessorT *accessor,
+ const attribute_id attr_id) {
+ return static_cast<NativeTypeConstPtr>(
+ accessor->template getUntypedValue<nullable>(attr_id));
+ }
+
+ inline static bool IsNull(const NativeType *value) {
+ return value == nullptr;
+ }
+
+ // Dereference: NativeTypeConstPtr& -> const NativeType&
+ inline static const NativeType& Dereference(const NativeType *value) {
+ return *value;
+ }
+
+ inline static const NativeType ToNativeValueConst(const TypedValue &value) {
+ return value.getLiteral<NativeType>();
+ }
+};
+
+template <typename FuncSpec, typename T>
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kNonNativeInline>> {
+ using ColumnVectorType = NativeColumnVector;
+ using FunctorSpecializer = FuncSpec;
+
+ using NativeType = void*;
+ using NativeTypeConst = const void*;
+ using NativeTypeConstRef = const void*;
+ using NativeTypeConstPtr = const void*;
+
+ template <typename ArgumentGen>
+ inline static TypedValue ApplyUnaryTypedValue(
+ typename ArgumentGen::NativeTypeConstRef argument,
+ const Type &result_type,
+ const typename FuncSpec::FunctorType &functor) {
+ void *result = std::malloc(result_type.maximumByteLength());
+ FuncSpec::Invoke(functor, argument, result);
+ return TypedValue::CreateWithOwnedData(T::kStaticTypeID,
+ result,
+ result_type.maximumByteLength());
+ }
+
+ template <typename ArgumentGen>
+ inline static void ApplyUnaryColumnVector(
+ const typename ArgumentGen::NativeTypeConstRef argument,
+ const typename FuncSpec::FunctorType &functor,
+ ColumnVectorType *cv) {
+ FuncSpec::Invoke(functor, argument, cv->getPtrForDirectWrite());
+ }
+
+ template <typename LeftGen, typename RightGen>
+ inline static TypedValue ApplyBinaryTypedValue(
+ typename LeftGen::NativeTypeConstRef left,
+ typename RightGen::NativeTypeConstRef right,
+ const Type &result_type,
+ const typename FuncSpec::FunctorType &functor) {
+ void *result = std::malloc(result_type.maximumByteLength());
+ FuncSpec::Invoke(functor, left, right, result);
+ return TypedValue::CreateWithOwnedData(T::kStaticTypeID,
+ result,
+ result_type.maximumByteLength());
+ }
+
+ template <typename LeftGen, typename RightGen>
+ inline static void ApplyBinaryColumnVector(
+ const typename LeftGen::NativeTypeConstRef left,
+ const typename RightGen::NativeTypeConstRef right,
+ const typename FuncSpec::FunctorType &functor,
+ ColumnVectorType *cv) {
+ FuncSpec::Invoke(functor, left, right, cv->getPtrForDirectWrite());
+ }
+
+ template <bool nullable, typename AccessorT>
+ inline static NativeTypeConstPtr GetValuePtr(
+ const AccessorT *accessor,
+ const attribute_id attr_id) {
+ return accessor->template getUntypedValue<nullable>(attr_id);
+ }
+
+ inline static bool IsNull(const void *value) {
+ return value == nullptr;
+ }
+
+ // Dereference: NativeTypeConstPtr& -> const NativeType&
+ inline static const void* Dereference(const void *value) {
+ return value;
+ }
+
+ inline static const void* ToNativeValueConst(const TypedValue &value) {
+ return value.getDataPtr();
+ }
+};
+
+template <typename FuncSpec, typename T>
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kOutOfLine>> {
+ using ColumnVectorType = IndirectColumnVector;
+ using FunctorSpecializer = FuncSpec;
+
+ using NativeType = TypedValue;
+ using NativeTypeConst = const TypedValue;
+ using NativeTypeConstRef = const TypedValue&;
+ using NativeTypeConstPtr = const TypedValue;
+
+ template <typename ArgumentGen>
+ inline static TypedValue ApplyUnaryTypedValue(
+ typename ArgumentGen::NativeTypeConstRef argument,
+ const Type &result_type,
+ const typename FuncSpec::FunctorType &functor) {
+ return FuncSpec::Invoke(functor, argument);
+ }
+
+ template <typename ArgumentGen>
+ inline static void ApplyUnaryColumnVector(
+ const typename ArgumentGen::NativeTypeConstRef argument,
+ const typename FuncSpec::FunctorType &functor,
+ ColumnVectorType *cv) {
+ cv->appendTypedValue(FuncSpec::Invoke(functor, argument));
+ }
+
+ template <typename LeftGen, typename RightGen>
+ inline static TypedValue ApplyBinaryTypedValue(
+ typename LeftGen::NativeTypeConstRef left,
+ typename RightGen::NativeTypeConstRef right,
+ const Type &result_type,
+ const typename FuncSpec::FunctorType &functor) {
+ return FuncSpec::Invoke(functor, left, right);
+ }
+
+ template <typename LeftGen, typename RightGen>
+ inline static void ApplyBinaryColumnVector(
+ const typename LeftGen::NativeTypeConstRef left,
+ const typename RightGen::NativeTypeConstRef right,
+ const typename FuncSpec::FunctorType &functor,
+ ColumnVectorType *cv) {
+ cv->appendTypedValue(FuncSpec::Invoke(functor, left, right));
+ }
+
+ template <bool nullable, typename AccessorT>
+ inline static NativeTypeConstPtr GetValuePtr(
+ const AccessorT *accessor,
+ const attribute_id attr_id) {
+ return accessor->getTypedValue(attr_id);
+ }
+
+ inline static bool IsNull(NativeTypeConstPtr &value) {
+ return value.isNull();
+ }
+
+ // Dereference: NativeTypeConstPtr& -> const NativeType&
+ inline static const NativeType& Dereference(NativeTypeConstPtr &value) {
+ return value;
+ }
+
+ inline static const NativeType& ToNativeValueConst(const TypedValue &value) {
+ return value;
+ }
+};
+
+template <typename ...FunctorTypes>
+struct FunctorPack {
+ template <typename Dispatcher>
+ inline static std::list<OperationPtr> GenerateOperations() {
+ std::vector<std::list<OperationPtr>> op_list_groups =
+ { Dispatcher::template Generate<FunctorTypes>()... };
+
+ std::list<OperationPtr> operations;
+ for (std::list<OperationPtr> &op_list : op_list_groups) {
+ operations.splice(operations.end(), std::move(op_list));
+ }
+ return operations;
+ }
+};
+
+struct OperationPack {
+ virtual std::vector<OperationPtr> generateOperations() = 0;
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTIL_HPP_