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/04/12 19:34:26 UTC
[23/27] incubator-quickstep git commit: Refactor type system and
operations.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index 07225d5..088c125 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -27,6 +27,7 @@
#include "types/DatetimeLit.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
@@ -40,73 +41,14 @@ class TypedValue;
/**
* @brief A type representing the date.
**/
-class DateType : public Type {
+class DateType : public TypeSynthesizer<kDate> {
public:
- typedef DateLit cpptype;
-
- static const TypeID kStaticTypeID = kDate;
-
- /**
- * @brief Get a reference to the non-nullable singleton instance of this
- * Type.
- *
- * @return A reference to the non-nullable singleton instance of this Type.
- **/
- static const DateType& InstanceNonNullable() {
- static DateType instance(false);
- return instance;
- }
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type.
- *
- * @return A reference to the nullable singleton instance of this Type.
- **/
- static const DateType& InstanceNullable() {
- static DateType instance(true);
- return instance;
- }
-
- /**
- * @brief Get a reference to a singleton instance of this Type.
- *
- * @param nullable Whether to get the nullable version of this Type.
- * @return A reference to the desired singleton instance of this Type.
- **/
- static const DateType& Instance(const bool nullable) {
- if (nullable) {
- return InstanceNullable();
- } else {
- return InstanceNonNullable();
- }
- }
-
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable();
- }
-
- std::size_t estimateAverageByteLength() const override {
- return sizeof(DateLit);
- }
-
- bool isCoercibleFrom(const Type &original_type) const override;
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
int getPrintWidth() const override {
return DateLit::kIsoChars;
}
std::string printValueToString(const TypedValue &value) const override;
- void printValueToFile(const TypedValue &value,
- FILE *file,
- const int padding = 0) const override;
-
/**
* @note value_string is expected to be in (possibly extended) ISO-8601
* format. Extended ISO-8601 date format is "YYYY-MM-DD". YYYY is an
@@ -124,8 +66,9 @@ class DateType : public Type {
private:
explicit DateType(const bool nullable)
- : Type(Type::kOther, kDate, nullable, sizeof(DateLit), sizeof(DateLit)) {
- }
+ : TypeSynthesizer<kDate>(nullable) {}
+
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(DateType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/DatetimeIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.cpp b/types/DatetimeIntervalType.cpp
index 1eae03a..2c77f89 100644
--- a/types/DatetimeIntervalType.cpp
+++ b/types/DatetimeIntervalType.cpp
@@ -31,7 +31,6 @@
#include "types/IntervalLit.hpp"
#include "types/IntervalParser.hpp"
-#include "types/NullCoercibilityCheckMacro.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
@@ -47,16 +46,6 @@ using std::snprintf;
namespace quickstep {
-bool DatetimeIntervalType::isCoercibleFrom(const Type &original_type) const {
- QUICKSTEP_NULL_COERCIBILITY_CHECK();
- return (original_type.getTypeID() == kDatetimeInterval);
-}
-
-bool DatetimeIntervalType::isSafelyCoercibleFrom(const Type &original_type) const {
- QUICKSTEP_NULL_COERCIBILITY_CHECK();
- return (original_type.getTypeID() == kDatetimeInterval);
-}
-
std::string DatetimeIntervalType::printValueToString(const TypedValue &value) const {
DCHECK(!value.isNull());
@@ -121,14 +110,6 @@ std::string DatetimeIntervalType::printValueToString(const TypedValue &value) co
return std::string(interval_buf);
}
-void DatetimeIntervalType::printValueToFile(const TypedValue &value,
- FILE *file,
- const int padding) const {
- // We simply re-use the logic from printValueToString(), as trying to do
- // padding on-the fly with so many different fields is too much of a hassle.
- std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
-}
-
bool DatetimeIntervalType::parseValueFromString(const std::string &value_string,
TypedValue *value) const {
// Try simple-format parse first.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index 005cb31..d22f965 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -28,6 +28,7 @@
#include "types/IntervalLit.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"
@@ -40,73 +41,14 @@ namespace quickstep {
/**
* @brief A type representing the datetime interval.
**/
-class DatetimeIntervalType : public Type {
+class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
public:
- typedef DatetimeIntervalLit cpptype;
-
- static const TypeID kStaticTypeID = kDatetimeInterval;
-
- /**
- * @brief Get a reference to the non-nullable singleton instance of this
- * Type.
- *
- * @return A reference to the non-nullable singleton instance of this Type.
- **/
- static const DatetimeIntervalType& InstanceNonNullable() {
- static DatetimeIntervalType instance(false);
- return instance;
- }
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type.
- *
- * @return A reference to the nullable singleton instance of this Type.
- **/
- static const DatetimeIntervalType& InstanceNullable() {
- static DatetimeIntervalType instance(true);
- return instance;
- }
-
- /**
- * @brief Get a reference to a singleton instance of this Type.
- *
- * @param nullable Whether to get the nullable version of this Type.
- * @return A reference to the desired singleton instance of this Type.
- **/
- static const DatetimeIntervalType& Instance(const bool nullable) {
- if (nullable) {
- return InstanceNullable();
- } else {
- return InstanceNonNullable();
- }
- }
-
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable();
- }
-
- std::size_t estimateAverageByteLength() const override {
- return sizeof(DatetimeIntervalLit);
- }
-
- bool isCoercibleFrom(const Type &original_type) const override;
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
int getPrintWidth() const override {
return DatetimeIntervalLit::kPrintingChars;
}
std::string printValueToString(const TypedValue &value) const override;
- void printValueToFile(const TypedValue &value,
- FILE *file,
- const int padding = 0) const override;
-
TypedValue makeZeroValue() const override {
return TypedValue(DatetimeIntervalLit{0});
}
@@ -116,8 +58,9 @@ class DatetimeIntervalType : public Type {
private:
explicit DatetimeIntervalType(const bool nullable)
- : Type(Type::kOther, kDatetimeInterval, nullable, sizeof(DatetimeIntervalLit), sizeof(DatetimeIntervalLit)) {
- }
+ : TypeSynthesizer<kDatetimeInterval>(nullable) {}
+
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(DatetimeIntervalType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/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/da9baf7e/types/DatetimeType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.cpp b/types/DatetimeType.cpp
index f54f318..723da61 100644
--- a/types/DatetimeType.cpp
+++ b/types/DatetimeType.cpp
@@ -33,7 +33,6 @@
#include <string>
#include "types/DatetimeLit.hpp"
-#include "types/NullCoercibilityCheckMacro.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
@@ -51,16 +50,6 @@ using std::snprintf;
namespace quickstep {
-bool DatetimeType::isCoercibleFrom(const Type &original_type) const {
- QUICKSTEP_NULL_COERCIBILITY_CHECK();
- return (original_type.getTypeID() == kDatetime);
-}
-
-bool DatetimeType::isSafelyCoercibleFrom(const Type &original_type) const {
- QUICKSTEP_NULL_COERCIBILITY_CHECK();
- return (original_type.getTypeID() == kDatetime);
-}
-
std::string DatetimeType::printValueToString(const TypedValue &value) const {
DCHECK(!value.isNull());
@@ -114,14 +103,6 @@ std::string DatetimeType::printValueToString(const TypedValue &value) const {
return std::string(datebuf);
}
-void DatetimeType::printValueToFile(const TypedValue &value,
- FILE *file,
- const int padding) const {
- // We simply re-use the logic from printValueToString(), as trying to do
- // padding on-the fly with so many different fields is too much of a hassle.
- std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
-}
-
bool DatetimeType::parseValueFromString(const std::string &value_string,
TypedValue *value) const {
int year;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index aad536a..6ee15c6 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -27,6 +27,7 @@
#include "types/DatetimeLit.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
@@ -40,73 +41,15 @@ class TypedValue;
/**
* @brief A type representing the datetime.
**/
-class DatetimeType : public Type {
+class DatetimeType
+ : public TypeSynthesizer<kDatetime> {
public:
- typedef DatetimeLit cpptype;
-
- static const TypeID kStaticTypeID = kDatetime;
-
- /**
- * @brief Get a reference to the non-nullable singleton instance of this
- * Type.
- *
- * @return A reference to the non-nullable singleton instance of this Type.
- **/
- static const DatetimeType& InstanceNonNullable() {
- static DatetimeType instance(false);
- return instance;
- }
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type.
- *
- * @return A reference to the nullable singleton instance of this Type.
- **/
- static const DatetimeType& InstanceNullable() {
- static DatetimeType instance(true);
- return instance;
- }
-
- /**
- * @brief Get a reference to a singleton instance of this Type.
- *
- * @param nullable Whether to get the nullable version of this Type.
- * @return A reference to the desired singleton instance of this Type.
- **/
- static const DatetimeType& Instance(const bool nullable) {
- if (nullable) {
- return InstanceNullable();
- } else {
- return InstanceNonNullable();
- }
- }
-
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable();
- }
-
- std::size_t estimateAverageByteLength() const override {
- return sizeof(DatetimeLit);
- }
-
- bool isCoercibleFrom(const Type &original_type) const override;
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
int getPrintWidth() const override {
return DatetimeLit::kIsoChars;
}
std::string printValueToString(const TypedValue &value) const override;
- void printValueToFile(const TypedValue &value,
- FILE *file,
- const int padding = 0) const override;
-
/**
* @note value_string is expected to be in (possibly extended) ISO-8601
* format. Extended ISO-8601 format is one of the following:
@@ -132,8 +75,9 @@ class DatetimeType : public Type {
private:
explicit DatetimeType(const bool nullable)
- : Type(Type::kOther, kDatetime, nullable, sizeof(DatetimeLit), sizeof(DatetimeLit)) {
- }
+ : TypeSynthesizer<kDatetime>(nullable) {}
+
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(DatetimeType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/DoubleType.cpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.cpp b/types/DoubleType.cpp
index 6a7914c..f5c2650 100644
--- a/types/DoubleType.cpp
+++ b/types/DoubleType.cpp
@@ -25,11 +25,8 @@
#include <limits>
#include <string>
-#include "types/NullCoercibilityCheckMacro.hpp"
-#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
-#include "utility/EqualsAnyConstant.hpp"
#include "glog/logging.h"
@@ -41,39 +38,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(),
- kInt, kLong, kFloat, kDouble);
-}
-
-TypedValue DoubleType::coerceValue(const TypedValue &original_value,
- const Type &original_type) const {
- DCHECK(isCoercibleFrom(original_type))
- << "Can't coerce value of Type " << original_type.getName()
- << " to Type " << getName();
-
- if (original_value.isNull()) {
- return makeNullValue();
- }
-
- switch (original_type.getTypeID()) {
- case kInt:
- return TypedValue(static_cast<double>(original_value.getLiteral<int>()));
- case kLong:
- return TypedValue(static_cast<double>(original_value.getLiteral<std::int64_t>()));
- case kFloat:
- return TypedValue(static_cast<double>(original_value.getLiteral<float>()));
- case kDouble:
- return original_value;
- default:
- LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
- << " (not recognized as a numeric Type) to " << getName();
- }
-}
-
std::string DoubleType::printValueToString(const TypedValue &value) const {
DCHECK(!value.isNull());
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index b4175b0..05bec64 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -26,12 +26,12 @@
#include "types/NumericSuperType.hpp"
#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
class Type;
+class TypedValue;
/** \addtogroup Types
* @{
@@ -40,55 +40,8 @@ class Type;
/**
* @brief A type representing a double-precision floating-point number.
**/
-class DoubleType : public NumericSuperType<double> {
+class DoubleType : public NumericSuperType<kDouble> {
public:
- static const TypeID kStaticTypeID;
-
- /**
- * @brief Get a reference to the non-nullable singleton instance of this
- * Type.
- *
- * @return A reference to the non-nullable singleton instance of this Type.
- **/
- static const DoubleType& InstanceNonNullable() {
- static DoubleType instance(false);
- return instance;
- }
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type.
- *
- * @return A reference to the nullable singleton instance of this Type.
- **/
- static const DoubleType& InstanceNullable() {
- static DoubleType instance(true);
- return instance;
- }
-
- /**
- * @brief Get a reference to a singleton instance of this Type.
- *
- * @param nullable Whether to get the nullable version of this Type.
- * @return A reference to the desired singleton instance of this Type.
- **/
- static const DoubleType& Instance(const bool nullable) {
- if (nullable) {
- return InstanceNullable();
- } else {
- return InstanceNonNullable();
- }
- }
-
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable();
- }
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
int getPrintWidth() const override {
return kPrintWidth;
}
@@ -102,9 +55,6 @@ class DoubleType : public NumericSuperType<double> {
bool parseValueFromString(const std::string &value_string,
TypedValue *value) const override;
- TypedValue coerceValue(const TypedValue &original_value,
- const Type &original_type) const override;
-
private:
static_assert((std::numeric_limits<double>::max_exponent10 < 1000)
&& (std::numeric_limits<double>::min_exponent10 > -1000),
@@ -122,8 +72,9 @@ 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>(nullable) {}
+
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(DoubleType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/FloatType.cpp
----------------------------------------------------------------------
diff --git a/types/FloatType.cpp b/types/FloatType.cpp
index e904f29..be22770 100644
--- a/types/FloatType.cpp
+++ b/types/FloatType.cpp
@@ -25,11 +25,8 @@
#include <limits>
#include <string>
-#include "types/NullCoercibilityCheckMacro.hpp"
-#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
-#include "utility/EqualsAnyConstant.hpp"
#include "glog/logging.h"
@@ -41,39 +38,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(),
- kInt, kFloat);
-}
-
-TypedValue FloatType::coerceValue(const TypedValue &original_value,
- const Type &original_type) const {
- DCHECK(isCoercibleFrom(original_type))
- << "Can't coerce value of Type " << original_type.getName()
- << " to Type " << getName();
-
- if (original_value.isNull()) {
- return makeNullValue();
- }
-
- switch (original_type.getTypeID()) {
- case kInt:
- return TypedValue(static_cast<float>(original_value.getLiteral<int>()));
- case kLong:
- return TypedValue(static_cast<float>(original_value.getLiteral<std::int64_t>()));
- case kFloat:
- return original_value;
- case kDouble:
- return TypedValue(static_cast<float>(original_value.getLiteral<double>()));
- default:
- LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
- << " (not recognized as a numeric Type) to " << getName();
- }
-}
-
std::string FloatType::printValueToString(const TypedValue &value) const {
DCHECK(!value.isNull());
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 2a156e1..6c8466d 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -26,12 +26,12 @@
#include "types/NumericSuperType.hpp"
#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
class Type;
+class TypedValue;
/** \addtogroup Types
* @{
@@ -40,55 +40,8 @@ class Type;
/**
* @brief A type representing a single-precision floating-point number.
**/
-class FloatType : public NumericSuperType<float> {
+class FloatType : public NumericSuperType<kFloat> {
public:
- static const TypeID kStaticTypeID;
-
- /**
- * @brief Get a reference to the non-nullable singleton instance of this
- * Type.
- *
- * @return A reference to the non-nullable singleton instance of this Type
- **/
- static const FloatType& InstanceNonNullable() {
- static FloatType instance(false);
- return instance;
- }
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type
- *
- * @return A reference to the nullable singleton instance of this Type
- **/
- static const FloatType& InstanceNullable() {
- static FloatType instance(true);
- return instance;
- }
-
- /**
- * @brief Get a reference to a singleton instance of this Type
- *
- * @param nullable Whether to get the nullable version of this Type
- * @return A reference to the desired singleton instance of this Type
- **/
- static const FloatType& Instance(const bool nullable) {
- if (nullable) {
- return InstanceNullable();
- } else {
- return InstanceNonNullable();
- }
- }
-
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable();
- }
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
int getPrintWidth() const override {
return kPrintWidth;
}
@@ -102,9 +55,6 @@ class FloatType : public NumericSuperType<float> {
bool parseValueFromString(const std::string &value_string,
TypedValue *value) const override;
- TypedValue coerceValue(const TypedValue &original_value,
- const Type &original_type) const override;
-
private:
static_assert((std::numeric_limits<float>::max_exponent10 < 100)
&& (std::numeric_limits<float>::min_exponent10 > -100),
@@ -122,8 +72,9 @@ 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>(nullable) {}
+
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(FloatType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/IntType.cpp
----------------------------------------------------------------------
diff --git a/types/IntType.cpp b/types/IntType.cpp
index 9781675..1005aa9 100644
--- a/types/IntType.cpp
+++ b/types/IntType.cpp
@@ -19,12 +19,9 @@
#include "types/IntType.hpp"
-#include <cstdint>
#include <cstdio>
#include <string>
-#include "types/NullCoercibilityCheckMacro.hpp"
-#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
@@ -32,38 +29,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;
-}
-
-TypedValue IntType::coerceValue(const TypedValue &original_value,
- const Type &original_type) const {
- DCHECK(isCoercibleFrom(original_type))
- << "Can't coerce value of Type " << original_type.getName()
- << " to Type " << getName();
-
- if (original_value.isNull()) {
- return makeNullValue();
- }
-
- switch (original_type.getTypeID()) {
- case kInt:
- return original_value;
- case kLong:
- return TypedValue(static_cast<int>(original_value.getLiteral<std::int64_t>()));
- case kFloat:
- return TypedValue(static_cast<int>(original_value.getLiteral<float>()));
- case kDouble:
- return TypedValue(static_cast<int>(original_value.getLiteral<double>()));
- default:
- LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
- << " (not recognized as a numeric Type) to " << getName();
- }
-}
-
std::string IntType::printValueToString(const TypedValue &value) const {
DCHECK(!value.isNull());
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index 08d6b3d..84cc7ce 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -26,12 +26,12 @@
#include "types/NumericSuperType.hpp"
#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
class Type;
+class TypedValue;
/** \addtogroup Types
* @{
@@ -40,55 +40,8 @@ class Type;
/**
* @brief A type representing a 32-bit integer.
**/
-class IntType : public NumericSuperType<int> {
+class IntType : public NumericSuperType<kInt> {
public:
- static const TypeID kStaticTypeID;
-
- /**
- * @brief Get a reference to the non-nullable singleton instance of this
- * Type.
- *
- * @return A reference to the non-nullable singleton instance of this Type.
- **/
- static const IntType& InstanceNonNullable() {
- static IntType instance(false);
- return instance;
- }
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type.
- *
- * @return A reference to the nullable singleton instance of this Type.
- **/
- static const IntType& InstanceNullable() {
- static IntType instance(true);
- return instance;
- }
-
- /**
- * @brief Get a reference to a singleton instance of this Type.
- *
- * @param nullable Whether to get the nullable version of this Type.
- * @return A reference to the desired singleton instance of this Type.
- **/
- static const IntType& Instance(const bool nullable) {
- if (nullable) {
- return InstanceNullable();
- } else {
- return InstanceNonNullable();
- }
- }
-
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable();
- }
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
int getPrintWidth() const override {
// Fully represented digits, single leading digit, and possible '-'
// character.
@@ -104,13 +57,11 @@ class IntType : public NumericSuperType<int> {
bool parseValueFromString(const std::string &value_string,
TypedValue *value) const override;
- TypedValue coerceValue(const TypedValue &original_value,
- const Type &original_type) const override;
-
private:
explicit IntType(const bool nullable)
- : NumericSuperType<int>(kInt, nullable) {
- }
+ : NumericSuperType<kInt>(nullable) {}
+
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(IntType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/LongType.cpp
----------------------------------------------------------------------
diff --git a/types/LongType.cpp b/types/LongType.cpp
index fbf8d30..334821d 100644
--- a/types/LongType.cpp
+++ b/types/LongType.cpp
@@ -28,49 +28,13 @@
#include <cstdio>
#include <string>
-#include "types/NullCoercibilityCheckMacro.hpp"
-#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
-#include "utility/EqualsAnyConstant.hpp"
#include "glog/logging.h"
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(),
- kInt, kLong);
-}
-
-TypedValue LongType::coerceValue(const TypedValue &original_value,
- const Type &original_type) const {
- DCHECK(isCoercibleFrom(original_type))
- << "Can't coerce value of Type " << original_type.getName()
- << " to Type " << getName();
-
- if (original_value.isNull()) {
- return makeNullValue();
- }
-
- switch (original_type.getTypeID()) {
- case kInt:
- return TypedValue(static_cast<std::int64_t>(original_value.getLiteral<int>()));
- case kLong:
- return original_value;
- case kFloat:
- return TypedValue(static_cast<std::int64_t>(original_value.getLiteral<float>()));
- case kDouble:
- return TypedValue(static_cast<std::int64_t>(original_value.getLiteral<double>()));
- default:
- LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
- << " (not recognized as a numeric Type) to " << getName();
- }
-}
-
std::string LongType::printValueToString(const TypedValue &value) const {
DCHECK(!value.isNull());
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index a90dd32..e52a166 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -27,12 +27,12 @@
#include "types/NumericSuperType.hpp"
#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
class Type;
+class TypedValue;
/** \addtogroup Types
* @{
@@ -41,55 +41,8 @@ class Type;
/**
* @brief A type representing a 64-bit integer.
**/
-class LongType : public NumericSuperType<std::int64_t> {
+class LongType : public NumericSuperType<kLong> {
public:
- static const TypeID kStaticTypeID;
-
- /**
- * @brief Get a reference to the non-nullable singleton instance of this
- * Type.
- *
- * @return A reference to the non-nullable singleton instance of this Type.
- **/
- static const LongType& InstanceNonNullable() {
- static LongType instance(false);
- return instance;
- }
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type.
- *
- * @return A reference to the nullable singleton instance of this Type.
- **/
- static const LongType& InstanceNullable() {
- static LongType instance(true);
- return instance;
- }
-
- /**
- * @brief Get a reference to a singleton instance of this Type.
- *
- * @param nullable Whether to get the nullable version of this Type.
- * @return A reference to the desired singleton instance of this Type.
- **/
- static const LongType& Instance(const bool nullable) {
- if (nullable) {
- return InstanceNullable();
- } else {
- return InstanceNonNullable();
- }
- }
-
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable();
- }
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
// Fully represented digits, single leading digit, and possible '-'
// character.
int getPrintWidth() const override {
@@ -105,13 +58,11 @@ class LongType : public NumericSuperType<std::int64_t> {
bool parseValueFromString(const std::string &value_string,
TypedValue *value) const override;
- TypedValue coerceValue(const TypedValue &original_value,
- const Type &original_type) const override;
-
private:
explicit LongType(const bool nullable)
- : NumericSuperType<std::int64_t>(kLong, nullable) {
- }
+ : NumericSuperType<kLong>(nullable) {}
+
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(LongType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/NullCoercibilityCheckMacro.hpp
----------------------------------------------------------------------
diff --git a/types/NullCoercibilityCheckMacro.hpp b/types/NullCoercibilityCheckMacro.hpp
index 70e1beb..9cdd152 100644
--- a/types/NullCoercibilityCheckMacro.hpp
+++ b/types/NullCoercibilityCheckMacro.hpp
@@ -20,9 +20,6 @@
#ifndef QUICKSTEP_TYPES_NULL_COERCIBILITY_CHECK_MACRO_HPP_
#define QUICKSTEP_TYPES_NULL_COERCIBILITY_CHECK_MACRO_HPP_
-#include "types/Type.hpp"
-#include "types/TypeID.hpp"
-
/** \addtogroup Types
* @{
*/
@@ -34,7 +31,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/da9baf7e/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index c27a584..c416a05 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -26,6 +26,7 @@
#include "types/Type.hpp"
#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
#include "utility/Macros.hpp"
#include "glog/logging.h"
@@ -48,40 +49,20 @@ 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 TypeSynthesizer<kNullType> {
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
- * non-nullable version of NullType. NullType is ALWAYS nullable.
- *
- * @return A reference to the nullable singleton instance of this Type.
- **/
- static const NullType& InstanceNullable() {
- static NullType instance;
- return instance;
+ static const NullType& InstanceNonNullable() {
+ LOG(FATAL) << "Called NullType::InstanceNonNullable(), "
+ << "which is not allowed.";
}
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- LOG(FATAL) << "Called NullType::getNonNullableVersion(), which is not allowed.";
- }
-
- std::size_t estimateAverageByteLength() const override {
- return 0;
- }
-
- bool isCoercibleFrom(const Type &original_type) const override {
- return original_type.getTypeID() == kNullType;
- }
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override {
- return original_type.getTypeID() == kNullType;
+ static const NullType& Instance(const bool nullable) {
+ if (nullable) {
+ return InstanceNullable();
+ } else {
+ LOG(FATAL) << "Called NullType::Instance(nullable = true), "
+ << "which is not allowed.";
+ }
}
int getPrintWidth() const override {
@@ -106,9 +87,13 @@ 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(const bool nullable)
+ : TypeSynthesizer<kNullType>(nullable, 0, 0) {
+ DCHECK(nullable);
}
+ template <typename, bool> friend class TypeInstance;
+
DISALLOW_COPY_AND_ASSIGN(NullType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index 0cc1546..abe8b87 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -21,12 +21,17 @@
#define QUICKSTEP_TYPES_NUMERIC_SUPER_TYPE_HPP_
#include <cstddef>
+#include <unordered_set>
#include "types/NullCoercibilityCheckMacro.hpp"
+#include "types/NumericTypeSafeCoercibility.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "types/TypeSynthesizer.hpp"
#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"
+#include "utility/meta/TMP.hpp"
namespace quickstep {
@@ -38,30 +43,72 @@ 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>
+class NumericSuperType : public TypeSynthesizer<type_id> {
public:
- typedef CppType cpptype;
-
- std::size_t estimateAverageByteLength() const override {
- return sizeof(CppType);
+ bool isSafelyCoercibleFrom(const Type &original_type) const override {
+ QUICKSTEP_NULL_COERCIBILITY_CHECK();
+ const auto it = safe_coerce_cache_.find(original_type.getTypeID());
+ return it != safe_coerce_cache_.end();
}
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 {
- return TypedValue(static_cast<CppType>(0));
+ return TypedValue(static_cast<typename TypeIDTrait<type_id>::cpptype>(0));
}
- protected:
- NumericSuperType(const TypeID type_id, const bool nullable)
- : Type(Type::kNumeric, type_id, nullable, sizeof(CppType), sizeof(CppType)) {
+ TypedValue coerceValue(const TypedValue &original_value,
+ const Type &original_type) const override {
+ if (original_type.getSuperTypeID() != Type::kNumeric) {
+ LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
+ << " (not recognized as a numeric Type) to " << Type::getName();
+ }
+
+ if (original_value.isNull()) {
+ return Type::makeNullValue();
+ }
+
+ return InvokeOnTypeID<TypeIDSelectorNumeric>(
+ original_type.getTypeID(),
+ [&](auto orig_tid) -> TypedValue { // NOLINT(build/c++11)
+ using OrigCppType = typename TypeIDTrait<decltype(orig_tid)::value>::cpptype;
+ using TargetCppType = typename TypeIDTrait<type_id>::cpptype;
+
+ return TypedValue(
+ static_cast<TargetCppType>(original_value.getLiteral<OrigCppType>()));
+ });
}
+ protected:
+ explicit NumericSuperType(const bool nullable)
+ : TypeSynthesizer<type_id>(nullable),
+ safe_coerce_cache_(CreateSafeCoercibilityCache()) {}
+
private:
+ using TargetType = typename TypeIDTrait<type_id>::TypeClass;
+
+ template <typename SourceTypeID>
+ struct SafeCoercibilityFilter {
+ static constexpr bool value =
+ NumericTypeSafeCoercibility<
+ typename TypeIDTrait<SourceTypeID::value>::TypeClass,
+ TargetType>::value;
+ };
+
+ inline static auto CreateSafeCoercibilityCache() {
+ using SourceTypeIDs = TypeIDSequenceAll::template bind_to<meta::TypeList>;
+ using ResultTypeIDs = SourceTypeIDs::template filter<SafeCoercibilityFilter>;
+
+ return ResultTypeIDs::template as_sequence<TypeID>
+ ::template Instantiate<std::unordered_set<TypeID>>();
+ };
+
+ const std::unordered_set<TypeID> safe_coerce_cache_;
+
DISALLOW_COPY_AND_ASSIGN(NumericSuperType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/NumericTypeSafeCoercibility.hpp
----------------------------------------------------------------------
diff --git a/types/NumericTypeSafeCoercibility.hpp b/types/NumericTypeSafeCoercibility.hpp
new file mode 100644
index 0000000..914927c
--- /dev/null
+++ b/types/NumericTypeSafeCoercibility.hpp
@@ -0,0 +1,61 @@
+/**
+ * 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_NUMERIC_TYPE_SAFE_COERCIBILITY_HPP_
+#define QUICKSTEP_TYPES_NUMERIC_TYPE_SAFE_COERCIBILITY_HPP_
+
+#include "utility/meta/TMP.hpp"
+
+namespace quickstep {
+
+class BoolType;
+class DoubleType;
+class FloatType;
+class IntType;
+class LongType;
+
+/** \addtogroup Types
+ * @{
+ */
+
+template <typename LeftType, typename RightType>
+using IsSafelyCoercible = meta::TypeList<LeftType, RightType>;
+
+using NumericTypeSafeCoersionPartialOrder = meta::TypeList<
+ IsSafelyCoercible<BoolType, IntType>,
+ IsSafelyCoercible<IntType, FloatType>,
+ IsSafelyCoercible<IntType, LongType>,
+ IsSafelyCoercible<FloatType, DoubleType>,
+ IsSafelyCoercible<LongType, DoubleType>>;
+
+using NumericTypeSafeCoersionClosure =
+ meta::TransitiveClosure<NumericTypeSafeCoersionPartialOrder>;
+
+template <typename LeftType, typename RightType>
+struct NumericTypeSafeCoercibility {
+ static constexpr bool value =
+ NumericTypeSafeCoersionClosure::contains<
+ IsSafelyCoercible<LeftType, RightType>>::value;
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_NUMERIC_TYPE_SAFE_COERCIBILITY_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/NumericTypeUnifier.hpp
----------------------------------------------------------------------
diff --git a/types/NumericTypeUnifier.hpp b/types/NumericTypeUnifier.hpp
index 168dfb1..0c3f13f 100644
--- a/types/NumericTypeUnifier.hpp
+++ b/types/NumericTypeUnifier.hpp
@@ -20,16 +20,9 @@
#ifndef QUICKSTEP_TYPES_NUMERIC_TYPE_UNIFIER_HPP_
#define QUICKSTEP_TYPES_NUMERIC_TYPE_UNIFIER_HPP_
-namespace quickstep {
-
-class DoubleType;
-class FloatType;
-class IntType;
-class LongType;
+#include "types/NumericTypeSafeCoercibility.hpp"
-/** \addtogroup Types
- * @{
- */
+namespace quickstep {
/**
* @brief A traits template that resolves what the "unifying" Type of two
@@ -51,92 +44,47 @@ class LongType;
* @tparam RightType The second Quickstep numeric Type class to unify.
**/
template <typename LeftType, typename RightType>
-struct NumericTypeUnifier {
-};
+struct NumericTypeUnifier;
-/** @} */
-// Explicit template specializations for all combinations of builtin numeric
-// types.
-template<>
-struct NumericTypeUnifier<IntType, IntType> {
- typedef IntType type;
-};
+namespace internal {
-template<>
-struct NumericTypeUnifier<IntType, LongType> {
- typedef LongType type;
-};
-
-template<>
-struct NumericTypeUnifier<IntType, FloatType> {
- typedef FloatType type;
-};
+template <typename LeftType, typename RightType, typename EnableT = void>
+struct NumericTypeUnifierHelper;
-template<>
-struct NumericTypeUnifier<IntType, DoubleType> {
- typedef DoubleType type;
-};
-
-template<>
-struct NumericTypeUnifier<LongType, IntType> {
- typedef LongType type;
-};
-
-template<>
-struct NumericTypeUnifier<LongType, LongType> {
- typedef LongType type;
-};
-
-template<>
-struct NumericTypeUnifier<LongType, FloatType> {
- typedef DoubleType type;
-};
-
-template<>
-struct NumericTypeUnifier<LongType, DoubleType> {
- typedef DoubleType type;
-};
-
-template<>
-struct NumericTypeUnifier<FloatType, IntType> {
- typedef FloatType type;
-};
-
-template<>
-struct NumericTypeUnifier<FloatType, LongType> {
- typedef DoubleType type;
+template <typename LeftType, typename RightType>
+struct NumericTypeUnifierHelper<
+ LeftType, RightType,
+ std::enable_if_t<NumericTypeSafeCoercibility<LeftType, RightType>::value>> {
+ typedef RightType type;
};
-template<>
-struct NumericTypeUnifier<FloatType, FloatType> {
- typedef FloatType type;
+template <typename LeftType, typename RightType>
+struct NumericTypeUnifierHelper<
+ LeftType, RightType,
+ std::enable_if_t<!std::is_same<LeftType, RightType>::value &&
+ NumericTypeSafeCoercibility<RightType, LeftType>::value>> {
+ typedef LeftType type;
};
+// Explicit template specializations
template<>
-struct NumericTypeUnifier<FloatType, DoubleType> {
+struct NumericTypeUnifierHelper<LongType, FloatType> {
typedef DoubleType type;
};
template<>
-struct NumericTypeUnifier<DoubleType, IntType> {
+struct NumericTypeUnifierHelper<FloatType, LongType> {
typedef DoubleType type;
};
-template<>
-struct NumericTypeUnifier<DoubleType, LongType> {
- typedef DoubleType type;
-};
+} // namespace internal
-template<>
-struct NumericTypeUnifier<DoubleType, FloatType> {
- typedef DoubleType type;
-};
+template <typename LeftType, typename RightType>
+struct NumericTypeUnifier
+ : internal::NumericTypeUnifierHelper<LeftType, RightType> {};
-template<>
-struct NumericTypeUnifier<DoubleType, DoubleType> {
- typedef DoubleType type;
-};
+/** @} */
} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index f3d3f1b..b69cb65 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -28,43 +28,35 @@
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");
+bool Type::isCoercibleFrom(const Type &original_type) const {
+ return isSafelyCoercibleFrom(original_type);
+}
+
+bool Type::isSafelyCoercibleFrom(const Type &original_type) const {
+ if (original_type.isNullable() && !this->nullable_) {
+ return false;
}
+ if (original_type.getTypeID() == kNullType) {
+ return true;
+ }
+ return (original_type.getTypeID() == type_id_);
+}
- proto.set_nullable(nullable_);
+std::size_t Type::estimateAverageByteLength() const {
+ if (minimum_byte_length_ == maximum_byte_length_) {
+ return maximum_byte_length_;
+ }
+ if (maximum_byte_length_ > 160) {
+ return 80;
+ } else {
+ return (maximum_byte_length_ >> 1) + 1;
+ }
+}
- return proto;
+void Type::printValueToFile(const TypedValue &value,
+ FILE *file,
+ const int padding) const {
+ std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
}
TypedValue Type::coerceValue(const TypedValue &original_value,
@@ -85,12 +77,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/da9baf7e/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index 0e8c4e5..bf6c167 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -112,7 +112,7 @@ class Type {
*
* @return The serialized Protocol Buffer representation of this Type.
**/
- virtual serialization::Type getProto() const;
+ virtual serialization::Type getProto() const = 0;
/**
* @brief Determine what supertype this type belongs to.
@@ -154,16 +154,7 @@ class Type {
TypeSignature sig;
sig.id = type_id_;
sig.nullable = nullable_;
- switch (type_id_) {
- case kChar:
- sig.length = maximum_byte_length_;
- break;
- case kVarChar:
- sig.length = maximum_byte_length_ - 1;
- break;
- default:
- sig.length = 0;
- }
+ sig.length = parameter_;
return sig;
}
@@ -227,7 +218,7 @@ class Type {
* @return An estimate of the average number of bytes used by data items of
* this type.
**/
- virtual std::size_t estimateAverageByteLength() const = 0;
+ virtual std::size_t estimateAverageByteLength() const;
/**
* @brief Determine whether this Type is exactly the same as another.
@@ -255,7 +246,7 @@ class Type {
* @param original_type The original Type for coercion to this Type.
* @return true if coercion is supported, false otherwise.
**/
- virtual bool isCoercibleFrom(const Type &original_type) const = 0;
+ virtual bool isCoercibleFrom(const Type &original_type) const;
/**
* @brief Determine whether data items of another type can be coerced (used
@@ -264,7 +255,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
@@ -277,7 +268,7 @@ class Type {
* @param original_type The original Type for coercion to this Type.
* @return true if coercion is supported, false otherwise.
**/
- virtual bool isSafelyCoercibleFrom(const Type &original_type) const = 0;
+ virtual bool isSafelyCoercibleFrom(const Type &original_type) const;
/**
* @brief Determine whether data items of this type are always guaranteed to
@@ -348,7 +339,7 @@ class Type {
**/
virtual void printValueToFile(const TypedValue &value,
FILE *file,
- const int padding = 0) const = 0;
+ const int padding = 0) const;
/**
* @brief Make a TypedValue of this Type.
@@ -453,10 +444,12 @@ class Type {
const TypeID type_id,
const bool nullable,
const std::size_t minimum_byte_length,
- const std::size_t maximum_byte_length)
+ const std::size_t maximum_byte_length,
+ const std::size_t parameter = 0)
: super_type_id_(super_type_id),
type_id_(type_id),
nullable_(nullable),
+ parameter_(parameter),
minimum_byte_length_(minimum_byte_length),
maximum_byte_length_(maximum_byte_length) {
}
@@ -464,6 +457,7 @@ class Type {
const SuperTypeID super_type_id_;
const TypeID type_id_;
const bool nullable_;
+ const std::size_t parameter_;
const std::size_t minimum_byte_length_;
const std::size_t maximum_byte_length_;
@@ -471,38 +465,6 @@ class Type {
DISALLOW_COPY_AND_ASSIGN(Type);
};
-/**
- * @brief A superclass for ASCII string types.
- **/
-class AsciiStringSuperType : public Type {
- public:
- bool isCoercibleFrom(const Type &original_type) const override;
-
- /**
- * @brief Get the character-length of this string type.
- *
- * @return The maximum length of a string of this type.
- **/
- inline std::size_t getStringLength() const {
- return length_;
- }
-
- protected:
- AsciiStringSuperType(const TypeID type_id,
- 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),
- length_(string_length) {
- }
-
- const std::size_t length_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AsciiStringSuperType);
-};
-
/** @} */
} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index d03b5a4..ed8df36 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -19,39 +19,13 @@ 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;
-
- // The convention for extension numbering is that extensions for a particular
- // TypeID should begin from (type_id + 1) * 32.
- extensions 32 to max;
+ optional uint64 length = 3;
}
-message CharType {
- extend Type {
- // Required when type_id == CHAR.
- optional uint64 length = 160;
- }
-}
-
-message VarCharType {
- extend Type {
- // Required when type_id == VAR_CHAR.
- optional uint64 length = 192;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index 7403dc9..66efc92 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -22,66 +22,45 @@
#include <cstddef>
#include <string>
-#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 "types/TypeUtil.hpp"
#include "utility/Macros.hpp"
#include "glog/logging.h"
namespace quickstep {
+bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
+ return TypeUtil::IsParameterized(id);
+}
+
const Type& TypeFactory::GetType(const TypeID id,
const bool nullable) {
- switch (id) {
- case kInt:
- return IntType::Instance(nullable);
- case kLong:
- return LongType::Instance(nullable);
- case kFloat:
- return FloatType::Instance(nullable);
- case kDouble:
- return DoubleType::Instance(nullable);
- case kDate:
- return DateType::Instance(nullable);
- case kDatetime:
- return DatetimeType::Instance(nullable);
- case kDatetimeInterval:
- return DatetimeIntervalType::Instance(nullable);
- case kYearMonthInterval:
- return YearMonthIntervalType::Instance(nullable);
- case kNullType:
- DCHECK(nullable);
- return NullType::InstanceNullable();
- default:
- FATAL_ERROR("Called TypeFactory::GetType() for a type which requires "
- " a length parameter without specifying one.");
- }
+ DCHECK(!TypeRequiresLengthParameter(id))
+ << "Called TypeFactory::GetType() for a type which requires "
+ << " a length parameter without specifying one.";
+
+ return *InvokeOnTypeID<TypeIDSelectorNonParameterized>(
+ id,
+ [&](auto id) -> const Type* { // NOLINT(build/c++11)
+ return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable);
+ });
}
const Type& TypeFactory::GetType(const TypeID id,
const std::size_t length,
const bool nullable) {
- switch (id) {
- case kChar:
- return CharType::Instance(length, nullable);
- case kVarChar:
- return VarCharType::Instance(length, nullable);
- default:
- FATAL_ERROR("Provided a length parameter to TypeFactory::GetType() for "
- "a type which does not take one.");
- }
+ DCHECK(TypeRequiresLengthParameter(id))
+ << "Provided a length parameter to TypeFactory::GetType() for "
+ << "a type which does not take one.";
+
+ return *InvokeOnTypeID<TypeIDSelectorParameterized>(
+ id,
+ [&](auto id) -> const Type* { // NOLINT(build/c++11)
+ return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, length);
+ });
}
bool TypeFactory::ProtoIsValid(const serialization::Type &proto) {
@@ -90,26 +69,18 @@ bool TypeFactory::ProtoIsValid(const serialization::Type &proto) {
return false;
}
- // 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:
- return true;
- case serialization::Type::CHAR:
- return proto.HasExtension(serialization::CharType::length);
- case serialization::Type::VAR_CHAR:
- return proto.HasExtension(serialization::VarCharType::length);
- case serialization::Type::NULL_TYPE:
- return proto.nullable();
- default:
- return false;
+ // Check that the type_id is valid, and has length if parameterized.
+ const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
+
+ if (type_id == kNullType) {
+ return proto.nullable();
+ }
+
+ if (TypeRequiresLengthParameter(type_id)) {
+ return proto.has_length();
}
+
+ return true;
}
const Type& TypeFactory::ReconstructFromProto(const serialization::Type &proto) {
@@ -117,32 +88,12 @@ 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:
- return IntType::Instance(proto.nullable());
- case serialization::Type::LONG:
- return LongType::Instance(proto.nullable());
- case serialization::Type::FLOAT:
- return FloatType::Instance(proto.nullable());
- case serialization::Type::DOUBLE:
- return DoubleType::Instance(proto.nullable());
- case serialization::Type::DATE:
- return DateType::Instance(proto.nullable());
- case serialization::Type::DATETIME:
- return DatetimeType::Instance(proto.nullable());
- case serialization::Type::DATETIME_INTERVAL:
- return DatetimeIntervalType::Instance(proto.nullable());
- case serialization::Type::YEAR_MONTH_INTERVAL:
- return YearMonthIntervalType::Instance(proto.nullable());
- case serialization::Type::CHAR:
- return CharType::InstanceFromProto(proto);
- case serialization::Type::VAR_CHAR:
- return VarCharType::InstanceFromProto(proto);
- case serialization::Type::NULL_TYPE:
- DCHECK(proto.nullable());
- return NullType::InstanceNullable();
- default:
- FATAL_ERROR("Unrecognized TypeID in TypeFactory::ReconstructFromProto");
+ const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
+
+ if (TypeRequiresLengthParameter(type_id)) {
+ return GetType(type_id, proto.length(), proto.nullable());
+ } else {
+ return GetType(type_id, proto.nullable());
}
}
@@ -157,9 +108,11 @@ const Type* TypeFactory::GetMostSpecificType(const Type &first, const Type &seco
}
const Type* TypeFactory::GetUnifyingType(const Type &first, const Type &second) {
+ // TODO: cache
const Type *unifier = nullptr;
if (first.isNullable() || second.isNullable()) {
- unifier = GetMostSpecificType(first.getNullableVersion(), second.getNullableVersion());
+ unifier = GetMostSpecificType(first.getNullableVersion(),
+ second.getNullableVersion());
if (unifier == nullptr) {
if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
|| ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/TypeFactory.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.hpp b/types/TypeFactory.hpp
index 742348e..89ff497 100644
--- a/types/TypeFactory.hpp
+++ b/types/TypeFactory.hpp
@@ -48,25 +48,7 @@ class TypeFactory {
* @param id The id of the desired Type.
* @return Whether a length must be specified for Types of the given id.
**/
- static bool TypeRequiresLengthParameter(const TypeID id) {
- switch (id) {
- case kInt:
- case kLong:
- case kFloat:
- case kDouble:
- case kDate:
- case kDatetime:
- case kDatetimeInterval:
- case kYearMonthInterval:
- case kNullType:
- return false;
- case kChar:
- case kVarChar:
- return true;
- default:
- FATAL_ERROR("Unrecognized TypeID in TypeFactory::TypeRequiresLengthParameter");
- }
- }
+ static bool TypeRequiresLengthParameter(const TypeID id);
/**
* @brief Factory method to get a Type by its TypeID.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/TypeID.cpp
----------------------------------------------------------------------
diff --git a/types/TypeID.cpp b/types/TypeID.cpp
index ff2f8e6..afc9c2b 100644
--- a/types/TypeID.cpp
+++ b/types/TypeID.cpp
@@ -22,6 +22,7 @@
namespace quickstep {
const char *kTypeNames[] = {
+ "Bool",
"Int",
"Long",
"Float",
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/TypeID.hpp
----------------------------------------------------------------------
diff --git a/types/TypeID.hpp b/types/TypeID.hpp
index c54d8a5..d27368c 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,8 +33,9 @@ namespace quickstep {
*
* @note TypedValue assumes that this doesn't exceed 64 TypeIDs.
**/
-enum TypeID {
- kInt = 0,
+enum TypeID : int {
+ kBool = 0,
+ kInt,
kLong,
kFloat,
kDouble,
@@ -44,6 +49,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 +77,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/da9baf7e/types/TypeIDSelectors.hpp
----------------------------------------------------------------------
diff --git a/types/TypeIDSelectors.hpp b/types/TypeIDSelectors.hpp
new file mode 100644
index 0000000..d75a887
--- /dev/null
+++ b/types/TypeIDSelectors.hpp
@@ -0,0 +1,152 @@
+/**
+ * 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_ID_SELECTORS_HPP_
+#define QUICKSTEP_TYPES_TYPE_ID_SELECTORS_HPP_
+
+#include <type_traits>
+
+#include "types/TypeID.hpp"
+#include "utility/meta/Common.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+struct TypeIDSelectorAll;
+
+struct TypeIDSelectorNumeric;
+
+struct TypeIDSelectorParameterized;
+
+struct TypeIDSelectorNonParameterized;
+
+template <TypeID ...candidates>
+struct TypeIDSelectorEqualsAny;
+
+
+// Forward declaration
+template <TypeID type_id>
+struct TypeIDTrait;
+
+struct TypeIDSelectorAll {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+ };
+};
+
+struct TypeIDSelectorNumeric {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreturn-type"
+ inline static auto Invoke(const FunctorT &functor)
+ -> decltype(functor(TypeIDConstant())) {
+ DLOG(FATAL) << "Unexpected TypeID: "
+ << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+ }
+#pragma GCC diagnostic pop
+ };
+};
+
+template <typename TypeIDConstant, typename FunctorT>
+struct TypeIDSelectorNumeric::Implementation<
+ TypeIDConstant, FunctorT,
+ std::enable_if_t<TypeIDTrait<TypeIDConstant::value>
+ ::kStaticSuperTypeID == Type::kNumeric>> {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+};
+
+template <TypeID ...candidates>
+struct TypeIDSelectorEqualsAny {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreturn-type"
+ inline static auto Invoke(const FunctorT &functor)
+ -> decltype(functor(TypeIDConstant())) {
+ DLOG(FATAL) << "Unexpected TypeID: "
+ << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+ }
+#pragma GCC diagnostic pop
+ };
+};
+
+template <TypeID ...candidates>
+template <typename TypeIDConstant, typename FunctorT>
+struct TypeIDSelectorEqualsAny<candidates...>::Implementation<
+ TypeIDConstant, FunctorT,
+ std::enable_if_t<
+ meta::EqualsAny<TypeIDConstant,
+ std::integral_constant<TypeID, candidates>...>::value>> {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+};
+
+namespace internal {
+
+template <bool require_parameterized>
+struct TypeIDSelectorParameterizedHelper {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreturn-type"
+ inline static auto Invoke(const FunctorT &functor)
+ -> decltype(functor(TypeIDConstant())) {
+ DLOG(FATAL) << "Unexpected TypeID: "
+ << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+ }
+#pragma GCC diagnostic pop
+ };
+};
+
+template <bool require_non_parameterized>
+template <typename TypeIDConstant, typename FunctorT>
+struct TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementation<
+ TypeIDConstant, FunctorT,
+ std::enable_if_t<TypeIDTrait<TypeIDConstant::value>::kParameterized
+ ^ require_non_parameterized>> {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+};
+
+} // namespace internal
+
+struct TypeIDSelectorNonParameterized
+ : internal::TypeIDSelectorParameterizedHelper<true> {};
+
+struct TypeIDSelectorParameterized
+ : internal::TypeIDSelectorParameterizedHelper<false> {};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_ID_SELECTORS_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
new file mode 100644
index 0000000..f4c9fb9
--- /dev/null
+++ b/types/TypeRegistrar.hpp
@@ -0,0 +1,122 @@
+/**
+ * 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_REGISTRAR_HPP_
+#define QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
+
+#include <cstdint>
+#include <type_traits>
+
+#include "types/DatetimeLit.hpp"
+#include "types/IntervalLit.hpp"
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeIDSelectors.hpp"
+#include "utility/meta/Common.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+template <TypeID type_id>
+struct TypeIDTrait;
+
+#define REGISTER_TYPE(T, type_id, super_type_id, parameterized, layout, CppType) \
+ class T; \
+ template <> struct TypeIDTrait<type_id> { \
+ typedef T TypeClass; \
+ typedef CppType cpptype; \
+ static constexpr TypeID kStaticTypeID = type_id; \
+ static constexpr Type::SuperTypeID kStaticSuperTypeID = super_type_id; \
+ static constexpr bool kParameterized = parameterized; \
+ static constexpr TypeStorageLayout kLayout = layout; \
+ };
+
+REGISTER_TYPE(BoolType, kBool, \
+ Type::kNumeric, false, kNativeEmbedded, bool);
+REGISTER_TYPE(IntType, kInt, \
+ Type::kNumeric, false, kNativeEmbedded, int);
+REGISTER_TYPE(LongType, kLong, \
+ Type::kNumeric, false, kNativeEmbedded, std::int64_t);
+REGISTER_TYPE(FloatType, kFloat, \
+ Type::kNumeric, false, kNativeEmbedded, float);
+REGISTER_TYPE(DoubleType, kDouble, \
+ Type::kNumeric, false, kNativeEmbedded, double);
+REGISTER_TYPE(DateType, kDate, \
+ Type::kOther, false, kNativeEmbedded, DateLit);
+REGISTER_TYPE(DatetimeType, kDatetime, \
+ Type::kOther, false, kNativeEmbedded, DatetimeLit);
+REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval, \
+ Type::kOther, false, kNativeEmbedded, DatetimeIntervalLit);
+REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval, \
+ Type::kOther, false, kNativeEmbedded, YearMonthIntervalLit);
+REGISTER_TYPE(CharType, kChar, \
+ Type::kAsciiString, true, kNonNativeInline, void);
+REGISTER_TYPE(VarCharType, kVarChar, \
+ Type::kAsciiString, true, kOutOfLine, void);
+REGISTER_TYPE(NullType, kNullType, \
+ Type::kOther, false, kNonNativeInline, void);
+
+#undef REGISTER_TYPE
+
+using TypeIDSequenceAll =
+ meta::MakeSequence<static_cast<std::size_t>(kNumTypeIDs)>
+ ::type::template cast_to<TypeID>;
+
+template <typename Selector = TypeIDSelectorAll, typename FunctorT>
+auto InvokeOnTypeID(const TypeID type_id, const FunctorT &functor);
+
+namespace internal {
+
+template <int l, int r, typename Selector, typename FunctorT>
+inline auto InvokeOnTypeIDInner(const int value,
+ const FunctorT &functor) {
+ DCHECK_LE(l, r);
+ if (l == r) {
+ constexpr TypeID type_id = static_cast<TypeID>(r);
+ return Selector::template Implementation<
+ std::integral_constant<TypeID, type_id>, FunctorT>::Invoke(functor);
+ }
+ constexpr int m = (l + r) >> 1;
+ if (value <= m) {
+ return InvokeOnTypeIDInner<l, m, Selector, FunctorT>(value, functor);
+ } else {
+ return InvokeOnTypeIDInner<m+1, r, Selector, FunctorT>(value, functor);
+ }
+}
+
+} // namespace internal
+
+template <typename Selector, typename FunctorT>
+auto InvokeOnTypeID(const TypeID type_id,
+ const FunctorT &functor) {
+ return internal::InvokeOnTypeIDInner<0, static_cast<int>(kNumTypeIDs)-1,
+ Selector, FunctorT>(
+ static_cast<int>(type_id), functor);
+}
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
new file mode 100644
index 0000000..27ba02a
--- /dev/null
+++ b/types/TypeSynthesizer.hpp
@@ -0,0 +1,210 @@
+/**
+ * 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_SYNTHESIZER_HPP_
+#define QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_
+
+#include <cstddef>
+#include <type_traits>
+
+#include "types/Type.hpp"
+#include "types/Type.pb.h"
+#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "utility/Macros.hpp"
+#include "utility/PtrMap.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+template <typename TypeClass, bool parameterized>
+class TypeInstance;
+
+
+template <TypeID type_id>
+class TypeSynthesizer
+ : public Type,
+ public TypeInstance<typename TypeIDTrait<type_id>::TypeClass,
+ TypeIDTrait<type_id>::kParameterized> {
+ public:
+ using Trait = TypeIDTrait<type_id>;
+ using TypeClass = typename Trait::TypeClass;
+
+ static constexpr Type::SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
+ static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID;
+ static constexpr bool kParameterized = Trait::kParameterized;
+ static constexpr TypeStorageLayout kLayout = Trait::kLayout;
+
+ typedef typename Trait::cpptype cpptype;
+
+ serialization::Type getProto() const override {
+ serialization::Type proto;
+
+ proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
+ proto.set_nullable(nullable_);
+
+ if (kParameterized) {
+ proto.set_length(parameter_);
+ }
+
+ return proto;
+ }
+
+ const Type& getNullableVersion() const override {
+ return getInstance<kParameterized>(true);
+ }
+
+ const Type& getNonNullableVersion() const override {
+ return getInstance<kParameterized>(false);
+ }
+
+ protected:
+ template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+ explicit TypeSynthesizer(const bool nullable,
+ std::enable_if_t<layout == kNativeEmbedded ||
+ layout == kNativeInline>* = 0)
+ : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+ sizeof(cpptype), sizeof(cpptype)) {
+ DCHECK(!kParameterized);
+ }
+
+ template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+ TypeSynthesizer(const bool nullable,
+ const std::size_t minimum_byte_length,
+ const std::size_t maximum_byte_length,
+ const std::size_t parameter,
+ std::enable_if_t<parameterized &&
+ (layout == kNonNativeInline ||
+ layout == kOutOfLine)>* = 0)
+ : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+ minimum_byte_length, maximum_byte_length, parameter) {
+ DCHECK(kLayout != kNonNativeInline || minimum_byte_length == maximum_byte_length);
+ }
+
+ template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+ TypeSynthesizer(const bool nullable,
+ const std::size_t minimum_byte_length,
+ const std::size_t maximum_byte_length,
+ std::enable_if_t<!parameterized &&
+ (layout == kNonNativeInline ||
+ layout == kOutOfLine)>* = 0)
+ : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+ minimum_byte_length, maximum_byte_length) {
+ DCHECK(kLayout != kNonNativeInline || minimum_byte_length == maximum_byte_length);
+ }
+
+ private:
+ template <bool has_param>
+ inline const Type& getInstance(const bool nullable,
+ std::enable_if_t<has_param>* = 0) const {
+ return TypeInstance<TypeClass, kParameterized>::Instance(parameter_, nullable);
+ }
+
+ template <bool has_param>
+ inline const Type& getInstance(const bool nullable,
+ std::enable_if_t<!has_param>* = 0) const {
+ return TypeInstance<TypeClass, kParameterized>::Instance(nullable);
+ }
+
+ friend class TypeInstance<TypeClass, kParameterized>;
+
+ DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
+};
+
+template <TypeID type_id>
+constexpr Type::SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
+
+template <TypeID type_id>
+constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
+
+template <TypeID type_id>
+constexpr bool TypeSynthesizer<type_id>::kParameterized;
+
+template <TypeID type_id>
+constexpr TypeStorageLayout TypeSynthesizer<type_id>::kLayout;
+
+
+template <typename TypeClass>
+class TypeInstance<TypeClass, false> {
+ public:
+ static const TypeClass& InstanceNonNullable() {
+ return InstanceInternal<false>();
+ }
+
+ static const TypeClass& InstanceNullable() {
+ return InstanceInternal<true>();
+ }
+
+ static const TypeClass& Instance(const bool nullable) {
+ if (nullable) {
+ return InstanceNullable();
+ } else {
+ return InstanceNonNullable();
+ }
+ }
+
+ private:
+ template <bool nullable>
+ inline static const TypeClass& InstanceInternal() {
+ static TypeClass instance(nullable);
+ return instance;
+ }
+};
+
+template <typename TypeClass>
+class TypeInstance<TypeClass, true> {
+ public:
+ static const TypeClass& InstanceNonNullable(const std::size_t length) {
+ return InstanceInternal<false>(length);
+ }
+
+ static const TypeClass& InstanceNullable(const std::size_t length) {
+ return InstanceInternal<true>(length);
+ }
+
+ static const TypeClass& Instance(const bool nullable, const std::size_t length) {
+ if (nullable) {
+ return InstanceNullable(length);
+ } else {
+ return InstanceNonNullable(length);
+ }
+ }
+
+ private:
+ template <bool nullable>
+ inline static const TypeClass& InstanceInternal(const std::size_t length) {
+ static PtrMap<size_t, TypeClass> instance_map;
+ auto imit = instance_map.find(length);
+ if (imit == instance_map.end()) {
+ imit = instance_map.insert(length, new TypeClass(length, nullable)).first;
+ }
+ return *(imit->second);
+ }
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/da9baf7e/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
new file mode 100644
index 0000000..b146f02
--- /dev/null
+++ b/types/TypeUtil.hpp
@@ -0,0 +1,70 @@
+/**
+ * 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/BoolType.hpp"
+#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/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "types/VarCharType.hpp"
+#include "types/YearMonthIntervalType.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+class TypeUtil {
+ public:
+ static bool IsParameterized(const TypeID type_id) {
+ return InvokeOnTypeID(
+ type_id,
+ [&](auto tid) -> bool { // NOLINT(build/c++11)
+ return TypeIDTrait<decltype(tid)::value>::kParameterized;
+ });
+ }
+
+ private:
+ TypeUtil() {}
+
+ DISALLOW_COPY_AND_ASSIGN(TypeUtil);
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_UTIL_HPP_