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/09 21:29:14 UTC
[4/8] incubator-quickstep git commit: Initial commit
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index f1876b8..18a3aa0 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -79,103 +79,104 @@ extern int quickstep_yydebug;
TOKEN_CSB_TREE = 289,
TOKEN_BY = 290,
TOKEN_CASE = 291,
- TOKEN_CHARACTER = 292,
- TOKEN_CHECK = 293,
- TOKEN_COLUMN = 294,
- TOKEN_CONSTRAINT = 295,
- TOKEN_COPY = 296,
- TOKEN_CREATE = 297,
- TOKEN_CURRENT = 298,
- TOKEN_DATE = 299,
- TOKEN_DATETIME = 300,
- TOKEN_DAY = 301,
- TOKEN_DECIMAL = 302,
- TOKEN_DEFAULT = 303,
- TOKEN_DELETE = 304,
- TOKEN_DELIMITER = 305,
- TOKEN_DESC = 306,
- TOKEN_DISTINCT = 307,
- TOKEN_DOUBLE = 308,
- TOKEN_DROP = 309,
- TOKEN_ELSE = 310,
- TOKEN_END = 311,
- TOKEN_ESCAPE_STRINGS = 312,
- TOKEN_EXISTS = 313,
- TOKEN_EXTRACT = 314,
- TOKEN_FALSE = 315,
- TOKEN_FIRST = 316,
- TOKEN_FLOAT = 317,
- TOKEN_FOLLOWING = 318,
- TOKEN_FOR = 319,
- TOKEN_FOREIGN = 320,
- TOKEN_FROM = 321,
- TOKEN_FULL = 322,
- TOKEN_GROUP = 323,
- TOKEN_HASH = 324,
- TOKEN_HAVING = 325,
- TOKEN_HOUR = 326,
- TOKEN_IN = 327,
- TOKEN_INDEX = 328,
- TOKEN_INNER = 329,
- TOKEN_INSERT = 330,
- TOKEN_INTEGER = 331,
- TOKEN_INTERVAL = 332,
- TOKEN_INTO = 333,
- TOKEN_JOIN = 334,
- TOKEN_KEY = 335,
- TOKEN_LAST = 336,
- TOKEN_LEFT = 337,
- TOKEN_LIMIT = 338,
- TOKEN_LONG = 339,
- TOKEN_MINUTE = 340,
- TOKEN_MONTH = 341,
- TOKEN_NULL = 342,
- TOKEN_NULLS = 343,
- TOKEN_OFF = 344,
- TOKEN_ON = 345,
- TOKEN_ORDER = 346,
- TOKEN_OUTER = 347,
- TOKEN_OVER = 348,
- TOKEN_PARTITION = 349,
- TOKEN_PARTITIONS = 350,
- TOKEN_PERCENT = 351,
- TOKEN_PRECEDING = 352,
- TOKEN_PRIMARY = 353,
- TOKEN_PRIORITY = 354,
- TOKEN_QUIT = 355,
- TOKEN_RANGE = 356,
- TOKEN_REAL = 357,
- TOKEN_REFERENCES = 358,
- TOKEN_RIGHT = 359,
- TOKEN_ROW = 360,
- TOKEN_ROW_DELIMITER = 361,
- TOKEN_ROWS = 362,
- TOKEN_SECOND = 363,
- TOKEN_SELECT = 364,
- TOKEN_SET = 365,
- TOKEN_SMA = 366,
- TOKEN_SMALLINT = 367,
- TOKEN_SUBSTRING = 368,
- TOKEN_TABLE = 369,
- TOKEN_THEN = 370,
- TOKEN_TIME = 371,
- TOKEN_TIMESTAMP = 372,
- TOKEN_TRUE = 373,
- TOKEN_TUPLESAMPLE = 374,
- TOKEN_UNBOUNDED = 375,
- TOKEN_UNIQUE = 376,
- TOKEN_UPDATE = 377,
- TOKEN_USING = 378,
- TOKEN_VALUES = 379,
- TOKEN_VARCHAR = 380,
- TOKEN_WHEN = 381,
- TOKEN_WHERE = 382,
- TOKEN_WINDOW = 383,
- TOKEN_WITH = 384,
- TOKEN_YEAR = 385,
- TOKEN_YEARMONTH = 386,
- TOKEN_EOF = 387,
- TOKEN_LEX_ERROR = 388
+ TOKEN_CAST = 292,
+ TOKEN_CHARACTER = 293,
+ TOKEN_CHECK = 294,
+ TOKEN_COLUMN = 295,
+ TOKEN_CONSTRAINT = 296,
+ TOKEN_COPY = 297,
+ TOKEN_CREATE = 298,
+ TOKEN_CURRENT = 299,
+ TOKEN_DATE = 300,
+ TOKEN_DATETIME = 301,
+ TOKEN_DAY = 302,
+ TOKEN_DECIMAL = 303,
+ TOKEN_DEFAULT = 304,
+ TOKEN_DELETE = 305,
+ TOKEN_DELIMITER = 306,
+ TOKEN_DESC = 307,
+ TOKEN_DISTINCT = 308,
+ TOKEN_DOUBLE = 309,
+ TOKEN_DROP = 310,
+ TOKEN_ELSE = 311,
+ TOKEN_END = 312,
+ TOKEN_ESCAPE_STRINGS = 313,
+ TOKEN_EXISTS = 314,
+ TOKEN_EXTRACT = 315,
+ TOKEN_FALSE = 316,
+ TOKEN_FIRST = 317,
+ TOKEN_FLOAT = 318,
+ TOKEN_FOLLOWING = 319,
+ TOKEN_FOR = 320,
+ TOKEN_FOREIGN = 321,
+ TOKEN_FROM = 322,
+ TOKEN_FULL = 323,
+ TOKEN_GROUP = 324,
+ TOKEN_HASH = 325,
+ TOKEN_HAVING = 326,
+ TOKEN_HOUR = 327,
+ TOKEN_IN = 328,
+ TOKEN_INDEX = 329,
+ TOKEN_INNER = 330,
+ TOKEN_INSERT = 331,
+ TOKEN_INTEGER = 332,
+ TOKEN_INTERVAL = 333,
+ TOKEN_INTO = 334,
+ TOKEN_JOIN = 335,
+ TOKEN_KEY = 336,
+ TOKEN_LAST = 337,
+ TOKEN_LEFT = 338,
+ TOKEN_LIMIT = 339,
+ TOKEN_LONG = 340,
+ TOKEN_MINUTE = 341,
+ TOKEN_MONTH = 342,
+ TOKEN_NULL = 343,
+ TOKEN_NULLS = 344,
+ TOKEN_OFF = 345,
+ TOKEN_ON = 346,
+ TOKEN_ORDER = 347,
+ TOKEN_OUTER = 348,
+ TOKEN_OVER = 349,
+ TOKEN_PARTITION = 350,
+ TOKEN_PARTITIONS = 351,
+ TOKEN_PERCENT = 352,
+ TOKEN_PRECEDING = 353,
+ TOKEN_PRIMARY = 354,
+ TOKEN_PRIORITY = 355,
+ TOKEN_QUIT = 356,
+ TOKEN_RANGE = 357,
+ TOKEN_REAL = 358,
+ TOKEN_REFERENCES = 359,
+ TOKEN_RIGHT = 360,
+ TOKEN_ROW = 361,
+ TOKEN_ROW_DELIMITER = 362,
+ TOKEN_ROWS = 363,
+ TOKEN_SECOND = 364,
+ TOKEN_SELECT = 365,
+ TOKEN_SET = 366,
+ TOKEN_SMA = 367,
+ TOKEN_SMALLINT = 368,
+ TOKEN_SUBSTRING = 369,
+ TOKEN_TABLE = 370,
+ TOKEN_THEN = 371,
+ TOKEN_TIME = 372,
+ TOKEN_TIMESTAMP = 373,
+ TOKEN_TRUE = 374,
+ TOKEN_TUPLESAMPLE = 375,
+ TOKEN_UNBOUNDED = 376,
+ TOKEN_UNIQUE = 377,
+ TOKEN_UPDATE = 378,
+ TOKEN_USING = 379,
+ TOKEN_VALUES = 380,
+ TOKEN_VARCHAR = 381,
+ TOKEN_WHEN = 382,
+ TOKEN_WHERE = 383,
+ TOKEN_WINDOW = 384,
+ TOKEN_WITH = 385,
+ TOKEN_YEAR = 386,
+ TOKEN_YEARMONTH = 387,
+ TOKEN_EOF = 388,
+ TOKEN_LEX_ERROR = 389
};
#endif
@@ -184,7 +185,7 @@ extern int quickstep_yydebug;
union YYSTYPE
{
-#line 120 "../SqlParser.ypp" /* yacc.c:1915 */
+#line 117 "../SqlParser.ypp" /* yacc.c:1915 */
quickstep::ParseString *string_value_;
@@ -255,7 +256,7 @@ union YYSTYPE
quickstep::ParseStatementQuit *quit_statement_;
const quickstep::Comparison *comparison_;
- const quickstep::UnaryOperation *unary_operation_;
+ quickstep::ParseString *unary_operation_;
const quickstep::BinaryOperation *binary_operation_;
quickstep::ParseFunctionCall *function_call_;
@@ -284,7 +285,7 @@ union YYSTYPE
quickstep::ParsePriority *opt_priority_clause_;
-#line 288 "SqlParser_gen.hpp" /* yacc.c:1915 */
+#line 289 "SqlParser_gen.hpp" /* yacc.c:1915 */
};
typedef union YYSTYPE YYSTYPE;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/query_optimizer/LogicalGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/LogicalGenerator.cpp b/query_optimizer/LogicalGenerator.cpp
index abeca53..49481d3 100644
--- a/query_optimizer/LogicalGenerator.cpp
+++ b/query_optimizer/LogicalGenerator.cpp
@@ -53,7 +53,8 @@ L::LogicalPtr LogicalGenerator::generatePlan(
resolver::Resolver resolver(catalog_database, optimizer_context_);
DVLOG(4) << "Parse tree:\n" << parse_statement.toString();
logical_plan_ = resolver.resolve(parse_statement);
- DVLOG(4) << "Initial logical plan:\n" << logical_plan_->toString();
+ std::cerr << "Initial logical plan:\n" << logical_plan_->toString();
+// exit(0);
optimizePlan();
DVLOG(4) << "Optimized logical plan:\n" << logical_plan_->toString();
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index 35fac90..d7ce686 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -104,7 +104,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions_Cast
quickstep_queryoptimizer_expressions_PatternMatcher
quickstep_queryoptimizer_expressions_Scalar
quickstep_types_Type
- quickstep_types_operations_unaryoperations_NumericCastOperation
+ quickstep_types_operations_unaryoperations_CastOperation
quickstep_utility_Macros)
target_link_libraries(quickstep_queryoptimizer_expressions_ComparisonExpression
glog
@@ -299,8 +299,9 @@ target_link_libraries(quickstep_queryoptimizer_expressions_UnaryExpression
quickstep_queryoptimizer_expressions_ExpressionType
quickstep_queryoptimizer_expressions_PatternMatcher
quickstep_queryoptimizer_expressions_Scalar
+ quickstep_queryoptimizer_expressions_ScalarLiteral
+ quickstep_types_operations_OperationSignature
quickstep_types_operations_unaryoperations_UnaryOperation
- quickstep_types_operations_unaryoperations_UnaryOperationID
quickstep_utility_Macros)
target_link_libraries(quickstep_queryoptimizer_expressions_WindowAggregateFunction
glog
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/query_optimizer/expressions/Cast.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Cast.cpp b/query_optimizer/expressions/Cast.cpp
index c0813c5..7180aa3 100644
--- a/query_optimizer/expressions/Cast.cpp
+++ b/query_optimizer/expressions/Cast.cpp
@@ -32,7 +32,7 @@
#include "query_optimizer/expressions/PatternMatcher.hpp"
#include "query_optimizer/expressions/Scalar.hpp"
#include "types/Type.hpp"
-#include "types/operations/unary_operations/NumericCastOperation.hpp"
+#include "types/operations/unary_operations/CastOperation.hpp"
#include "glog/logging.h"
@@ -51,8 +51,9 @@ ExpressionPtr Cast::copyWithNewChildren(
::quickstep::Scalar *Cast::concretize(
const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
- return new ::quickstep::ScalarUnaryExpression(::quickstep::NumericCastOperation::Instance(target_type_),
- operand_->concretize(substitution_map));
+// return new ::quickstep::ScalarUnaryExpression(::quickstep::NumericCastOperation::Instance(target_type_),
+// operand_->concretize(substitution_map));
+ return nullptr;
}
void Cast::getFieldStringItems(
@@ -62,11 +63,11 @@ void Cast::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 {
- inline_field_names->push_back("target_type");
- inline_field_values->push_back(target_type_.getName());
-
- non_container_child_field_names->push_back("operand");
- non_container_child_fields->push_back(operand_);
+// inline_field_names->push_back("target_type");
+// inline_field_values->push_back(target_type_.getName());
+//
+// non_container_child_field_names->push_back("operand");
+// non_container_child_fields->push_back(operand_);
}
} // namespace expressions
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/query_optimizer/expressions/UnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.cpp b/query_optimizer/expressions/UnaryExpression.cpp
index b0fff62..d7bde71 100644
--- a/query_optimizer/expressions/UnaryExpression.cpp
+++ b/query_optimizer/expressions/UnaryExpression.cpp
@@ -29,8 +29,8 @@
#include "query_optimizer/expressions/Expression.hpp"
#include "query_optimizer/expressions/PatternMatcher.hpp"
#include "query_optimizer/expressions/Scalar.hpp"
+#include "query_optimizer/expressions/ScalarLiteral.hpp"
#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
#include "glog/logging.h"
@@ -39,7 +39,7 @@ namespace optimizer {
namespace expressions {
std::string UnaryExpression::getName() const {
- return operation_.getName();
+ return operation_->getName();
}
ExpressionPtr UnaryExpression::copyWithNewChildren(
@@ -47,13 +47,20 @@ ExpressionPtr UnaryExpression::copyWithNewChildren(
DCHECK_EQ(new_children.size(), children().size());
DCHECK(SomeScalar::Matches(new_children[0]));
return UnaryExpression::Create(
- operation_, std::static_pointer_cast<const Scalar>(new_children[0]));
+ op_signature_,
+ operation_,
+ std::static_pointer_cast<const Scalar>(new_children[0]),
+ static_arguments_,
+ static_argument_types_);
}
::quickstep::Scalar* UnaryExpression::concretize(
const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
return new ::quickstep::ScalarUnaryExpression(
- operation_, operand_->concretize(substitution_map));
+ op_signature_,
+ operation_,
+ operand_->concretize(substitution_map),
+ static_arguments_);
}
void UnaryExpression::getFieldStringItems(
@@ -63,8 +70,21 @@ void UnaryExpression::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 {
- non_container_child_field_names->push_back("Operand");
- non_container_child_fields->push_back(operand_);
+ inline_field_names->emplace_back("op_signature");
+ inline_field_values->emplace_back(op_signature_->toString());
+
+ non_container_child_field_names->emplace_back("operand");
+ non_container_child_fields->emplace_back(operand_);
+
+ 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/27c41625/query_optimizer/expressions/UnaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.hpp b/query_optimizer/expressions/UnaryExpression.hpp
index c4542d0..c08519f 100644
--- a/query_optimizer/expressions/UnaryExpression.hpp
+++ b/query_optimizer/expressions/UnaryExpression.hpp
@@ -30,6 +30,7 @@
#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/unary_operations/UnaryOperation.hpp"
#include "utility/Macros.hpp"
@@ -64,7 +65,7 @@ class UnaryExpression : public Scalar {
/**
* @return The unary operator.
*/
- const UnaryOperation& operation() const { return operation_; }
+ const UnaryOperationPtr& operation() const { return operation_; }
/**
* @return The operand of the unary operator.
@@ -72,7 +73,7 @@ class UnaryExpression : public Scalar {
const ScalarPtr& operand() const { return operand_; }
const Type& getValueType() const override {
- return *(operation_.resultTypeForArgumentType(operand_->getValueType()));
+ return result_type_;
}
ExpressionPtr copyWithNewChildren(
@@ -93,9 +94,18 @@ class UnaryExpression : public Scalar {
* @return An immutable UnaryExpression that applies the operation to the
* operand.
*/
- static UnaryExpressionPtr Create(const UnaryOperation &operation,
- const ScalarPtr &operand) {
- return UnaryExpressionPtr(new UnaryExpression(operation, operand));
+ static UnaryExpressionPtr Create(
+ const OperationSignaturePtr &op_signature,
+ const UnaryOperationPtr &operation,
+ const ScalarPtr &operand,
+ const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+ const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) {
+ return UnaryExpressionPtr(
+ new UnaryExpression(op_signature,
+ operation,
+ operand,
+ static_arguments,
+ static_argument_types));
}
protected:
@@ -108,15 +118,27 @@ class UnaryExpression : public Scalar {
std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
private:
- UnaryExpression(const UnaryOperation &operation,
- const ScalarPtr &operand)
- : operation_(operation), operand_(operand) {
- DCHECK(operation_.canApplyToType(operand_->getValueType())) << toString();
+ UnaryExpression(const OperationSignaturePtr &op_signature,
+ const UnaryOperationPtr &operation,
+ const ScalarPtr &operand,
+ const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+ const std::shared_ptr<const std::vector<const Type*>> &static_argument_types)
+ : op_signature_(op_signature),
+ operation_(operation),
+ operand_(operand),
+ static_arguments_(static_arguments),
+ static_argument_types_(static_argument_types),
+ result_type_(*(operation_->getResultType(operand_->getValueType(), *static_arguments_))) {
+ DCHECK(operation_->canApplyTo(operand_->getValueType(), *static_arguments)) << toString();
addChild(operand);
}
- const UnaryOperation &operation_;
- ScalarPtr operand_;
+ const OperationSignaturePtr op_signature_;
+ const UnaryOperationPtr operation_;
+ const ScalarPtr operand_;
+ const std::shared_ptr<const std::vector<TypedValue>> static_arguments_;
+ const std::shared_ptr<const std::vector<const Type*>> static_argument_types_;
+ const Type &result_type_;
DISALLOW_COPY_AND_ASSIGN(UnaryExpression);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/query_optimizer/resolver/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index a34273e..27497a2 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -121,15 +121,16 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
quickstep_storage_StorageConstants
quickstep_types_IntType
quickstep_types_Type
+ quickstep_types_TypeUtil
quickstep_types_TypedValue
quickstep_types_TypeFactory
+ 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_DateExtractOperation
- quickstep_types_operations_unaryoperations_SubstringOperation
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/27c41625/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index df589fd..1741409 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -22,7 +22,6 @@
#include <algorithm>
#include <map>
#include <memory>
-#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -116,15 +115,16 @@
#include "storage/StorageConstants.hpp"
#include "types/IntType.hpp"
#include "types/Type.hpp"
-#include "types/TypedValue.hpp"
#include "types/TypeFactory.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/TypedValue.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/DateExtractOperation.hpp"
-#include "types/operations/unary_operations/SubstringOperation.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"
@@ -142,6 +142,26 @@ namespace E = ::quickstep::optimizer::expressions;
namespace L = ::quickstep::optimizer::logical;
namespace S = ::quickstep::serialization;
+namespace {
+
+attribute_id GetAttributeIdFromName(const PtrList<ParseAttributeDefinition> &attribute_definition_list,
+ const std::string &attribute_name) {
+ const std::string lower_attribute_name = ToLower(attribute_name);
+
+ attribute_id attr_id = 0;
+ for (const ParseAttributeDefinition &attribute_definition : attribute_definition_list) {
+ if (lower_attribute_name == ToLower(attribute_definition.name()->value())) {
+ return attr_id;
+ }
+
+ ++attr_id;
+ }
+
+ return kInvalidAttributeID;
+}
+
+} // namespace
+
struct Resolver::ExpressionResolutionInfo {
/**
* @brief Constructs an ExpressionResolutionInfo that disallows aggregate
@@ -490,26 +510,6 @@ L::LogicalPtr Resolver::resolveCreateTable(
return L::CreateTable::Create(relation_name, attributes, block_properties, partition_scheme_header_proto);
}
-namespace {
-
-attribute_id GetAttributeIdFromName(const PtrList<ParseAttributeDefinition> &attribute_definition_list,
- const std::string &attribute_name) {
- const std::string lower_attribute_name = ToLower(attribute_name);
-
- attribute_id attr_id = 0;
- for (const ParseAttributeDefinition &attribute_definition : attribute_definition_list) {
- if (lower_attribute_name == ToLower(attribute_definition.name()->value())) {
- return attr_id;
- }
-
- ++attr_id;
- }
-
- return kInvalidAttributeID;
-}
-
-} // namespace
-
StorageBlockLayoutDescription* Resolver::resolveBlockProperties(
const ParseStatementCreateTable &create_table_statement) {
const ParseBlockProperties *block_properties
@@ -2247,57 +2247,6 @@ E::ScalarPtr Resolver::resolveExpression(
type_hint,
expression_resolution_info);
}
- case ParseExpression::kUnaryExpression: {
- const ParseUnaryExpression &parse_unary_expr =
- static_cast<const ParseUnaryExpression&>(parse_expression);
-
- E::ScalarPtr argument = resolveExpression(
- *parse_unary_expr.operand(),
- parse_unary_expr.op().pushDownTypeHint(type_hint),
- expression_resolution_info);
-
- // If the argument is a NULL of unknown Type, try to resolve result Type
- // of this UnaryExpression as follows:
- //
- // 1. If the UnaryExpression can only return one type, then the
- // result is a NULL of that type.
- // 2. If there is a type hint for the UnaryExpression's result, and
- // it is possible for the UnaryExpression to return the hinted
- // type, then the result is a NULL of that type.
- // 3. Otherwise, the result is a NULL of unknown type (i.e.
- // NullType).
- //
- // NOTE(chasseur): As with binary expressions above, step #3 does not
- // always completely capture information about what types the NULL result
- // can take on, since NullType is implicitly convertable to any Type.
- if (argument->getValueType().getTypeID() == kNullType) {
- const Type *fixed_result_type = parse_unary_expr.op().fixedNullableResultType();
- 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_unary_expr.op().resultTypeIsPlausible(nullable_type_hint)) {
- return E::ScalarLiteral::Create(nullable_type_hint.makeNullValue(),
- nullable_type_hint);
- }
- }
-
- const Type &null_type = TypeFactory::GetType(kNullType, true);
- return E::ScalarLiteral::Create(null_type.makeNullValue(),
- null_type);
- }
-
- if (!parse_unary_expr.op().canApplyToType(argument->getValueType())) {
- THROW_SQL_ERROR_AT(&parse_unary_expr)
- << "Can not apply unary operation \"" << parse_unary_expr.op().getName()
- << "\" to argument of type " << argument->getValueType().getName();
- }
-
- return E::UnaryExpression::Create(parse_unary_expr.op(), argument);
- }
case ParseExpression::kFunctionCall: {
return resolveFunctionCall(
static_cast<const ParseFunctionCall&>(parse_expression),
@@ -2311,75 +2260,6 @@ E::ScalarPtr Resolver::resolveExpression(
expression_resolution_info,
true /* has_single_column */);
}
- case ParseExpression::kExtract: {
- const ParseExtractFunction &parse_extract =
- static_cast<const ParseExtractFunction&>(parse_expression);
-
- const ParseString &extract_field = *parse_extract.extract_field();
- const std::string lowered_unit = ToLower(extract_field.value());
- DateExtractUnit extract_unit;
- if (lowered_unit == "year") {
- extract_unit = DateExtractUnit::kYear;
- } else if (lowered_unit == "month") {
- extract_unit = DateExtractUnit::kMonth;
- } else if (lowered_unit == "day") {
- extract_unit = DateExtractUnit::kDay;
- } else if (lowered_unit == "hour") {
- extract_unit = DateExtractUnit::kHour;
- } else if (lowered_unit == "minute") {
- extract_unit = DateExtractUnit::kMinute;
- } else if (lowered_unit == "second") {
- extract_unit = DateExtractUnit::kSecond;
- } else {
- THROW_SQL_ERROR_AT(&extract_field)
- << "Invalid extract unit: " << extract_field.value();
- }
-
- const DateExtractOperation &op = DateExtractOperation::Instance(extract_unit);
- const E::ScalarPtr argument = resolveExpression(
- *parse_extract.date_expression(),
- op.pushDownTypeHint(type_hint),
- expression_resolution_info);
-
- if (!op.canApplyToType(argument->getValueType())) {
- THROW_SQL_ERROR_AT(parse_extract.date_expression())
- << "Can not extract from argument of type: "
- << argument->getValueType().getName();
- }
-
- return E::UnaryExpression::Create(op, argument);
- }
- case ParseExpression::kSubstring: {
- const ParseSubstringFunction &parse_substring =
- static_cast<const ParseSubstringFunction&>(parse_expression);
-
- // Validate start position and substring length.
- if (parse_substring.start_position() <= 0) {
- THROW_SQL_ERROR_AT(&parse_expression)
- << "The start position must be greater than 0";
- }
- if (parse_substring.length() <= 0) {
- THROW_SQL_ERROR_AT(&parse_expression)
- << "The substring length must be greater than 0";
- }
-
- // Convert 1-base position to 0-base position
- const std::size_t zero_base_start_position = parse_substring.start_position() - 1;
- const SubstringOperation &op =
- SubstringOperation::Instance(zero_base_start_position,
- parse_substring.length());
-
- const E::ScalarPtr argument =
- resolveExpression(*parse_substring.operand(),
- op.pushDownTypeHint(type_hint),
- expression_resolution_info);
- if (!op.canApplyToType(argument->getValueType())) {
- THROW_SQL_ERROR_AT(&parse_substring)
- << "Can not apply substring function to argument of type "
- << argument->getValueType().getName();
- }
- return E::UnaryExpression::Create(op, argument);
- }
default:
LOG(FATAL) << "Unknown scalar type: "
<< parse_expression.getExpressionType();
@@ -2639,6 +2519,126 @@ E::ScalarPtr Resolver::resolveSimpleCaseExpression(
*result_data_type);
}
+E::ScalarPtr Resolver::resolveScalarFunction(
+ const ParseFunctionCall &parse_function_call,
+ const std::string &function_name,
+ 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());
+ }
+
+ std::vector<TypedValue> maximal_static_arguments;
+ for (std::size_t i = first_static_argument_position; i < arity; ++i) {
+ maximal_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 {
+ THROW_SQL_ERROR_AT(&parse_function_call) << message;
+ }
+ }
+
+ THROW_SQL_ERROR_AT(&parse_function_call)
+ << "Cannot resolve scalar function";
+
+ return nullptr;
+}
+
// TODO(chasseur): For now this only handles resolving aggregate functions. In
// the future it should be extended to resolve scalar functions as well.
// TODO(Shixuan): This will handle resolving window aggregation function as well,
@@ -2659,8 +2659,7 @@ E::ScalarPtr Resolver::resolveFunctionCall(
}
std::vector<E::ScalarPtr> resolved_arguments;
- const PtrList<ParseExpression> *unresolved_arguments =
- parse_function_call.arguments();
+ const PtrList<ParseExpression> *unresolved_arguments = parse_function_call.arguments();
// The first aggregate function and window aggregate function in the arguments.
const ParseTreeNode *first_aggregate_function = nullptr;
const ParseTreeNode *first_window_aggregate_function = nullptr;
@@ -2668,7 +2667,7 @@ E::ScalarPtr Resolver::resolveFunctionCall(
for (const ParseExpression &unresolved_argument : *unresolved_arguments) {
ExpressionResolutionInfo expr_resolution_info(
*expression_resolution_info);
- resolved_arguments.push_back(
+ resolved_arguments.emplace_back(
resolveExpression(unresolved_argument,
nullptr, // No Type hint.
&expr_resolution_info));
@@ -2687,6 +2686,17 @@ E::ScalarPtr Resolver::resolveFunctionCall(
}
}
+ if (UnaryOperationFactory::Instance().hasUnaryOperation(function_name,
+ resolved_arguments.size())) {
+ E::ScalarPtr scalar = resolveScalarFunction(parse_function_call,
+ function_name,
+ resolved_arguments,
+ expression_resolution_info);
+ expression_resolution_info->parse_aggregate_expression = first_aggregate_function;
+ expression_resolution_info->parse_window_aggregate_expression = first_window_aggregate_function;
+ return scalar;
+ }
+
if (count_star && !resolved_arguments.empty()) {
THROW_SQL_ERROR_AT(&parse_function_call)
<< "COUNT aggregate has both star (*) and non-star arguments.";
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/query_optimizer/resolver/Resolver.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.hpp b/query_optimizer/resolver/Resolver.hpp
index a3d0833..ea26e0c 100644
--- a/query_optimizer/resolver/Resolver.hpp
+++ b/query_optimizer/resolver/Resolver.hpp
@@ -452,9 +452,6 @@ class Resolver {
* @brief Resolves a function call. For a non-scalar function, the returned
* expression is an AttributeReference to the actual resolved expression.
*
- * @note This currently only handles resolving aggregate functions and window
- * aggregate functions.
- *
* @param parse_function_call The function call to be resolved.
* @param expression_resolution_info Resolution info that contains the name
* resolver and info to be updated after
@@ -465,6 +462,12 @@ class Resolver {
const ParseFunctionCall &parse_function_call,
ExpressionResolutionInfo *expression_resolution_info);
+ expressions::ScalarPtr resolveScalarFunction(
+ const ParseFunctionCall &parse_function_call,
+ const std::string &function_name,
+ const std::vector<expressions::ScalarPtr> &resolved_arguments,
+ ExpressionResolutionInfo *expression_resolution_info);
+
/**
* @brief Resolves a window aggregate function.
*
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 769187b..1fac11a 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -49,9 +49,11 @@ 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)
+add_library(quickstep_types_TypeUtil ../empty_src.cpp TypeUtil.hpp)
add_library(quickstep_types_Type_proto ${types_Type_proto_srcs})
add_library(quickstep_types_TypedValue TypedValue.cpp TypedValue.hpp)
add_library(quickstep_types_TypedValue_proto ${types_TypedValue_proto_srcs})
@@ -165,6 +167,8 @@ 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
@@ -182,6 +186,25 @@ target_link_libraries(quickstep_types_TypeFactory
quickstep_types_VarCharType
quickstep_types_YearMonthIntervalType
quickstep_utility_Macros)
+target_link_libraries(quickstep_types_TypeID
+ quickstep_types_Type_proto
+ quickstep_utility_Macros)
+target_link_libraries(quickstep_types_TypeUtil
+ quickstep_types_CharType
+ quickstep_types_DateType
+ quickstep_types_DatetimeIntervalType
+ quickstep_types_DatetimeType
+ quickstep_types_DoubleType
+ quickstep_types_FloatType
+ quickstep_types_IntType
+ quickstep_types_LongType
+ quickstep_types_NullType
+ quickstep_types_Type
+ quickstep_types_TypeID
+ quickstep_types_Type_proto
+ quickstep_types_VarCharType
+ quickstep_types_YearMonthIntervalType
+ quickstep_utility_Macros)
target_link_libraries(quickstep_types_TypedValue
farmhash
glog
@@ -238,6 +261,7 @@ target_link_libraries(quickstep_types
quickstep_types_NumericSuperType
quickstep_types_NumericTypeUnifier
quickstep_types_Type
+ quickstep_types_TypeUtil
quickstep_types_Type_proto
quickstep_types_TypeErrors
quickstep_types_TypeFactory
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/CharType.cpp
----------------------------------------------------------------------
diff --git a/types/CharType.cpp b/types/CharType.cpp
index 591c038..bc05711 100644
--- a/types/CharType.cpp
+++ b/types/CharType.cpp
@@ -66,8 +66,7 @@ const CharType& CharType::InstanceFromProto(const serialization::Type &proto) {
serialization::Type CharType::getProto() const {
serialization::Type proto;
- proto.set_type_id(serialization::Type::CHAR);
-
+ proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
proto.set_nullable(nullable_);
proto.SetExtension(serialization::CharType::length, length_);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index c7321f4..e591953 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 {
+class CharType : public AsciiStringSuperType<kChar, kNonNativeInline> {
public:
/**
* @brief Get a reference to the non-nullable singleton instance of this Type
@@ -134,7 +134,7 @@ class CharType : public AsciiStringSuperType {
private:
CharType(const std::size_t length, const bool nullable)
- : AsciiStringSuperType(kChar, nullable, length, length, length) {
+ : AsciiStringSuperType<kChar, kNonNativeInline>(nullable, length, length, length) {
}
template <bool nullable_internal>
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index 07225d5..a39a28c 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -40,12 +40,8 @@ class TypedValue;
/**
* @brief A type representing the date.
**/
-class DateType : public Type {
+class DateType : public TypeConcept<kDate, false, kNativeEmbedded, DateLit> {
public:
- typedef DateLit cpptype;
-
- static const TypeID kStaticTypeID = kDate;
-
/**
* @brief Get a reference to the non-nullable singleton instance of this
* Type.
@@ -124,7 +120,9 @@ class DateType : public Type {
private:
explicit DateType(const bool nullable)
- : Type(Type::kOther, kDate, nullable, sizeof(DateLit), sizeof(DateLit)) {
+ : TypeConcept<kDate, false, kNativeEmbedded, DateLit>(
+ Type::kOther, kStaticTypeID, nullable,
+ sizeof(DateLit), sizeof(DateLit)) {
}
DISALLOW_COPY_AND_ASSIGN(DateType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index 005cb31..3b22471 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -40,12 +40,9 @@ namespace quickstep {
/**
* @brief A type representing the datetime interval.
**/
-class DatetimeIntervalType : public Type {
+class DatetimeIntervalType :
+ public TypeConcept<kDatetimeInterval, false, kNativeEmbedded, DatetimeIntervalLit> {
public:
- typedef DatetimeIntervalLit cpptype;
-
- static const TypeID kStaticTypeID = kDatetimeInterval;
-
/**
* @brief Get a reference to the non-nullable singleton instance of this
* Type.
@@ -116,7 +113,9 @@ class DatetimeIntervalType : public Type {
private:
explicit DatetimeIntervalType(const bool nullable)
- : Type(Type::kOther, kDatetimeInterval, nullable, sizeof(DatetimeIntervalLit), sizeof(DatetimeIntervalLit)) {
+ : TypeConcept<kDatetimeInterval, false, kNativeEmbedded, DatetimeIntervalLit>(
+ Type::kOther, kStaticTypeID, nullable,
+ sizeof(DatetimeIntervalLit), sizeof(DatetimeIntervalLit)) {
}
DISALLOW_COPY_AND_ASSIGN(DatetimeIntervalType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/DatetimeLit.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeLit.hpp b/types/DatetimeLit.hpp
index 58c852f..db887eb 100644
--- a/types/DatetimeLit.hpp
+++ b/types/DatetimeLit.hpp
@@ -99,6 +99,10 @@ struct DateLit {
inline std::int32_t monthField() const {
return static_cast<std::int32_t>(month);
}
+
+ inline std::int32_t dayField() const {
+ return static_cast<std::int32_t>(day);
+ }
};
/**
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index aad536a..b6742f9 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -40,12 +40,8 @@ class TypedValue;
/**
* @brief A type representing the datetime.
**/
-class DatetimeType : public Type {
+class DatetimeType : public TypeConcept<kDatetime, false, kNativeEmbedded, DatetimeLit> {
public:
- typedef DatetimeLit cpptype;
-
- static const TypeID kStaticTypeID = kDatetime;
-
/**
* @brief Get a reference to the non-nullable singleton instance of this
* Type.
@@ -132,7 +128,9 @@ class DatetimeType : public Type {
private:
explicit DatetimeType(const bool nullable)
- : Type(Type::kOther, kDatetime, nullable, sizeof(DatetimeLit), sizeof(DatetimeLit)) {
+ : TypeConcept<kDatetime, false, kNativeEmbedded, quickstep::DatetimeLit>(
+ Type::kOther, kStaticTypeID, nullable,
+ sizeof(DatetimeLit), sizeof(DatetimeLit)) {
}
DISALLOW_COPY_AND_ASSIGN(DatetimeType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/DoubleType.cpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.cpp b/types/DoubleType.cpp
index 6a7914c..52645f8 100644
--- a/types/DoubleType.cpp
+++ b/types/DoubleType.cpp
@@ -41,8 +41,6 @@ using std::snprintf;
namespace quickstep {
-const TypeID DoubleType::kStaticTypeID = kDouble;
-
bool DoubleType::isSafelyCoercibleFrom(const Type &original_type) const {
QUICKSTEP_NULL_COERCIBILITY_CHECK();
return QUICKSTEP_EQUALS_ANY_CONSTANT(original_type.getTypeID(),
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index b4175b0..4d1dd7e 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -40,10 +40,8 @@ class Type;
/**
* @brief A type representing a double-precision floating-point number.
**/
-class DoubleType : public NumericSuperType<double> {
+class DoubleType : public NumericSuperType<kDouble, double> {
public:
- static const TypeID kStaticTypeID;
-
/**
* @brief Get a reference to the non-nullable singleton instance of this
* Type.
@@ -122,7 +120,7 @@ class DoubleType : public NumericSuperType<double> {
// exponent never takes more than 3 base-10 digits to represent.
explicit DoubleType(const bool nullable)
- : NumericSuperType<double>(kDouble, nullable) {
+ : NumericSuperType<kDouble, double>(nullable) {
}
DISALLOW_COPY_AND_ASSIGN(DoubleType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/FloatType.cpp
----------------------------------------------------------------------
diff --git a/types/FloatType.cpp b/types/FloatType.cpp
index e904f29..3aa2eb9 100644
--- a/types/FloatType.cpp
+++ b/types/FloatType.cpp
@@ -41,8 +41,6 @@ using std::snprintf;
namespace quickstep {
-const TypeID FloatType::kStaticTypeID = kFloat;
-
bool FloatType::isSafelyCoercibleFrom(const Type &original_type) const {
QUICKSTEP_NULL_COERCIBILITY_CHECK();
return QUICKSTEP_EQUALS_ANY_CONSTANT(original_type.getTypeID(),
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 2a156e1..ee9c45c 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -40,10 +40,8 @@ class Type;
/**
* @brief A type representing a single-precision floating-point number.
**/
-class FloatType : public NumericSuperType<float> {
+class FloatType : public NumericSuperType<kFloat, float> {
public:
- static const TypeID kStaticTypeID;
-
/**
* @brief Get a reference to the non-nullable singleton instance of this
* Type.
@@ -122,7 +120,7 @@ class FloatType : public NumericSuperType<float> {
// never takes more than 2 base-10 digits to represent.
explicit FloatType(const bool nullable)
- : NumericSuperType<float>(kFloat, nullable) {
+ : NumericSuperType<kFloat, float>(nullable) {
}
DISALLOW_COPY_AND_ASSIGN(FloatType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/IntType.cpp
----------------------------------------------------------------------
diff --git a/types/IntType.cpp b/types/IntType.cpp
index 9781675..8b7fbb1 100644
--- a/types/IntType.cpp
+++ b/types/IntType.cpp
@@ -32,8 +32,6 @@
namespace quickstep {
-const TypeID IntType::kStaticTypeID = kInt;
-
bool IntType::isSafelyCoercibleFrom(const Type &original_type) const {
QUICKSTEP_NULL_COERCIBILITY_CHECK();
return original_type.getTypeID() == kInt;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index 08d6b3d..25ce3c8 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -40,10 +40,8 @@ class Type;
/**
* @brief A type representing a 32-bit integer.
**/
-class IntType : public NumericSuperType<int> {
+class IntType : public NumericSuperType<kInt, int> {
public:
- static const TypeID kStaticTypeID;
-
/**
* @brief Get a reference to the non-nullable singleton instance of this
* Type.
@@ -109,7 +107,7 @@ class IntType : public NumericSuperType<int> {
private:
explicit IntType(const bool nullable)
- : NumericSuperType<int>(kInt, nullable) {
+ : NumericSuperType<kInt, int>(nullable) {
}
DISALLOW_COPY_AND_ASSIGN(IntType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/LongType.cpp
----------------------------------------------------------------------
diff --git a/types/LongType.cpp b/types/LongType.cpp
index fbf8d30..153e239 100644
--- a/types/LongType.cpp
+++ b/types/LongType.cpp
@@ -38,8 +38,6 @@
namespace quickstep {
-const TypeID LongType::kStaticTypeID = kLong;
-
bool LongType::isSafelyCoercibleFrom(const Type &original_type) const {
QUICKSTEP_NULL_COERCIBILITY_CHECK();
return QUICKSTEP_EQUALS_ANY_CONSTANT(original_type.getTypeID(),
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index a90dd32..52244a7 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -41,10 +41,8 @@ class Type;
/**
* @brief A type representing a 64-bit integer.
**/
-class LongType : public NumericSuperType<std::int64_t> {
+class LongType : public NumericSuperType<kLong, std::int64_t> {
public:
- static const TypeID kStaticTypeID;
-
/**
* @brief Get a reference to the non-nullable singleton instance of this
* Type.
@@ -110,7 +108,7 @@ class LongType : public NumericSuperType<std::int64_t> {
private:
explicit LongType(const bool nullable)
- : NumericSuperType<std::int64_t>(kLong, nullable) {
+ : NumericSuperType<kLong, std::int64_t>(nullable) {
}
DISALLOW_COPY_AND_ASSIGN(LongType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/NullCoercibilityCheckMacro.hpp
----------------------------------------------------------------------
diff --git a/types/NullCoercibilityCheckMacro.hpp b/types/NullCoercibilityCheckMacro.hpp
index 70e1beb..2dcbec3 100644
--- a/types/NullCoercibilityCheckMacro.hpp
+++ b/types/NullCoercibilityCheckMacro.hpp
@@ -34,7 +34,7 @@
**/
#define QUICKSTEP_NULL_COERCIBILITY_CHECK() \
do { \
- if (original_type.isNullable() && !nullable_) { \
+ if (original_type.isNullable() && !this->nullable_) { \
return false; \
} else if (original_type.getTypeID() == kNullType) { \
return true; \
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index c27a584..6c6dd06 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -48,10 +48,8 @@ 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 Type {
+class NullType : public TypeConcept<kNullType, false, kNativeEmbedded> {
public:
- static const TypeID kStaticTypeID = kNullType;
-
/**
* @brief Get a reference to the nullable singleton instance of this Type.
* @note Unlike other Types, there is no corresponding method to get a
@@ -106,7 +104,9 @@ class NullType : public Type {
private:
// NOTE(chasseur): NullType requires 0 bytes of inherent storage. It does,
// however, require a bit in NULL bitmaps.
- NullType() : Type(Type::kOther, kNullType, true, 0, 0) {
+ NullType()
+ : TypeConcept<kNullType, false, kNativeEmbedded>(
+ Type::kOther, kStaticTypeID, true, 0, 0) {
}
DISALLOW_COPY_AND_ASSIGN(NullType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index 0cc1546..ceb24b6 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -38,18 +38,16 @@ namespace quickstep {
* @brief Templatized superclass for Numeric types. Contains code common to all
* Numeric types.
**/
-template <typename CppType>
-class NumericSuperType : public Type {
+template <TypeID type_id, typename CppType>
+class NumericSuperType : public TypeConcept<type_id, false, kNativeEmbedded, CppType> {
public:
- typedef CppType cpptype;
-
std::size_t estimateAverageByteLength() const override {
return sizeof(CppType);
}
bool isCoercibleFrom(const Type &original_type) const override {
QUICKSTEP_NULL_COERCIBILITY_CHECK();
- return (original_type.getSuperTypeID() == kNumeric);
+ return (original_type.getSuperTypeID() == Type::kNumeric);
}
TypedValue makeZeroValue() const override {
@@ -57,8 +55,9 @@ class NumericSuperType : public Type {
}
protected:
- NumericSuperType(const TypeID type_id, const bool nullable)
- : Type(Type::kNumeric, type_id, nullable, sizeof(CppType), sizeof(CppType)) {
+ NumericSuperType(const bool nullable)
+ : TypeConcept<type_id, false, kNativeEmbedded, CppType>(
+ Type::kNumeric, type_id, nullable, sizeof(CppType), sizeof(CppType)) {
}
private:
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index f3d3f1b..144f39a 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -30,38 +30,7 @@ namespace quickstep {
serialization::Type Type::getProto() const {
serialization::Type proto;
- switch (type_id_) {
- case kInt:
- proto.set_type_id(serialization::Type::INT);
- break;
- case kLong:
- proto.set_type_id(serialization::Type::LONG);
- break;
- case kFloat:
- proto.set_type_id(serialization::Type::FLOAT);
- break;
- case kDouble:
- proto.set_type_id(serialization::Type::DOUBLE);
- break;
- case kDate:
- proto.set_type_id(serialization::Type::DATE);
- break;
- case kDatetime:
- proto.set_type_id(serialization::Type::DATETIME);
- break;
- case kDatetimeInterval:
- proto.set_type_id(serialization::Type::DATETIME_INTERVAL);
- break;
- case kYearMonthInterval:
- proto.set_type_id(serialization::Type::YEAR_MONTH_INTERVAL);
- break;
- case kNullType:
- proto.set_type_id(serialization::Type::NULL_TYPE);
- break;
- default:
- FATAL_ERROR("Unrecognized TypeID in Type::getProto");
- }
-
+ proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
proto.set_nullable(nullable_);
return proto;
@@ -85,12 +54,4 @@ TypedValue Type::coerceValue(const TypedValue &original_value,
return original_value;
}
-bool AsciiStringSuperType::isCoercibleFrom(const Type &original_type) const {
- if (original_type.isNullable() && !nullable_) {
- return false;
- }
- return (original_type.getSuperTypeID() == kAsciiString)
- || (original_type.getTypeID() == kNullType);
-}
-
} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index 0e8c4e5..afc46eb 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -264,7 +264,7 @@ class Type {
* @note It is NOT possible to coerce a nullable type to a non-nullable type,
* even if coercion would otherwise be possible.
* @note Integer types are safely coercible to other integer or
- * floating-poin types of equal or greater length.
+ * floating-point types of equal or greater length.
* @note Floating-point types are safely coercible to other floating-point
* types of equal or greater precision.
* @note ASCII string types are safely coercible to other ASCII string types
@@ -471,12 +471,59 @@ class Type {
DISALLOW_COPY_AND_ASSIGN(Type);
};
+template <TypeID type_id,
+ bool parameterized,
+ TypeStorageLayout layout,
+ typename CppType = void>
+class TypeConcept : public Type {
+ public:
+ static constexpr TypeID kStaticTypeID = type_id;
+ static constexpr bool kParameterized = parameterized;
+ static constexpr TypeStorageLayout kLayout = layout;
+
+ typedef CppType cpptype;
+
+ protected:
+ template <typename ...ArgTypes>
+ TypeConcept(ArgTypes &&...args)
+ : Type(std::forward<ArgTypes>(args)...) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeConcept);
+};
+
+
+template <TypeID type_id,
+ bool parameterized,
+ TypeStorageLayout layout,
+ typename CppType>
+constexpr TypeID TypeConcept<type_id, parameterized, layout, CppType>::kStaticTypeID;
+
+template <TypeID type_id,
+ bool parameterized,
+ TypeStorageLayout layout,
+ typename CppType>
+constexpr bool TypeConcept<type_id, parameterized, layout, CppType>::kParameterized;
+
+template <TypeID type_id,
+ bool parameterized,
+ TypeStorageLayout layout,
+ typename CppType>
+constexpr TypeStorageLayout TypeConcept<type_id, parameterized, layout, CppType>::kLayout;
+
/**
* @brief A superclass for ASCII string types.
**/
-class AsciiStringSuperType : public Type {
+template <TypeID type_id, TypeStorageLayout layout>
+class AsciiStringSuperType : public TypeConcept<type_id, true, layout> {
public:
- bool isCoercibleFrom(const Type &original_type) const override;
+ bool isCoercibleFrom(const Type &original_type) const override {
+ if (original_type.isNullable() && !this->nullable_) {
+ return false;
+ }
+ return (original_type.getSuperTypeID() == Type::kAsciiString)
+ || (original_type.getTypeID() == kNullType);
+ }
/**
* @brief Get the character-length of this string type.
@@ -488,12 +535,12 @@ class AsciiStringSuperType : public Type {
}
protected:
- AsciiStringSuperType(const TypeID type_id,
- const bool nullable,
+ AsciiStringSuperType(const bool nullable,
const std::size_t minimum_byte_length,
const std::size_t maximum_byte_length,
const std::size_t string_length)
- : Type(Type::kAsciiString, type_id, nullable, minimum_byte_length, maximum_byte_length),
+ : TypeConcept<type_id, true, layout>(
+ Type::kAsciiString, type_id, nullable, minimum_byte_length, maximum_byte_length),
length_(string_length) {
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index d03b5a4..d454923 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -19,21 +19,11 @@ syntax = "proto2";
package quickstep.serialization;
-message Type {
- enum TypeID {
- INT = 0;
- LONG = 1;
- FLOAT = 2;
- DOUBLE = 3;
- CHAR = 4;
- VAR_CHAR = 5;
- DATETIME = 6;
- DATETIME_INTERVAL = 7;
- YEAR_MONTH_INTERVAL = 8;
- NULL_TYPE = 9;
- DATE = 10;
- }
+message TypeID {
+ required int32 id = 1;
+}
+message Type {
required TypeID type_id = 1;
required bool nullable = 2;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/TypeConcept.hpp
----------------------------------------------------------------------
diff --git a/types/TypeConcept.hpp b/types/TypeConcept.hpp
new file mode 100644
index 0000000..d1ec79d
--- /dev/null
+++ b/types/TypeConcept.hpp
@@ -0,0 +1,33 @@
+/**
+ * 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_TYPE_CONCEPT_HPP_
+#define QUICKSTEP_TYPES_TYPE_CONCEPT_HPP_
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_CONCEPT_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index 7403dc9..df21d50 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -91,21 +91,22 @@ bool TypeFactory::ProtoIsValid(const serialization::Type &proto) {
}
// Check that the type_id is valid, and extensions if any.
- switch (proto.type_id()) {
- case serialization::Type::INT:
- case serialization::Type::LONG:
- case serialization::Type::FLOAT:
- case serialization::Type::DOUBLE:
- case serialization::Type::DATE:
- case serialization::Type::DATETIME:
- case serialization::Type::DATETIME_INTERVAL:
- case serialization::Type::YEAR_MONTH_INTERVAL:
+ const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
+ switch (type_id) {
+ case kInt:
+ case kLong:
+ case kFloat:
+ case kDouble:
+ case kDate:
+ case kDatetime:
+ case kDatetimeInterval:
+ case kYearMonthInterval:
return true;
- case serialization::Type::CHAR:
+ case kChar:
return proto.HasExtension(serialization::CharType::length);
- case serialization::Type::VAR_CHAR:
+ case kVarChar:
return proto.HasExtension(serialization::VarCharType::length);
- case serialization::Type::NULL_TYPE:
+ case kNullType:
return proto.nullable();
default:
return false;
@@ -117,28 +118,29 @@ const Type& TypeFactory::ReconstructFromProto(const serialization::Type &proto)
<< "Attempted to create Type from an invalid proto description:\n"
<< proto.DebugString();
- switch (proto.type_id()) {
- case serialization::Type::INT:
+ const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
+ switch (type_id) {
+ case kInt:
return IntType::Instance(proto.nullable());
- case serialization::Type::LONG:
+ case kLong:
return LongType::Instance(proto.nullable());
- case serialization::Type::FLOAT:
+ case kFloat:
return FloatType::Instance(proto.nullable());
- case serialization::Type::DOUBLE:
+ case kDouble:
return DoubleType::Instance(proto.nullable());
- case serialization::Type::DATE:
+ case kDate:
return DateType::Instance(proto.nullable());
- case serialization::Type::DATETIME:
+ case kDatetime:
return DatetimeType::Instance(proto.nullable());
- case serialization::Type::DATETIME_INTERVAL:
+ case kDatetimeInterval:
return DatetimeIntervalType::Instance(proto.nullable());
- case serialization::Type::YEAR_MONTH_INTERVAL:
+ case kYearMonthInterval:
return YearMonthIntervalType::Instance(proto.nullable());
- case serialization::Type::CHAR:
+ case kChar:
return CharType::InstanceFromProto(proto);
- case serialization::Type::VAR_CHAR:
+ case kVarChar:
return VarCharType::InstanceFromProto(proto);
- case serialization::Type::NULL_TYPE:
+ case kNullType:
DCHECK(proto.nullable());
return NullType::InstanceNullable();
default:
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/TypeID.hpp
----------------------------------------------------------------------
diff --git a/types/TypeID.hpp b/types/TypeID.hpp
index c54d8a5..26731b9 100644
--- a/types/TypeID.hpp
+++ b/types/TypeID.hpp
@@ -21,6 +21,10 @@
#define QUICKSTEP_TYPES_TYPE_ID_HPP_
#include <cstddef>
+#include <type_traits>
+
+#include "types/Type.pb.h"
+#include "utility/Macros.hpp"
namespace quickstep {
@@ -29,7 +33,7 @@ namespace quickstep {
*
* @note TypedValue assumes that this doesn't exceed 64 TypeIDs.
**/
-enum TypeID {
+enum TypeID : int {
kInt = 0,
kLong,
kFloat,
@@ -44,6 +48,13 @@ enum TypeID {
kNumTypeIDs // Not a real TypeID, exists for counting purposes.
};
+enum TypeStorageLayout {
+ kNativeEmbedded,
+ kNativeInline,
+ kNonNativeInline,
+ kOutOfLine
+};
+
/**
* @brief Provides basic information about a Type in the Quickstep type system.
*
@@ -65,6 +76,26 @@ struct TypeSignature {
**/
extern const char *kTypeNames[kNumTypeIDs];
+class TypeIDFactory {
+ public:
+ inline static serialization::TypeID GetProto(const TypeID type_id) {
+ serialization::TypeID proto;
+ proto.set_id(static_cast<std::underlying_type_t<TypeID>>(type_id));
+ return proto;
+ }
+
+ inline static TypeID ReconstructFromProto(const serialization::TypeID &proto) {
+ return static_cast<TypeID>(proto.id());
+ }
+
+ inline static bool ProtoIsValid(const serialization::TypeID &proto) {
+ return proto.id() < static_cast<std::underlying_type_t<TypeID>>(kNumTypeIDs);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeIDFactory);
+};
+
} // namespace quickstep
#endif // QUICKSTEP_TYPES_TYPE_ID_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
new file mode 100644
index 0000000..fe55952
--- /dev/null
+++ b/types/TypeUtil.hpp
@@ -0,0 +1,181 @@
+/**
+ * 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_TYPE_UTIL_HPP_
+#define QUICKSTEP_TYPES_TYPE_UTIL_HPP_
+
+#include <type_traits>
+
+#include "types/CharType.hpp"
+#include "types/DateType.hpp"
+#include "types/DatetimeIntervalType.hpp"
+#include "types/DatetimeType.hpp"
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/NullType.hpp"
+#include "types/Type.hpp"
+#include "types/Type.pb.h"
+#include "types/TypeID.hpp"
+#include "types/VarCharType.hpp"
+#include "types/YearMonthIntervalType.hpp"
+#include "utility/Macros.hpp"
+#include "utility/TemplateUtil.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+template <TypeID type_id>
+struct TypeGenerator {};
+
+#define REGISTER_TYPE(T) \
+ template <> struct TypeGenerator<T::kStaticTypeID> { typedef T type; };
+
+REGISTER_TYPE(IntType);
+REGISTER_TYPE(LongType);
+REGISTER_TYPE(FloatType);
+REGISTER_TYPE(DoubleType);
+REGISTER_TYPE(DateType);
+REGISTER_TYPE(DatetimeType);
+REGISTER_TYPE(DatetimeIntervalType);
+REGISTER_TYPE(YearMonthIntervalType);
+REGISTER_TYPE(CharType);
+REGISTER_TYPE(VarCharType);
+REGISTER_TYPE(NullType);
+
+#undef REGISTER_TYPE
+
+namespace type_util_internal {
+
+template <bool require_parameterized>
+struct TypeIDSelectorParameterizedHelper {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+ inline static auto Invoke(const FunctorT &functor)
+ -> decltype(functor(TypeIDConstant())) {
+ DLOG(FATAL) << "Unexpected TypeID: "
+ << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+ }
+ };
+};
+
+template <bool require_non_parameterized>
+template <typename TypeIDConstant, typename FunctorT>
+struct TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementation<
+ TypeIDConstant, FunctorT,
+ std::enable_if_t<TypeGenerator<TypeIDConstant::value>::type::kParameterized
+ ^ require_non_parameterized>> {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+};
+
+} // namespace type_util_internal
+
+struct TypeIDSelectorAll {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+ };
+};
+
+using TypeIDSelectorNonParameterized =
+ type_util_internal::TypeIDSelectorParameterizedHelper<true>;
+
+using TypeIDSelectorParameterized =
+ type_util_internal::TypeIDSelectorParameterizedHelper<false>;
+
+template <TypeID ...candidates>
+struct TypeIDSelectorEqualsAny {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+ inline static auto Invoke(const FunctorT &functor)
+ -> decltype(functor(TypeIDConstant())) {
+ DLOG(FATAL) << "Unexpected TypeID: "
+ << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+ }
+ };
+};
+
+template <TypeID ...candidates>
+template <typename TypeIDConstant, typename FunctorT>
+struct TypeIDSelectorEqualsAny<candidates...>::Implementation<
+ TypeIDConstant, FunctorT,
+ std::enable_if_t<
+ EqualsAny<TypeIDConstant,
+ std::integral_constant<TypeID, candidates>...>::value>> {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+};
+
+template <typename Selector = TypeIDSelectorAll, typename FunctorT>
+inline auto InvokeOnTypeID(const TypeID type_id,
+ const FunctorT &functor) {
+#define REGISTER_TYPE_ID(type_id) \
+ case type_id: \
+ return Selector::template Implementation< \
+ std::integral_constant<TypeID, type_id>, FunctorT>::Invoke(functor)
+
+ switch (type_id) {
+
+ REGISTER_TYPE_ID(kInt);
+ REGISTER_TYPE_ID(kLong);
+ REGISTER_TYPE_ID(kFloat);
+ REGISTER_TYPE_ID(kDouble);
+ REGISTER_TYPE_ID(kDate);
+ REGISTER_TYPE_ID(kDatetime);
+ REGISTER_TYPE_ID(kDatetimeInterval);
+ REGISTER_TYPE_ID(kYearMonthInterval);
+ REGISTER_TYPE_ID(kChar);
+ REGISTER_TYPE_ID(kVarChar);
+ REGISTER_TYPE_ID(kNullType);
+
+ default:
+ FATAL_ERROR("Unrecognized TypeID in InvokeOnTypeID()");
+ }
+
+#undef REGISTER_TYPE_ID
+}
+
+class TypeUtil {
+ public:
+ static bool IsParameterized(const TypeID type_id) {
+ return InvokeOnTypeID(
+ type_id,
+ [&](auto tid) -> bool { // NOLINT(build/c++11)
+ return TypeGenerator<decltype(tid)::value>::type::kParameterized;
+ });
+ }
+
+ private:
+ TypeUtil() {}
+
+ DISALLOW_COPY_AND_ASSIGN(TypeUtil);
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_UTIL_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/TypedValue.cpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.cpp b/types/TypedValue.cpp
index 8dd8b60..1360237 100644
--- a/types/TypedValue.cpp
+++ b/types/TypedValue.cpp
@@ -82,33 +82,29 @@ serialization::TypedValue TypedValue::getProto() const {
// NOTE(chasseur): To represent a NULL value, only the 'type_id' field of the
// proto is filled in, and all the optional value fields are omitted.
+ proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(getTypeID()));
switch (getTypeID()) {
case kInt:
- proto.set_type_id(serialization::Type::INT);
if (!isNull()) {
proto.set_int_value(getLiteral<int>());
}
break;
case kLong:
- proto.set_type_id(serialization::Type::LONG);
if (!isNull()) {
proto.set_long_value(getLiteral<std::int64_t>());
}
break;
case kFloat:
- proto.set_type_id(serialization::Type::FLOAT);
if (!isNull()) {
proto.set_float_value(getLiteral<float>());
}
break;
case kDouble:
- proto.set_type_id(serialization::Type::DOUBLE);
if (!isNull()) {
proto.set_double_value(getLiteral<double>());
}
break;
case kDate:
- proto.set_type_id(serialization::Type::DATE);
if (!isNull()) {
serialization::TypedValue::DateLit *literal_date_proto = proto.mutable_date_value();
literal_date_proto->set_year(value_union_.date_value.year);
@@ -117,37 +113,31 @@ serialization::TypedValue TypedValue::getProto() const {
}
break;
case kDatetime:
- proto.set_type_id(serialization::Type::DATETIME);
if (!isNull()) {
proto.set_datetime_value(value_union_.datetime_value.ticks);
}
break;
case kDatetimeInterval:
- proto.set_type_id(serialization::Type::DATETIME_INTERVAL);
if (!isNull()) {
proto.set_datetime_interval_value(value_union_.datetime_interval_value.interval_ticks);
}
break;
case kYearMonthInterval:
- proto.set_type_id(serialization::Type::YEAR_MONTH_INTERVAL);
if (!isNull()) {
proto.set_year_month_interval_value(value_union_.year_month_interval_value.months);
}
break;
case kChar:
- proto.set_type_id(serialization::Type::CHAR);
if (!isNull()) {
proto.set_out_of_line_data(static_cast<const char*>(getOutOfLineData()), getDataSize());
}
break;
case kVarChar:
- proto.set_type_id(serialization::Type::VAR_CHAR);
if (!isNull()) {
proto.set_out_of_line_data(static_cast<const char*>(getOutOfLineData()), getDataSize());
}
break;
case kNullType:
- proto.set_type_id(serialization::Type::NULL_TYPE);
DCHECK(isNull());
break;
default:
@@ -166,24 +156,25 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
<< "Attempted to create TypedValue from an invalid proto description:\n"
<< proto.DebugString();
- switch (proto.type_id()) {
- case serialization::Type::INT:
+ const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
+ switch (type_id) {
+ case kInt:
return proto.has_int_value() ?
TypedValue(static_cast<int>(proto.int_value())) :
TypedValue(kInt);
- case serialization::Type::LONG:
+ case kLong:
return proto.has_long_value() ?
TypedValue(static_cast<std::int64_t>(proto.long_value())) :
TypedValue(kLong);
- case serialization::Type::FLOAT:
+ case kFloat:
return proto.has_float_value() ?
TypedValue(static_cast<float>(proto.float_value())) :
TypedValue(kFloat);
- case serialization::Type::DOUBLE:
+ case kDouble:
return proto.has_double_value() ?
TypedValue(static_cast<double>(proto.double_value())) :
TypedValue(kDouble);
- case serialization::Type::DATE:
+ case kDate:
if (proto.has_date_value()) {
return TypedValue(DateLit::Create(proto.date_value().year(),
proto.date_value().month(),
@@ -191,7 +182,7 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
} else {
return TypedValue(kDate);
}
- case serialization::Type::DATETIME:
+ case kDatetime:
if (proto.has_datetime_value()) {
DatetimeLit datetime;
datetime.ticks = proto.datetime_value();
@@ -199,7 +190,7 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
} else {
return TypedValue(kDatetime);
}
- case serialization::Type::DATETIME_INTERVAL:
+ case kDatetimeInterval:
if (proto.has_datetime_interval_value()) {
DatetimeIntervalLit interval;
interval.interval_ticks = proto.datetime_interval_value();
@@ -207,7 +198,7 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
} else {
return TypedValue(kDatetimeInterval);
}
- case serialization::Type::YEAR_MONTH_INTERVAL:
+ case kYearMonthInterval:
if (proto.has_year_month_interval_value()) {
YearMonthIntervalLit interval;
interval.months = proto.year_month_interval_value();
@@ -215,19 +206,19 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
} else {
return TypedValue(kYearMonthInterval);
}
- case serialization::Type::CHAR:
+ case kChar:
return proto.has_out_of_line_data() ?
TypedValue(kChar,
static_cast<const void*>(proto.out_of_line_data().c_str()),
proto.out_of_line_data().size()).ensureNotReference() :
TypedValue(kChar);
- case serialization::Type::VAR_CHAR:
+ case kVarChar:
return proto.has_out_of_line_data() ?
TypedValue(kVarChar,
static_cast<const void*>(proto.out_of_line_data().c_str()),
proto.out_of_line_data().size()).ensureNotReference() :
TypedValue(kVarChar);
- case serialization::Type::NULL_TYPE:
+ case kNullType:
return TypedValue(kNullType);
default:
FATAL_ERROR("Unrecognized TypeID in TypedValue::ReconstructFromProto");
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/TypedValue.hpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.hpp b/types/TypedValue.hpp
index 0ba3d53..18ed4af 100644
--- a/types/TypedValue.hpp
+++ b/types/TypedValue.hpp
@@ -264,9 +264,9 @@ class TypedValue {
* TypedValue will take ownership of this memory.
* @param value_size The number of bytes of data at value_ptr.
**/
- static TypedValue CreateWithOwnedData(const TypeID type_id,
- void *value_ptr,
- const std::size_t value_size) {
+ inline static TypedValue CreateWithOwnedData(const TypeID type_id,
+ void *value_ptr,
+ const std::size_t value_size) {
TypedValue val(type_id, value_ptr, value_size);
val.value_info_ |= kOwnershipMask;
return val;
@@ -467,7 +467,8 @@ class TypedValue {
* @return The underlying literal value represented by this TypedValue.
**/
template <typename LiteralType>
- LiteralType getLiteral() const;
+ LiteralType getLiteral() const {
+ }
/**
* @brief Get the out-of-line data which this TypedValue points to.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/TypedValue.proto
----------------------------------------------------------------------
diff --git a/types/TypedValue.proto b/types/TypedValue.proto
index 7f3ab7a..db44dec 100644
--- a/types/TypedValue.proto
+++ b/types/TypedValue.proto
@@ -22,7 +22,7 @@ package quickstep.serialization;
import "types/Type.proto";
message TypedValue {
- required Type.TypeID type_id = 1;
+ required TypeID type_id = 1;
// NOTE(zuyu): For a NULL value, none of the optional fields are filled in.
optional int32 int_value = 2;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/VarCharType.cpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.cpp b/types/VarCharType.cpp
index 02845b1..05162cf 100644
--- a/types/VarCharType.cpp
+++ b/types/VarCharType.cpp
@@ -66,8 +66,7 @@ const VarCharType& VarCharType::InstanceFromProto(const serialization::Type &pro
serialization::Type VarCharType::getProto() const {
serialization::Type proto;
- proto.set_type_id(serialization::Type::VAR_CHAR);
-
+ proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
proto.set_nullable(nullable_);
proto.SetExtension(serialization::VarCharType::length, length_);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index bb50e92..af3ab64 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 {
+class VarCharType : public AsciiStringSuperType<kVarChar, kOutOfLine> {
public:
/**
* @brief Get a reference to the non-nullable singleton instance of this Type
@@ -137,7 +137,7 @@ class VarCharType : public AsciiStringSuperType {
private:
VarCharType(const std::size_t length, const bool nullable)
- : AsciiStringSuperType(kVarChar, nullable, 1, length + 1, length) {
+ : AsciiStringSuperType<kVarChar, kOutOfLine>(nullable, 1, length + 1, length) {
}
template <bool nullable_internal>
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index a2ba175..f768046 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -39,12 +39,9 @@ namespace quickstep {
/**
* @brief A type representing the year-month interval.
**/
-class YearMonthIntervalType : public Type {
+class YearMonthIntervalType :
+ public TypeConcept<kYearMonthInterval, false, kNativeEmbedded, YearMonthIntervalLit> {
public:
- typedef YearMonthIntervalLit cpptype;
-
- static const TypeID kStaticTypeID = kYearMonthInterval;
-
/**
* @brief Get a reference to the non-nullable singleton instance of this
* Type.
@@ -115,7 +112,9 @@ class YearMonthIntervalType : public Type {
private:
explicit YearMonthIntervalType(const bool nullable)
- : Type(Type::kOther, kYearMonthInterval, nullable, sizeof(YearMonthIntervalLit), sizeof(YearMonthIntervalLit)) {
+ : TypeConcept<kYearMonthInterval, false, kNativeEmbedded, YearMonthIntervalLit>(
+ Type::kOther, kStaticTypeID, nullable,
+ sizeof(YearMonthIntervalLit), sizeof(YearMonthIntervalLit)) {
}
DISALLOW_COPY_AND_ASSIGN(YearMonthIntervalType);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/27c41625/types/containers/ColumnVector.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp
index fc65656..f0a2cd5 100644
--- a/types/containers/ColumnVector.hpp
+++ b/types/containers/ColumnVector.hpp
@@ -130,8 +130,8 @@ class NativeColumnVector : public ColumnVector {
NativeColumnVector(const Type &type, const std::size_t reserved_length)
: ColumnVector(type),
type_length_(type.maximumByteLength()),
- values_(std::malloc(type.maximumByteLength() * reserved_length)),
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_));
@@ -385,8 +385,9 @@ class NativeColumnVector : public ColumnVector {
private:
const std::size_t type_length_;
- void *values_;
const std::size_t reserved_length_;
+
+ void *values_;
std::size_t actual_length_;
std::unique_ptr<BitVector<false>> null_bitmap_;
@@ -498,6 +499,12 @@ class IndirectColumnVector : public ColumnVector {
values_.emplace_back(std::move(value));
}
+ inline void appendNullValue() {
+ DCHECK(type_.isNullable());
+ DCHECK_LT(values_.size(), reserved_length_);
+ values_.emplace_back(type_.makeNullValue());
+ }
+
/**
* @brief Fill this entire ColumnVector with copies of value.
*
@@ -559,6 +566,7 @@ class IndirectColumnVector : public ColumnVector {
private:
const bool type_is_nullable_;
const std::size_t reserved_length_;
+
std::vector<TypedValue> values_;
DISALLOW_COPY_AND_ASSIGN(IndirectColumnVector);