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/10/10 18:25:31 UTC

[01/38] incubator-quickstep git commit: Updates to casts

Repository: incubator-quickstep
Updated Branches:
  refs/heads/refactor-type [created] 4bf0857c5


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index fbfd091..269d683 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -36,9 +36,9 @@ add_library(quickstep_types_operations_unaryoperations_SubstringOperation
             SubstringOperation.cpp
             SubstringOperation.hpp)
 add_library(quickstep_types_operations_unaryoperations_UnaryOperation UnaryOperation.cpp UnaryOperation.hpp)
-add_library(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+add_library(quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
             ../../../empty_src.cpp
-            UnaryOperationWrapper.hpp)
+            UnaryOperationSynthesizer.hpp)
 
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
@@ -49,7 +49,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnary
                       quickstep_types_IntType
                       quickstep_types_LongType
                       quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_operations_utility_OperationSynthesizeUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors
                       quickstep_types_CharType
@@ -58,7 +58,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnar
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_VarCharType
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_types_port_strnlen
                       quickstep_utility_meta_Common)
@@ -67,28 +67,37 @@ target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryFunct
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_unaryoperations_CastFunctorOverloads
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_TypedValue
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
+                      quickstep_utility_meta_TypeList)
 target_link_libraries(quickstep_types_operations_unaryoperations_CastOperation
                       glog
                       quickstep_types_CharType
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
+                      quickstep_types_GenericValue
                       quickstep_types_IntType
                       quickstep_types_LongType
+                      quickstep_types_MetaType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypeUtil
                       quickstep_types_TypedValue
                       quickstep_types_VarCharType
+                      quickstep_types_operations_unaryoperations_CastFunctorOverloads
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_port_strnlen
                       quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros
-                      quickstep_utility_StringUtil)
+                      quickstep_utility_StringUtil
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOperation
                       glog
                       quickstep_types_DateType
@@ -100,7 +109,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOper
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_utility_Macros
                       quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_SubstringOperation
@@ -126,7 +135,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_Operation_proto
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       glog
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_ValueAccessor
@@ -152,7 +161,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper)
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer)
 
 # Tests:
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/CMathUnaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryFunctors.hpp b/types/operations/unary_operations/CMathUnaryFunctors.hpp
index 5ed8b50..edece53 100644
--- a/types/operations/unary_operations/CMathUnaryFunctors.hpp
+++ b/types/operations/unary_operations/CMathUnaryFunctors.hpp
@@ -27,7 +27,7 @@
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "types/operations/utility/OperationSynthesizeUtil.hpp"
 #include "utility/meta/Common.hpp"
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/CastFunctorOverloads.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastFunctorOverloads.hpp b/types/operations/unary_operations/CastFunctorOverloads.hpp
index 940cab6..0e4b059 100644
--- a/types/operations/unary_operations/CastFunctorOverloads.hpp
+++ b/types/operations/unary_operations/CastFunctorOverloads.hpp
@@ -26,9 +26,10 @@
 #include <type_traits>
 #include <vector>
 
+#include "types/GenericValue.hpp"
 #include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "utility/meta/TypeList.hpp"
 
 namespace quickstep {
@@ -62,12 +63,17 @@ struct CastFunctor<
 // ----------------------------------------------------------------------------
 // Implementations of any type to ascii string casts.
 
+using UnsupportedCastToAsciiStringTypes = meta::TypeList<NullType>;
+
+// TODO(refactor-type): Better implementation of casting among ascii string types.
+
 template <typename SourceType>
-struct CastFunctor<SourceType, CharType,
-                   std::enable_if_t<SourceType::kStaticSuperTypeID == SuperTypeID::kNumeric>>
+struct CastFunctor<
+    SourceType, CharType,
+    std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>>
     : public UnaryFunctor<SourceType, CharType> {
-  explicit CastFunctor(const SourceType &source_type_in,
-                       const CharType &target_type_in)
+  CastFunctor(const SourceType &source_type_in,
+              const CharType &target_type_in)
       : source_type(source_type_in),
         max_string_length(target_type_in.getStringLength()) {}
   inline void apply(const typename SourceType::cpptype &argument, void *result) const {
@@ -85,11 +91,12 @@ struct CastFunctor<SourceType, CharType,
 };
 
 template <typename SourceType>
-struct CastFunctor<SourceType, VarCharType,
-                   std::enable_if_t<SourceType::kStaticSuperTypeID == SuperTypeID::kNumeric>>
+struct CastFunctor<
+    SourceType, VarCharType,
+    std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>>
     : public UnaryFunctor<SourceType, VarCharType> {
-  explicit CastFunctor(const SourceType &source_type_in,
-                       const VarCharType &target_type_in)
+  CastFunctor(const SourceType &source_type_in,
+              const VarCharType &target_type_in)
       : source_type(source_type_in),
         max_string_length(target_type_in.getStringLength()) {}
   inline TypedValue apply(const typename SourceType::cpptype &argument) const {
@@ -105,75 +112,109 @@ struct CastFunctor<SourceType, VarCharType,
   const std::size_t max_string_length;
 };
 
-//template <typename SourceType>
-//struct CastFunctor<SourceType, TextType>
-//    : public UnaryFunctor<SourceType, TextType> {
-//  explicit CastFunctor(const SourceType &source_type_in,
-//                       const TextType &target_type_in)
-//      : source_type(source_type_in) {}
-//  inline std::string apply(const typename SourceType::cpptype &argument) const {
-//    return source_type.printValueToString(&argument);
-//  }
-//  const SourceType &source_type;
-//};
-//
-//
+template <typename SourceType>
+struct CastFunctor<
+    SourceType, TextType,
+    std::enable_if_t<!UnsupportedCastToAsciiStringTypes::contains<SourceType>::value>>
+    : public UnaryFunctor<SourceType, TextType> {
+  CastFunctor(const SourceType &source_type_in,
+              const TextType &target_type_in)
+      : source_type(source_type_in) {}
+  inline std::string apply(const typename SourceType::cpptype &argument) const {
+    return source_type.printValueToString(&argument);
+  }
+  const SourceType &source_type;
+};
+
+
 //// ----------------------------------------------------------------------------
-//// Implementations of ascii string to numeric casts.
-//
-//template <typename T>
-//T CastStringToNumericOverload(const char *str);
-//
-//template <>
-//bool CastStringToNumericOverload(const char *str) {
-//  return ToLower(str) == "true";
-//}
-//template <>
-//int CastStringToNumericOverload(const char *str) {
-//  return std::atoi(str);
-//}
-//template <>
-//float CastStringToNumericOverload(const char *str) {
-//  return static_cast<float>(std::atof(str));
-//}
-//template <>
-//std::int64_t CastStringToNumericOverload(const char *str) {
-//  return std::atoll(str);
-//}
-//template <>
-//double CastStringToNumericOverload(const char *str) {
-//  return std::atof(str);
-//}
-//
-//template <typename TargetType>
-//struct CastFunctor<CharType, TargetType,
-//                   std::enable_if_t<NumericTypes::contains<TargetType>::value>>
-//    : public UnaryFunctor<CharType, TargetType> {
-//  explicit CastFunctor(const CharType &source_type_in,
-//                       const TargetType &target_type_in)
-//      : max_string_length(source_type_in.getStringLength()) {}
-//  inline typename TargetType::cpptype apply(const void *argument) const {
-//    const char *str = static_cast<const char*>(argument);
-//    const std::string value(str, strnlen(str, max_string_length));
-//    return CastStringToNumericOverload<typename TargetType::cpptype>(value.c_str());
-//  }
-//  const std::size_t max_string_length;
-//};
-//
-//
-//template <typename TargetType>
-//struct CastFunctor<VarCharType, TargetType,
-//                   std::enable_if_t<NumericTypes::contains<TargetType>::value>>
-//    : public UnaryFunctor<VarCharType, TargetType> {
-//  explicit CastFunctor(const VarCharType &source_type_in,
-//                       const TargetType &target_type_in)
-//      : max_string_length(source_type_in.getStringLength()) {}
-//  inline typename TargetType::cpptype apply(const TypedValue &argument) const {
-//    return CastStringToNumericOverload<typename TargetType::cpptype>(
-//        static_cast<const char*>(argument.getDataPtr()));
-//  }
-//  const std::size_t max_string_length;
-//};
+//// Implementations of ascii string to other types casts.
+
+using UnsupportedParseFromAsciiStringTypes = meta::TypeList<NullType>;
+
+// TODO(refactor-type): Implement parseTypedValueFromString for other non-numeric types.
+// TODO(refactor-type): Possibly return NULL values.
+
+template <typename TargetType>
+struct CastFunctor<
+    CharType, TargetType,
+    std::enable_if_t<!UnsupportedParseFromAsciiStringTypes::contains<TargetType>::value &&
+                     TargetType::kMemoryLayout == kCxxInlinePod>>
+    : public UnaryFunctor<CharType, TargetType> {
+  CastFunctor(const CharType &source_type_in,
+              const TargetType &target_type_in)
+      : max_string_length(source_type_in.getStringLength()),
+        target_type(target_type_in) {}
+  inline typename TargetType::cpptype apply(const void *argument) const {
+    // TODO(refactor-type): Implement specialized parseValueFromString.
+    const char *str = static_cast<const char*>(argument);
+    const std::string value(str, strnlen(str, max_string_length));
+    TypedValue result;
+    target_type.parseTypedValueFromString(value, &result);
+    return result.getLiteral<typename TargetType::cpptype>();
+  }
+  const std::size_t max_string_length;
+  const TargetType &target_type;
+};
+
+
+template <typename TargetType>
+struct CastFunctor<VarCharType, TargetType,
+                   std::enable_if_t<NumericTypes::contains<TargetType>::value>>
+    : public UnaryFunctor<VarCharType, TargetType> {
+  CastFunctor(const VarCharType &source_type_in,
+              const TargetType &target_type_in)
+      : max_string_length(source_type_in.getStringLength()),
+        target_type(target_type_in) {}
+  inline typename TargetType::cpptype apply(const TypedValue &argument) const {
+    const std::string value(static_cast<const char*>(argument.getOutOfLineData()));
+    TypedValue result;
+    target_type.parseTypedValueFromString(value, &result);
+    return result.getLiteral<typename TargetType::cpptype>();
+  }
+  const std::size_t max_string_length;
+  const Type &target_type;
+};
+
+template <typename TargetType>
+struct CastFunctor<
+    TextType, TargetType,
+    std::enable_if_t<!UnsupportedParseFromAsciiStringTypes::contains<TargetType>::value &&
+                     TargetType::kMemoryLayout == kCxxInlinePod>>
+    : public UnaryFunctor<TextType, TargetType> {
+  CastFunctor(const TextType &source_type_in,
+              const TargetType &target_type_in)
+      : target_type(target_type_in) {}
+  inline typename TargetType::cpptype apply(const std::string &argument) const {
+    // TODO(refactor-type): Implement specialized parseValueFromString.
+    TypedValue result;
+    target_type.parseTypedValueFromString(argument, &result);
+    return result.getLiteral<typename TargetType::cpptype>();
+  }
+  const TargetType &target_type;
+};
+
+
+//// ----------------------------------------------------------------------------
+//// Implementations of array to array casts.
+
+template <>
+struct CastFunctor<ArrayType, ArrayType>
+    : public UnaryFunctor<ArrayType, ArrayType> {
+  CastFunctor(const ArrayType &source_type_in,
+              const ArrayType &target_type_in)
+      : source_element_type(source_type_in.getElementType()),
+        target_element_type(target_type_in.getElementType()) {}
+  inline ArrayLit apply(const ArrayLit &argument) const {
+    ArrayLit result(target_element_type);
+    for (const auto *value : argument) {
+      result.push_back(target_element_type.coerceValue(value, source_element_type));
+    }
+    return result;
+  }
+  const Type &source_element_type;
+  const Type &target_element_type;
+};
 
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp
index 8f725e2..f71ae7d 100644
--- a/types/operations/unary_operations/CastOperation.cpp
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -38,7 +38,7 @@
 #include "types/TypedValue.hpp"
 #include "types/VarCharType.hpp"
 #include "types/operations/unary_operations/CastFunctorOverloads.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "types/port/strnlen.hpp"
 #include "utility/EqualsAnyConstant.hpp"
 #include "utility/StringUtil.hpp"
@@ -53,7 +53,7 @@ UncheckedUnaryOperator* MakeUncheckedCastOperatorConstructorSpec(
     const SourceType &source_type,
     const TargetType &target_type,
     decltype(new CastFunctor<SourceType, TargetType>()) * = 0) {
-  return new UncheckedUnaryOperatorWrapperCodegen<
+  return new UncheckedUnaryOperatorSynthesizer<
       CastFunctor<SourceType, TargetType>>(
           source_type, target_type);
 }
@@ -63,7 +63,7 @@ UncheckedUnaryOperator* MakeUncheckedCastOperatorConstructorSpec(
     const SourceType &source_type,
     const TargetType &target_type,
     decltype(new CastFunctor<SourceType, TargetType>(source_type, target_type)) * = 0) {
-  return new UncheckedUnaryOperatorWrapperCodegen<
+  return new UncheckedUnaryOperatorSynthesizer<
       CastFunctor<SourceType, TargetType>>(
           source_type, target_type, source_type, target_type);
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/CastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp
index b8750c0..5a139b0 100644
--- a/types/operations/unary_operations/CastOperation.hpp
+++ b/types/operations/unary_operations/CastOperation.hpp
@@ -26,10 +26,10 @@
 #include <utility>
 #include <vector>
 
-#include "types/IntType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
 #include "utility/Macros.hpp"
@@ -63,7 +63,7 @@ class CastOperation : public UnaryOperation {
 
   std::vector<OperationSignaturePtr> getSignatures() const override {
     const std::vector<TypeID> source_type_ids =
-        { kBool, kInt, kLong, kFloat, kDouble, kChar, kVarChar };
+        TypeIDSequenceAll::Instantiate<std::vector<TypeID>>();
     const std::vector<TypeID> target_type_carrier = { kMetaType };
 
     std::vector<OperationSignaturePtr> signatures;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/DateExtractOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp
index f95e109..16e66a9 100644
--- a/types/operations/unary_operations/DateExtractOperation.cpp
+++ b/types/operations/unary_operations/DateExtractOperation.cpp
@@ -32,7 +32,7 @@
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 
 #include "glog/logging.h"
 
@@ -96,17 +96,17 @@ UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator(
   if (type.getTypeID() == kDate) {
     switch (unit) {
       case DateExtractUnit::kYear:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DateExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
                  type, *result_type);
       case DateExtractUnit::kMonth:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DateExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
                  type, *result_type);
       case DateExtractUnit::kDay:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DateExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
                  type, *result_type);
@@ -117,32 +117,32 @@ UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator(
   } else {
     switch (unit) {
       case DateExtractUnit::kYear:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
                  type, *result_type);
       case DateExtractUnit::kMonth:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
                  type, *result_type);
       case DateExtractUnit::kDay:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
                  type, *result_type);
       case DateExtractUnit::kHour:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kHour>>(
                  type, *result_type);
       case DateExtractUnit::kMinute:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kMinute>>(
                  type, *result_type);
       case DateExtractUnit::kSecond:
-        return new UncheckedUnaryOperatorWrapperCodegen<
+        return new UncheckedUnaryOperatorSynthesizer<
              DatetimeExtractFunctor,
              std::integral_constant<DateExtractUnit, DateExtractUnit::kSecond>>(
                  type, *result_type);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/UnaryOperationSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationSynthesizer.hpp b/types/operations/unary_operations/UnaryOperationSynthesizer.hpp
new file mode 100644
index 0000000..9d46af7
--- /dev/null
+++ b/types/operations/unary_operations/UnaryOperationSynthesizer.hpp
@@ -0,0 +1,273 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
+
+#include <cstddef>
+#include <string>
+#include <type_traits>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "storage/ValueAccessor.hpp"
+#include "storage/ValueAccessorUtil.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT, typename ResultT>
+struct UnaryFunctor {
+  typedef ArgumentT ArgumentType;
+  typedef ResultT ResultType;
+
+  static constexpr Operation
+      ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+class UncheckedUnaryOperatorSynthesizer : public UncheckedUnaryOperator {
+ public:
+  template <typename ...FunctorArgs>
+  UncheckedUnaryOperatorSynthesizer(const Type &argument_type,
+                                    const Type &result_type,
+                                    FunctorArgs &&...args)
+      : functor_(std::forward<FunctorArgs>(args)...),
+        impl_(functor_, argument_type, result_type) {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(result_type.getTypeID() == ResultType::kStaticTypeID);
+  }
+
+  TypedValue applyToTypedValue(const TypedValue &argument) const override {
+    return impl_.applyToTypedValue(argument);
+  }
+
+  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
+    using ArgumentCVT = typename ArgumentGen::ColumnVectorType;
+    DCHECK_EQ(argument.getImplementation(), ArgumentCVT::kImplementation);
+
+    using ArgumentAccessorT = ColumnVectorAccessor<ArgumentCVT>;
+    ArgumentAccessorT accessor(static_cast<const ArgumentCVT&>(argument));
+    return impl_.applyToValueAccessor(&accessor, 0);
+  }
+
+  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
+                                     const attribute_id attr_id) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToValueAccessor(accessor, attr_id);
+    });
+  }
+
+ private:
+  using ArgumentType = typename FunctorT::ArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
+  using ArgumentGen = OperationCodegen<FuncSpec, ArgumentType>;
+  using ResultGen = OperationCodegen<FuncSpec, ResultType>;
+
+  template <bool argument_nullable>
+  struct Implementation;
+
+  const FunctorT functor_;
+  const Implementation<true> impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorSynthesizer);
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool argument_nullable>
+struct UncheckedUnaryOperatorSynthesizer<FunctorT, SpecArgs...>
+    ::Implementation {
+  Implementation(const FunctorT &functor_in,
+                 const Type &argument_type_in,
+                 const Type &result_type_in)
+      : functor(functor_in),
+        argument_type(static_cast<const ArgumentType&>(argument_type_in)),
+        result_type(static_cast<const ResultType&>(result_type_in)) {}
+
+  inline TypedValue applyToTypedValue(const TypedValue &argument) const {
+    if (argument_nullable && argument.isNull()) {
+      return TypedValue(ResultType::kStaticTypeID);
+    }
+
+    return ResultGen::template ApplyUnaryTypedValue<ArgumentGen>(
+        ArgumentGen::ToNativeValueConst(argument, argument_type),
+        result_type,
+        functor);
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToValueAccessor(AccessorT *accessor,
+                                            const attribute_id attr_id) const {
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    std::unique_ptr<typename ArgumentGen::NativeType> value_cache;
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename ArgumentGen::NativeTypeConstPtr arg_value =
+          ArgumentGen::template GetValuePtr<argument_nullable, AccessorT>(
+              accessor, attr_id, argument_type, &value_cache);
+
+      if (argument_nullable && ArgumentGen::IsNull(arg_value)) {
+        result_cv->appendNullValue();
+      } else {
+        ResultGen::template ApplyUnaryColumnVector<ArgumentGen>(
+            ArgumentGen::Dereference(arg_value), functor, result_cv);
+      }
+    }
+    return result_cv;
+  }
+
+  const FunctorT &functor;
+  const ArgumentType &argument_type;
+  const ResultType &result_type;
+};
+
+template <typename FunctorT>
+class UnaryOperationSynthesizer : public UnaryOperation {
+ public:
+  UnaryOperationSynthesizer()
+      : UnaryOperation(),
+        operation_name_(FunctorT::GetName()) {}
+
+  std::string getName() const override {
+    return operation_name_;
+  }
+
+  std::string getShortName() const override {
+    return getName();
+  }
+
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    return {
+        OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0)
+    };
+  }
+
+  bool canApplyTo(const Type &argument_type,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return true;
+  }
+
+  const Type* getResultType(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return getResultTypeImpl<HasGetType<FunctorT>::value>(
+        argument_type, static_arguments);
+  }
+
+  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return makeUncheckedUnaryOperatorImpl<
+        std::is_default_constructible<FunctorT>::value>(
+            argument_type, static_arguments);
+  }
+
+ private:
+  using ArgumentType = typename FunctorT::ArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  QUICKSTEP_TRAIT_HAS_STATIC_METHOD(HasGetType, GetType);
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<functor_use_default_constructor> * = 0) const {
+    return new UncheckedUnaryOperatorSynthesizer<FunctorT>(
+        argument_type, *getResultType(argument_type, static_arguments));
+  }
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!functor_use_default_constructor> * = 0) const {
+    return new UncheckedUnaryOperatorSynthesizer<FunctorT>(
+        argument_type, *getResultType(argument_type, static_arguments),
+        static_cast<const ArgumentType&>(argument_type));
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!user_defined_get_type &&
+                       ResultType::kMemoryLayout == kCxxInlinePod> * = 0) const {
+    return &TypeFactory::GetType(ResultType::kStaticTypeID,
+                                 argument_type.isNullable());
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!user_defined_get_type &&
+                       ResultType::kMemoryLayout == kCxxGeneric> * = 0) const {
+    return &TypeFactory::GetType(ResultType::kStaticTypeID,
+                                 std::vector<GenericValue>(),
+                                 argument_type.isNullable());
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<user_defined_get_type ||
+                       ResultType::kMemoryLayout == kParInlinePod ||
+                       ResultType::kMemoryLayout == kParOutOfLinePod> * = 0) const {
+    // TODO(refactor-type): Specialize with regard to static arguments.
+    return FunctorT::GetResultType(argument_type);
+  }
+
+  const std::string operation_name_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnaryOperationSynthesizer);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/UnaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp
deleted file mode 100644
index 78285fa..0000000
--- a/types/operations/unary_operations/UnaryOperationWrapper.hpp
+++ /dev/null
@@ -1,250 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
-
-#include <cstddef>
-#include <string>
-#include <type_traits>
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
-#include "types/Type.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/OperationSignature.hpp"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/utility/OperationSynthesizeUtil.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename ArgumentT, typename ResultT>
-struct UnaryFunctor {
-  typedef ArgumentT ArgumentType;
-  typedef ResultT ResultType;
-
-  static constexpr Operation
-      ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation;
-};
-
-template <typename FunctorT, typename ...SpecArgs>
-class UncheckedUnaryOperatorWrapperCodegen : public UncheckedUnaryOperator {
- public:
-  template <typename ...ConstructorArgs>
-  UncheckedUnaryOperatorWrapperCodegen(const Type &argument_type,
-                                       const Type &result_type,
-                                       ConstructorArgs &&...args)
-      : functor_(std::forward<ConstructorArgs>(args)...),
-        impl_(functor_, argument_type, result_type) {}
-
-  TypedValue applyToTypedValue(const TypedValue &argument) const override {
-    return impl_.applyToTypedValue(argument);
-  }
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
-    using ArgumentCVT = typename ArgumentGen::ColumnVectorType;
-    DCHECK_EQ(argument.isNative(), ArgumentCVT::kNative);
-
-    using ArgumentAccessorT = ColumnVectorValueAccessor<ArgumentCVT>;
-    ArgumentAccessorT accessor(static_cast<const ArgumentCVT&>(argument));
-    return impl_.applyToValueAccessor(&accessor, 0);
-  }
-
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id attr_id) const override {
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      return impl_.applyToValueAccessor(accessor, attr_id);
-    });
-  }
-
- private:
-  using ArgumentType = typename FunctorT::ArgumentType;
-  using ResultType = typename FunctorT::ResultType;
-
-  using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
-  using ArgumentGen = OperationCodegen<FuncSpec, ArgumentType>;
-  using ResultGen = OperationCodegen<FuncSpec, ResultType>;
-
-  template <bool argument_nullable>
-  struct Implementation;
-
-  const FunctorT functor_;
-  const Implementation<true> impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorWrapperCodegen);
-};
-
-template <typename FunctorT, typename ...SpecArgs>
-template <bool argument_nullable>
-struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...>
-    ::Implementation {
-  Implementation(const FunctorT &functor_in,
-                 const Type &argument_type_in,
-                 const Type &result_type_in)
-      : functor(functor_in),
-        argument_type(argument_type_in),
-        result_type(result_type_in) {}
-
-  inline TypedValue applyToTypedValue(const TypedValue &argument) const {
-    if (argument_nullable && argument.isNull()) {
-      return TypedValue(ResultType::kStaticTypeID);
-    }
-
-    return ResultGen::template ApplyUnaryTypedValue<ArgumentGen>(
-        ArgumentGen::ToNativeValueConst(argument),
-        result_type,
-        functor);
-  }
-
-  template <typename AccessorT>
-  inline ColumnVector* applyToValueAccessor(AccessorT *accessor,
-                                            const attribute_id attr_id) const {
-    using ResultCVT = typename ResultGen::ColumnVectorType;
-    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
-
-    accessor->beginIteration();
-    while (accessor->next()) {
-      typename ArgumentGen::NativeTypeConstPtr arg_value =
-          ArgumentGen::template GetValuePtr<
-              argument_nullable, AccessorT>(accessor, attr_id);
-
-      if (argument_nullable && ArgumentGen::IsNull(arg_value)) {
-        result_cv->appendNullValue();
-      } else {
-        ResultGen::template ApplyUnaryColumnVector<ArgumentGen>(
-            ArgumentGen::Dereference(arg_value), functor, result_cv);
-      }
-    }
-    return result_cv;
-  }
-
-  const FunctorT &functor;
-  const Type &argument_type;
-  const Type &result_type;
-};
-
-template <typename FunctorT>
-class UnaryOperationWrapper : public UnaryOperation {
- public:
-  UnaryOperationWrapper()
-      : UnaryOperation(),
-        operation_name_(FunctorT::GetName()) {}
-
-  std::string getName() const override {
-    return operation_name_;
-  }
-
-  std::string getShortName() const override {
-    return getName();
-  }
-
-  std::vector<OperationSignaturePtr> getSignatures() const override {
-    return {
-        OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0)
-    };
-  }
-
-  bool canApplyTo(const Type &argument_type,
-                  const std::vector<TypedValue> &static_arguments,
-                  std::string *message) const override {
-    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return true;
-  }
-
-  const Type* getResultType(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments) const override {
-    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return getResultTypeImpl<ResultType::kIsParPod>(
-        argument_type, static_arguments);
-  }
-
-  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments) const override {
-    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return makeUncheckedUnaryOperatorImpl<
-        std::is_default_constructible<FunctorT>::value>(
-            argument_type, static_arguments);
-  }
-
- private:
-  using ArgumentType = typename FunctorT::ArgumentType;
-  using ResultType = typename FunctorT::ResultType;
-
-  template <bool functor_use_default_constructor>
-  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<functor_use_default_constructor>* = 0) const {
-    return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>(
-        argument_type, *getResultType(argument_type, static_arguments));
-  }
-
-  template <bool functor_use_default_constructor>
-  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<!functor_use_default_constructor>* = 0) const {
-    return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>(
-        argument_type, *getResultType(argument_type, static_arguments),
-        static_cast<const ArgumentType&>(argument_type));
-  }
-
-  template <bool result_type_has_parameter>
-  inline const Type* getResultTypeImpl(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<!result_type_has_parameter>* = 0) const {
-    return &TypeFactory::GetType(ResultType::kStaticTypeID,
-                                 argument_type.isNullable());
-  }
-
-  template <bool result_type_has_parameter>
-  inline const Type* getResultTypeImpl(
-      const Type &argument_type,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<result_type_has_parameter>* = 0) const {
-    return FunctorT::GetResultType(argument_type);
-  }
-
-  const std::string operation_name_;
-
-  DISALLOW_COPY_AND_ASSIGN(UnaryOperationWrapper);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/utility/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/utility/CMakeLists.txt b/types/operations/utility/CMakeLists.txt
index 89b1dc6..4f57387 100644
--- a/types/operations/utility/CMakeLists.txt
+++ b/types/operations/utility/CMakeLists.txt
@@ -23,12 +23,19 @@ add_library(quickstep_types_operations_utility_OperationSynthesizeUtil
 
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_utility_CastUtil
-                      glog)
+                      quickstep_types_TypeID
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_operations_unaryoperations_CastFunctorOverloads
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_Common
+                      quickstep_utility_meta_TypeList)
 target_link_libraries(quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_catalog_CatalogTypedefs
                       quickstep_types_Type
                       quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector)
+                      quickstep_types_containers_ColumnVector
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_TypeList)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_utility ../../../empty_src.cpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/utility/CastUtil.cpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/CastUtil.cpp b/types/operations/utility/CastUtil.cpp
index e69de29..697a9c0 100644
--- a/types/operations/utility/CastUtil.cpp
+++ b/types/operations/utility/CastUtil.cpp
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/operations/utility/CastUtil.hpp"
+
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/operations/unary_operations/CastFunctorOverloads.hpp"
+#include "utility/meta/Common.hpp"
+#include "utility/meta/TypeList.hpp"
+
+namespace quickstep {
+
+namespace {
+
+template <typename T>
+struct GetTypeClass {
+  using type = typename TypeIDTrait<T::value>::TypeClass;
+};
+
+template <typename TL>
+struct HasCast : meta::IsCompleteType<
+    CastFunctor<typename TL::template at<0>, typename TL::template at<1>>> {};
+
+template <typename TL>
+struct GetSourceTypeID {
+  inline TypeID operator()() const {
+    return TL::head::kStaticTypeID;
+  }
+};
+
+}  // namespace
+
+std::vector<TypeID> CastUtil::GetCoercibleSourceTypeIDs(const TypeID target_type_id) {
+  return InvokeOnTypeID(
+      target_type_id,
+      [](auto tid) -> std::vector<TypeID> {
+    using TargetType = typename TypeIDTrait<decltype(tid)::value>::TypeClass;
+    return TypeIDSequenceAll::template bind_to<meta::TypeList>
+                            ::template map<GetTypeClass>
+                            ::template cartesian_product<meta::TypeList<TargetType>>
+                            ::template filter<HasCast>
+                            ::template Instantiate<std::vector<TypeID>, GetSourceTypeID>();
+  });
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/utility/CastUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/CastUtil.hpp b/types/operations/utility/CastUtil.hpp
index e69de29..e45b06e 100644
--- a/types/operations/utility/CastUtil.hpp
+++ b/types/operations/utility/CastUtil.hpp
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UTILITY_CAST_UTIL_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UTILITY_CAST_UTIL_HPP_
+
+#include <type_traits>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class CastUtil {
+ public:
+  static std::vector<TypeID> GetCoercibleSourceTypeIDs(const TypeID target_type_id);
+
+
+ private:
+  CastUtil() {}
+
+  DISALLOW_COPY_AND_ASSIGN(CastUtil);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UTILITY_CAST_UTIL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/utility/OperationSynthesizeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/OperationSynthesizeUtil.hpp b/types/operations/utility/OperationSynthesizeUtil.hpp
index 2b910b3..50a5863 100644
--- a/types/operations/utility/OperationSynthesizeUtil.hpp
+++ b/types/operations/utility/OperationSynthesizeUtil.hpp
@@ -17,11 +17,12 @@
  * under the License.
  **/
 
-#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UTILITY_OPERATION_SYNTHESIZE_UTIL_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UTILITY_OPERATION_SYNTHESIZE_UTIL_HPP_
 
 #include <cstddef>
 #include <list>
+#include <memory>
 #include <string>
 #include <type_traits>
 
@@ -29,6 +30,8 @@
 #include "types/Type.hpp"
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVector.hpp"
+#include "utility/Macros.hpp"
+#include "utility/meta/TypeList.hpp"
 
 namespace quickstep {
 
@@ -68,35 +71,48 @@ struct FunctorSpecializer<FunctorT, SpecArgs...>
 };
 
 template <typename ColumnVectorT>
-struct ColumnVectorValueAccessor {
-  explicit ColumnVectorValueAccessor(const ColumnVectorT &column_vector_in)
-      : column_vector(column_vector_in),
-        length(column_vector.size()) {}
+class ColumnVectorAccessor {
+ public:
+  constexpr static bool kIsGenericColumnVectorAccessor =
+      (ColumnVectorT::kImplementation == ColumnVector::kGeneric);
+
+  inline explicit ColumnVectorAccessor(const ColumnVectorT &column_vector)
+      : column_vector_(column_vector),
+        length_(column_vector.size()) {}
 
   inline void beginIteration() {
-    pos = static_cast<std::size_t>(-1);
+    pos_ = static_cast<std::size_t>(-1);
   }
 
   inline bool next() {
-    return (++pos) < length;
+    return (++pos_) < length_;
   }
 
   inline std::size_t getNumTuples() const {
-    return length;
+    return length_;
   }
 
-  template <bool nullable>
+  template <bool check_null>
   inline const void* getUntypedValue(const attribute_id) const {
-    return column_vector.template getUntypedValue<nullable>(pos);
+    return column_vector_.template getUntypedValue<check_null>(pos_);
   }
 
   inline TypedValue getTypedValue(const attribute_id) const {
-    return column_vector.getTypedValue(pos);
+    return column_vector_.getTypedValue(pos_);
+  }
+
+  template <bool check_null, bool generic>
+  inline typename std::enable_if_t<generic, ColumnVectorT>::cpptype
+      getLiteralValue() const {
+    return column_vector_.template getLiteralValue<check_null>(pos_);
   }
 
-  const ColumnVectorT &column_vector;
-  const std::size_t length;
-  std::size_t pos;
+ private:
+  const ColumnVectorT &column_vector_;
+  const std::size_t length_;
+  std::size_t pos_;
+
+  DISALLOW_COPY_AND_ASSIGN(ColumnVectorAccessor);
 };
 
 template <typename FuncSpec, typename T, typename EnableT = void>
@@ -105,11 +121,12 @@ struct OperationCodegen;
 template <typename FuncSpec, typename T>
 struct OperationCodegen<FuncSpec, T,
                         std::enable_if_t<T::kMemoryLayout == kCxxInlinePod>> {
+  using ValueType = T;
   using ColumnVectorType = NativeColumnVector;
   using FunctorSpecializer = FuncSpec;
 
   using NativeType = typename T::cpptype;
-  using NativeTypeConst = const typename T::cpptype;
+  using NativeTypeConst = const NativeType;
   using NativeTypeConstRef = const NativeType&;
   using NativeTypeConstPtr = const NativeType*;
 
@@ -151,7 +168,8 @@ struct OperationCodegen<FuncSpec, T,
 
   template <bool nullable, typename AccessorT>
   inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor,
-                                               const attribute_id attr_id) {
+                                               const attribute_id attr_id,
+                                               const Type &, void *) {
     return static_cast<NativeTypeConstPtr>(
         accessor->template getUntypedValue<nullable>(attr_id));
   }
@@ -165,7 +183,8 @@ struct OperationCodegen<FuncSpec, T,
     return *value;
   }
 
-  inline static const NativeType ToNativeValueConst(const TypedValue &value) {
+  inline static const NativeType ToNativeValueConst(const TypedValue &value,
+                                                    const Type &) {
     return value.getLiteral<NativeType>();
   }
 };
@@ -173,6 +192,7 @@ struct OperationCodegen<FuncSpec, T,
 template <typename FuncSpec, typename T>
 struct OperationCodegen<FuncSpec, T,
                         std::enable_if_t<T::kMemoryLayout == kParInlinePod>> {
+  using ValueType = T;
   using ColumnVectorType = NativeColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -223,9 +243,11 @@ struct OperationCodegen<FuncSpec, T,
     FuncSpec::Invoke(functor, left, right, cv->getPtrForDirectWrite());
   }
 
+  // TODO(refactor-type): Use ColumnAccessor to improve performance.
   template <bool nullable, typename AccessorT>
   inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor,
-                                               const attribute_id attr_id) {
+                                               const attribute_id attr_id,
+                                               const Type &, void *) {
     return accessor->template getUntypedValue<nullable>(attr_id);
   }
 
@@ -238,7 +260,8 @@ struct OperationCodegen<FuncSpec, T,
     return value;
   }
 
-  inline static const void* ToNativeValueConst(const TypedValue &value) {
+  inline static const void* ToNativeValueConst(const TypedValue &value,
+                                               const Type &) {
     return value.getDataPtr();
   }
 };
@@ -246,6 +269,7 @@ struct OperationCodegen<FuncSpec, T,
 template <typename FuncSpec, typename T>
 struct OperationCodegen<FuncSpec, T,
                         std::enable_if_t<T::kMemoryLayout == kParOutOfLinePod>> {
+  using ValueType = T;
   using ColumnVectorType = IndirectColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -289,9 +313,9 @@ struct OperationCodegen<FuncSpec, T,
   }
 
   template <bool nullable, typename AccessorT>
-  inline static NativeTypeConstPtr GetValuePtr(
-      const AccessorT *accessor,
-      const attribute_id attr_id) {
+  inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor,
+                                               const attribute_id attr_id,
+                                               const Type &, void *) {
     return accessor->getTypedValue(attr_id);
   }
 
@@ -304,11 +328,121 @@ struct OperationCodegen<FuncSpec, T,
     return value;
   }
 
-  inline static const NativeType& ToNativeValueConst(const TypedValue &value) {
+  inline static const NativeType& ToNativeValueConst(const TypedValue &value,
+                                                     const Type &) {
     return value;
   }
 };
 
+
+// TODO(refactor-type): Remove this.
+namespace internal {
+
+template <typename T>
+std::enable_if_t<T::kIsGenericColumnVectorAccessor,
+                 std::true_type> IsGenericColumnVectorAccessorImpl(int);
+template <typename>
+std::false_type IsGenericColumnVectorAccessorImpl(...);
+
+}  // namespace internal
+
+template <typename T>
+using IsGenericColumnVectorAccessor =
+    decltype(internal::IsGenericColumnVectorAccessorImpl<T>());
+
+template <typename FuncSpec, typename T>
+struct OperationCodegen<FuncSpec, T,
+                        std::enable_if_t<T::kMemoryLayout == kCxxGeneric>> {
+  using ValueType = T;
+  using ColumnVectorType = GenericColumnVector<T>;
+  using FunctorSpecializer = FuncSpec;
+
+  using NativeType = typename T::cpptype;
+  using NativeTypeConst = const NativeType;
+  using NativeTypeConstRef = const NativeType&;
+  using NativeTypeConstPtr = const NativeType*;
+
+  template <typename ArgumentGen, typename ResultType>
+  inline static TypedValue ApplyUnaryTypedValue(
+      typename ArgumentGen::NativeTypeConstRef argument,
+      const ResultType &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    const NativeType result = FuncSpec::Invoke(functor, argument);
+    return result_type.marshallValue(&result);
+  }
+
+  template <typename ArgumentGen>
+  inline static void ApplyUnaryColumnVector(
+      const typename ArgumentGen::NativeTypeConstRef argument,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    cv->appendLiteralValue(FuncSpec::Invoke(functor, argument));
+  }
+
+  template <typename LeftGen, typename RightGen, typename ResultType>
+  inline static TypedValue ApplyBinaryTypedValue(
+      typename LeftGen::NativeTypeConstRef left,
+      typename RightGen::NativeTypeConstRef right,
+      const ResultType &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    const NativeType result = FuncSpec::Invoke(functor, left, right);
+    return result_type.marshallValue(&result);
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static void ApplyBinaryColumnVector(
+      const typename LeftGen::NativeTypeConstRef left,
+      const typename RightGen::NativeTypeConstRef right,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    cv->appendLiteralValue(FuncSpec::Invoke(functor, left, right));
+  }
+
+  // TODO(refactor-type): Use ColumnAccessor to handle the more general case.
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(
+      const AccessorT *accessor,
+      const attribute_id attr_id,
+      const Type &, void *,
+      std::enable_if_t<IsGenericColumnVectorAccessor<AccessorT>::value> * = 0) {
+    return &accessor->template getLiteralValue<nullable, true>();
+  }
+
+  // TODO(refactor-type): Use ColumnAccessor to handle the more general case.
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(
+      const AccessorT *accessor,
+      const attribute_id attr_id,
+      const ValueType &value_type,
+      std::unique_ptr<NativeType> *cache,
+      std::enable_if_t<!IsGenericColumnVectorAccessor<AccessorT>::value> * = 0) {
+    static_assert(std::is_same<NativeType, typename ValueType::cpptype>::value,
+                  "Unexpected value type in OperationCodegen::GetValuePtr for "
+                  "CxxGeneric types.");
+    cache->reset(static_cast<NativeType*>(
+        value_type.unmarshallTypedValue(accessor->getTypedValue(attr_id))));
+    return cache->get();
+  }
+
+  inline static bool IsNull(NativeTypeConstPtr &value) {
+    return value == nullptr;
+  }
+
+  // Dereference: NativeTypeConstPtr& -> const NativeType&
+  inline static const NativeType& Dereference(NativeTypeConstPtr &value) {
+    return *value;
+  }
+
+  inline static const NativeType ToNativeValueConst(const TypedValue &value,
+                                                    const ValueType &value_type) {
+    // TODO(refactor-type): Improve performance.
+    std::unique_ptr<NativeType> cache(
+        static_cast<NativeType*>(value_type.unmarshallTypedValue(value)));
+    return *cache;
+  }
+};
+
+
 template <typename ...FunctorTypes>
 struct FunctorPack {
   template <typename Dispatcher>
@@ -332,4 +466,4 @@ struct OperationPack {
 
 }  // namespace quickstep
 
-#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
+#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTILITY_SYNTHESIZE_UTIL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/utility/Cast.hpp
----------------------------------------------------------------------
diff --git a/utility/Cast.hpp b/utility/Cast.hpp
index 7d2a8c0..88bdc72 100644
--- a/utility/Cast.hpp
+++ b/utility/Cast.hpp
@@ -36,7 +36,7 @@ namespace quickstep {
  * @param source_ptrs The vector of shared_ptr objects to be casted.
  * @return target_ptrs The casted vector of shared_ptr with pointers of type const TargetType.
  */
-template<class TargetType, class SourceType>
+template <class TargetType, class SourceType>
 static std::vector<std::shared_ptr<const TargetType>> CastSharedPtrVector(
     const std::vector<std::shared_ptr<const SourceType>> &source_ptrs) {
   std::vector<std::shared_ptr<const TargetType>> target_ptrs;
@@ -46,6 +46,11 @@ static std::vector<std::shared_ptr<const TargetType>> CastSharedPtrVector(
   return target_ptrs;
 }
 
+template <class TargetContainer, class SourceContainer>
+static TargetContainer CastSTLContainer(const SourceContainer &source_container) {
+  return TargetContainer(source_container.begin(), source_container.end());
+}
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/utility/meta/Common.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp
index cbad665..bc259da 100644
--- a/utility/meta/Common.hpp
+++ b/utility/meta/Common.hpp
@@ -58,8 +58,8 @@ struct Sequence {
   using contains = EqualsAny<std::integral_constant<T, v>,
                              std::integral_constant<T, s>...>;
 
-  template <typename CollectionT>
-  inline static CollectionT Instantiate() {
+  template <typename Collection>
+  inline static Collection Instantiate() {
     return { s... };
   }
 };
@@ -168,6 +168,22 @@ template <> struct UnsignedInteger<8u> {
   using type = std::uint64_t;
 };
 
+
+//// ----------------------------------------------------------------------------
+//// Macros.
+
+#define QUICKSTEP_TRAIT_HAS_STATIC_METHOD(traitname, methodname) \
+  template <typename C> \
+  class traitname { \
+   private: \
+    template <typename T> \
+    static std::true_type Impl(int, decltype(T::methodname) * = 0); \
+    template <typename T> \
+    static std::false_type Impl(...); \
+   public: \
+    static constexpr bool value = decltype(Impl<C>(0))::value; \
+  }
+
 /** @} */
 
 }  // namespace meta

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/utility/meta/TypeList.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeList.hpp b/utility/meta/TypeList.hpp
index 5f4c4d9..47b03c8 100644
--- a/utility/meta/TypeList.hpp
+++ b/utility/meta/TypeList.hpp
@@ -31,25 +31,22 @@ namespace meta {
  */
 
 template <typename ...Ts>
-class TypeList;
+struct TypeList;
 
 namespace internal {
 
 using EmptyList = TypeList<>;
 
 template <typename ...Ts>
-class TypeListBase {
- private:
-  template <typename ...Tail> struct AppendHelper {
-    using type = TypeList<Ts..., Tail...>;
-  };
-
- public:
+struct TypeListBase {
   static constexpr std::size_t length = sizeof...(Ts);
 
   using type = TypeList<Ts...>;
   using self = type;
 
+  // ---------------------------------------------------------------------------
+  // Meta-methods.
+
   template <template <typename ...> class Host>
   using bind_to = Host<Ts...>;
 
@@ -76,7 +73,7 @@ class TypeListBase {
   using unique = typename UniqueImpl<EmptyList, self, DumbT...>::type;
 
   template <typename TL>
-  using append = typename TL::template bind_to<AppendHelper>::type;
+  using append = typename AppendImpl<self, TL>::type;
 
   template <typename TL>
   using cartesian_product = typename CartesianProductImpl<self, TL>::type;
@@ -113,19 +110,32 @@ class TypeListBase {
 
   template <typename T>
   using as_sequence = typename AsSequenceImpl<T, Ts...>::type;
+
+  // ---------------------------------------------------------------------------
+  // Methods.
+
+  template <typename Collection, typename Instantiator>
+  static Collection Instantiate(const Instantiator &functor) {
+    return { functor(Ts())... };
+  }
+
+  template <typename Collection, template <typename ...> class Instantiator>
+  static Collection Instantiate() {
+    return { Instantiator<Ts>()()... };
+  }
 };
 
 }  // namespace internal
 
 template <typename T, typename ...Ts>
-class TypeList<T, Ts...> : public internal::TypeListBase<T, Ts...> {
+struct TypeList<T, Ts...> : public internal::TypeListBase<T, Ts...> {
  public:
   using head = T;
   using tail = TypeList<Ts...>;
 };
 
 template <>
-class TypeList<> : public internal::TypeListBase<> {};
+struct TypeList<> : public internal::TypeListBase<> {};
 
 /** @} */
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/utility/meta/TypeListMetaFunctions.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeListMetaFunctions.hpp b/utility/meta/TypeListMetaFunctions.hpp
index baebe91..ba3a419 100644
--- a/utility/meta/TypeListMetaFunctions.hpp
+++ b/utility/meta/TypeListMetaFunctions.hpp
@@ -30,7 +30,7 @@ namespace meta {
  */
 
 template <typename ...Ts>
-class TypeList;
+struct TypeList;
 
 
 template <typename T>
@@ -112,6 +112,15 @@ struct UniqueImpl<Out, Rest,
                  typename Rest::tail> {};
 
 
+template <typename TL, typename UL>
+struct AppendImpl;
+
+template <typename ...Ts, typename ...Us>
+struct AppendImpl<meta::TypeList<Ts...>, meta::TypeList<Us...>> {
+  using type = meta::TypeList<Ts..., Us...>;
+};
+
+
 template <typename Out, typename Rest, typename Subtrahend, typename Enable = void>
 struct SubtractImpl;
 


[37/38] incubator-quickstep git commit: Type as first class citizen

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/preprocessed/SqlLexer_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.cpp b/parser/preprocessed/SqlLexer_gen.cpp
index 05d2d3c..eef10d4 100644
--- a/parser/preprocessed/SqlLexer_gen.cpp
+++ b/parser/preprocessed/SqlLexer_gen.cpp
@@ -592,8 +592,8 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 168
-#define YY_END_OF_BUFFER 169
+#define YY_NUM_RULES 151
+#define YY_END_OF_BUFFER 152
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -601,74 +601,67 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_accept[594] =
+static const flex_int16_t yy_accept[534] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  169,    2,    2,  167,  167,  166,  165,  167,
-      144,  140,  143,  140,  140,  163,  167,  133,  130,  134,
-      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
-      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
-      162,  162,  162,  162,  162,  141,  138,  139,    4,    5,
-        5,    3,  159,  159,  156,  160,  160,  154,  161,  161,
-      158,    1,  166,  131,  164,  163,  163,  163,    0,  137,
-      135,  132,  136,  162,  162,  162,  162,   10,  162,  162,
-      162,   23,  162,  162,  162,  162,  162,  162,  162,  162,
-
-      162,  162,  162,  142,  162,  162,  162,  162,  162,  162,
-      162,  162,  162,  162,  162,  162,   59,   68,  162,  162,
-      162,  162,  162,  162,  162,  162,  162,  162,  162,   82,
-       83,  162,  162,  162,  162,  162,  162,  162,  162,  162,
-      162,  162,  162,  162,  162,  162,  162,  162,  114,  162,
-      162,  162,  162,  162,  162,  162,  162,  162,    4,    5,
-        3,  159,  155,  160,  153,  153,  145,  147,  148,  149,
-      150,  151,  152,  153,  161,  157,  164,  163,    0,  163,
-        6,    7,  162,    9,   11,  162,  162,   15,  162,  162,
-      162,  162,  162,  162,  162,  162,  162,  162,  162,   34,
-
-      162,  162,  162,  162,  162,  162,  162,  162,   44,  162,
-      162,  162,  162,  162,  162,   51,  162,  162,  162,  162,
-      162,  162,  162,  162,  162,   63,  162,   70,  162,  162,
-      162,  162,  162,  162,  162,   78,  162,   81,  162,  162,
-      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
-      162,   99,  162,  162,  104,  105,  162,  162,  162,  162,
-      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
-      162,  162,  162,  145,  147,  146,  162,  162,  162,  162,
-      162,  162,  162,   20,   21,   24,  162,  162,  162,   29,
-      162,  162,  162,   32,  162,  162,  162,   38,  162,  162,
-
-       42,   43,  162,  162,  162,  162,  162,  162,  162,   53,
-       54,  162,   56,  162,   58,  162,  162,  162,  162,   67,
-       69,   71,   72,   73,  162,   75,  162,  162,   79,  162,
-      162,   86,  162,  162,  162,  162,  162,   93,  162,   95,
-      162,  162,  162,  101,  162,  162,  162,  162,  162,  162,
-      162,  162,  111,  112,  115,  162,  162,  162,  162,  162,
-      162,  162,  162,  124,  162,  162,  127,  128,  145,  146,
-        8,  162,  162,  162,  162,  162,  162,  162,   26,  162,
-      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
-      162,  162,  162,   47,   48,   49,  162,  162,   55,  162,
-
-       60,   61,  162,  162,  162,   74,  162,   77,   80,   84,
-       85,  162,  162,  162,  162,  162,   94,  162,  162,   98,
-      162,  162,  162,  162,  162,  162,  162,  110,  162,  162,
-      162,  118,  162,  162,  121,  162,  162,  125,  162,  162,
-      162,  162,   14,  162,  162,  162,  162,  162,   27,  162,
-       30,  162,  162,  162,  162,  162,   37,  162,  162,   41,
-       45,  162,  162,  162,   57,   62,  162,  162,  162,   76,
-      162,  162,  162,  162,  162,  162,   97,  162,  102,  103,
-      162,  107,  108,  162,  162,  162,  162,  119,  120,  122,
-      162,  126,  162,  162,   13,  162,  162,  162,  162,  162,
-
-      162,   22,   31,  162,   35,   36,  162,  162,   46,  162,
-       52,   64,  162,  162,  162,   89,  162,   91,  162,  162,
-      162,  162,  162,  162,  162,  162,  123,  162,  162,  162,
-      162,  162,  162,  162,  162,   33,  162,   40,  162,  162,
-       66,  162,  162,   92,  162,  162,  106,  162,  162,  162,
-      162,  162,   12,  162,  162,  162,  162,   25,  162,  162,
-       50,   65,   87,   90,  162,  162,  109,  113,  162,  117,
-      129,   16,  162,  162,  162,   28,   39,   88,   96,  162,
-      162,  162,   18,   19,  162,  116,  162,  162,  162,  100,
-      162,   17,    0
-
+        0,    0,  152,    2,    2,  150,  150,  149,  148,  150,
+      127,  123,  126,  123,  123,  146,  150,  116,  113,  117,
+      145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
+      145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
+      145,  145,  145,  145,  145,  124,  121,  122,    4,    5,
+        5,    3,  142,  142,  139,  143,  143,  137,  144,  144,
+      141,    1,  149,  114,  147,  146,  146,  146,    0,  120,
+      118,  115,  119,  145,  145,  145,  145,   10,  145,  145,
+      145,   21,  145,  145,  145,  145,  145,  145,  145,  145,
+
+      145,  145,  125,  145,  145,  145,  145,  145,  145,  145,
+      145,  145,  145,  145,   50,   57,  145,  145,  145,  145,
+      145,  145,  145,  145,  145,  145,   70,   71,  145,  145,
+      145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
+      145,  145,  145,  145,   99,  145,  145,  145,  145,  145,
+      145,  145,  145,  145,    4,    5,    3,  142,  138,  143,
+      136,  136,  128,  130,  131,  132,  133,  134,  135,  136,
+      144,  140,  147,  146,    0,  146,    6,    7,  145,    9,
+       11,  145,  145,  145,  145,  145,  145,  145,  145,  145,
+      145,  145,   28,  145,  145,  145,  145,  145,  145,   36,
+
+      145,  145,  145,  145,  145,   42,  145,  145,  145,  145,
+      145,  145,  145,  145,  145,  145,  145,   59,  145,  145,
+      145,  145,  145,  145,   66,  145,   69,  145,  145,  145,
+      145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
+       87,  145,  145,   92,   93,  145,  145,  145,  145,  145,
+      145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
+      128,  130,  129,  145,  145,  145,  145,  145,  145,   18,
+       19,  145,  145,  145,   25,  145,  145,  145,  145,  145,
+       31,  145,   34,   35,  145,  145,  145,  145,  145,  145,
+       44,   45,  145,   47,  145,   49,  145,  145,  145,  145,
+
+       56,   58,   60,   61,   62,  145,  145,  145,   67,  145,
+      145,   74,  145,  145,  145,  145,  145,   81,  145,   83,
+      145,  145,  145,   89,  145,  145,  145,  145,  145,  145,
+      145,   98,  100,  145,  145,  145,  145,  145,  145,  145,
+      108,  145,  145,  111,  112,  128,  129,    8,  145,  145,
+      145,  145,  145,   22,  145,  145,  145,  145,  145,  145,
+      145,  145,  145,  145,  145,   39,   40,  145,  145,   46,
+      145,   51,   52,  145,  145,   63,  145,   65,   68,   72,
+       73,  145,  145,  145,  145,  145,   82,  145,  145,   86,
+      145,  145,  145,  145,  145,  145,   97,  145,  145,  103,
+
+      145,  145,  106,  145,  109,  145,  145,  145,  145,  145,
+      145,  145,   23,  145,   26,  145,  145,  145,   30,  145,
+      145,   37,  145,  145,  145,   48,   53,  145,  145,   64,
+      145,  145,  145,  145,  145,  145,   85,  145,   90,   91,
+       94,   95,  145,  145,  145,  104,  105,  107,  110,  145,
+       13,  145,  145,  145,  145,  145,   20,   27,   29,  145,
+      145,   38,  145,   43,  145,  145,  145,   77,  145,   79,
+      145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
+      145,  145,  145,   33,  145,  145,   55,  145,  145,   80,
+      145,  145,  145,  145,  145,   12,  145,  145,  145,  145,
+
+      145,  145,   41,   54,   75,   78,  145,  145,   96,  145,
+      102,   14,  145,  145,  145,   24,   32,   76,   84,  145,
+      145,  145,   16,   17,  145,  101,  145,  145,  145,   88,
+      145,   15,    0
     } ;
 
 static const YY_CHAR yy_ec[256] =
@@ -715,155 +708,141 @@ static const YY_CHAR yy_meta[74] =
         8,    1,    1
     } ;
 
-static const flex_int16_t yy_base[609] =
+static const flex_int16_t yy_base[549] =
     {   0,
         0,    1,   46,    0,  119,  192,    2,    3,  129,  130,
-        6,   10,  231, 1299, 1299,    0, 1299,   13, 1299,  151,
-     1299, 1299, 1299,  152,    6,  118,  132,    4, 1299,   28,
-      118,  131,  248,  188,  197,  298,  106,  124,  112,  118,
-      129,  193,  126,  123,  237,  194,  121,  195,  240,  348,
-      238,  185,  256,    0,  182, 1299, 1299, 1299,   27,    4,
-       19,    0,    0,    0,   17,    0,    0,  412,    0,    0,
-        8,    0,   22, 1299,    0,  306,  309,  326,   18, 1299,
-     1299, 1299, 1299,    0,  197,  193,  203,  214,  224,  305,
-      247,    0,  249,  325,  359,  266,  275,  261,  298,  355,
-
-      284,  288,  300, 1299,  298,  320,  342,  323,  332,  350,
-      364,  353,  360,  362,  362,  362,  405,    0,  379,  368,
-      396,  410,  410,  406,  413,  414,  409,  419,  427,    0,
-      430,  415,  432,  421,  422,  437,  432,  437,  466,  467,
-      453,  474,  477,  475,  479,  480,  478,  471,    0,  464,
-      471,  486,  485,  481,  479,  487,  479,  497,    0,   29,
-        0,    0, 1299,    0, 1299, 1299,   22,   24, 1299, 1299,
-     1299, 1299, 1299,    0,    0, 1299,    0,  534,   26,   28,
-        0,    0,  499,    0,  504,  502,  522,  509,  531,  530,
-      518,  534,  519,  522,  517,  542,  524,  527,  542,    0,
-
-      539,  548,  546,  549,  533,  553,  540,  552,    0,  539,
-      541,  543,  548,  582,  577,  585,  579,  581,  573,  587,
-      588,  580,  594,  595,  596,  598,  588,    0,  584,  585,
-      601,  598,  601,  588,  590,    0,  599,    0,  609,  610,
-      598,  597,  617,  622,  635,  621,  640,  639,  647,  648,
-      647,  637,  642,  653,    0,  647,  656,  641,  650,  649,
-      659,  660,  655,  653,  657,  668,  659,  654,  675,  681,
-      679,  697,  688,   30,  132,    0,  690,  695,  705,  697,
-      708,  703,  702,    0,    0,  715,  706,  705,  699,    0,
-      700,  703,  717,  703,  712,  705,  707,  724,  721,  719,
-
-        0,    0,  712,  732,  731,  721,  733,  742,  754,    0,
-        0,  748,    0,  752,    0,  743,  750,  751,  765,    0,
-        0,    0,    0,    0,  751,    0,  753,  766,  756,  758,
-      759,    0,  769,  774,  775,  780,  766,    0,  780,    0,
-      769,  764,  769,    0,  786,  777,  791,  787,  793,  794,
-      801,  817,    0,  805,    0,  820,  805,  813,  808,  810,
-      824,  827,  825,    0,  829,  820,    0,  823,  153, 1299,
-        0,  833,  833,  819,  840,  826,  837,  843,    0,  833,
-      830,  844,  847,  843,  860,  872,  867,  875,  868,  869,
-      879,  866,  884,    0,    0,    0,  865,  882,    0,  883,
-
-        0,    0,  871,  887,  874,    0,  889,    0,    0,    0,
-        0,  875,  883,  895,  882,  892,    0,  898,  888,    0,
-      900,  902,  887,  901,  897,  907,  913,    0,  917,  919,
-      926,    0,  936,  937,    0,  924,  944,    0,  923,  932,
-      939,  935,    0,  928,  933,  951,  944,  934,    0,  954,
-        0,  952,  938,  946,  949,  942,    0,  959,  961,    0,
-        0,  945,  959,  959,    0,    0,  967,  984,  994,    0,
-      987,  978,  990,  975,  981,  989,    0,  992,    0,    0,
-      991,    0,    0,  997, 1006, 1007, 1005,    0,    0,    0,
-      992,    0,  997,  998,    0, 1004, 1000, 1003, 1005, 1014,
-
-     1011,    0,    0, 1016,    0,    0, 1013, 1003,    0, 1012,
-        0,    0, 1028, 1031, 1032,    0, 1039,    0, 1029, 1053,
-     1048, 1038, 1045, 1048, 1049, 1058,    0, 1044, 1058, 1052,
-     1051, 1052, 1049, 1052, 1057,    0, 1059,    0, 1067, 1055,
-        0, 1063, 1071,    0, 1074, 1067,    0, 1074, 1068, 1073,
-     1097, 1097,    0, 1104, 1107, 1102, 1110,    0, 1096, 1110,
-        0,    0, 1100,    0, 1101, 1112,    0,    0, 1110,    0,
-        0,    0, 1105, 1119, 1107,    0,    0,    0,    0, 1106,
-     1122, 1108,    0,    0, 1124,    0, 1122, 1114, 1128,    0,
-     1116,    0, 1299, 1181, 1191, 1201, 1211, 1221, 1225, 1228,
-
-     1234, 1244, 1254, 1264, 1274, 1284, 1289, 1291
+        6,   10,  231, 1182, 1182,    0, 1182,   13, 1182,  151,
+     1182, 1182, 1182,  152,    6,  118,  132,    4, 1182,   28,
+      118,  131,  248,  188,  197,  186,  106,  124,  112,  118,
+      129,  193,  126,  123,  237,  195,  121,  256,  255,  298,
+      189,  185,  236,    0,  194, 1182, 1182, 1182,   27,    4,
+       19,    0,    0,    0,   17,    0,    0,  362,    0,    0,
+        8,    0,   22, 1182,    0,  257,  306,  313,   18, 1182,
+     1182, 1182, 1182,    0,  206,  302,  208,  214,  234,  244,
+      266,    0,  284,  307,  309,  310,  315,  306,  301,  350,
+
+      311,  316, 1182,  315,  332,  352,  325,  320,  359,  355,
+      361,  359,  356,  358,  406,    0,  374,  359,  368,  382,
+      381,  375,  381,  394,  407,  416,    0,  423,  408,  424,
+      412,  413,  427,  424,  420,  434,  430,  415,  465,  441,
+      440,  443,  444,  442,    0,  429,  436,  478,  449,  463,
+      466,  478,  470,  485,    0,   29,    0,    0, 1182,    0,
+     1182, 1182,   22,   24, 1182, 1182, 1182, 1182, 1182,    0,
+        0, 1182,    0,  493,   26,   28,    0,    0,  486,    0,
+      487,  470,  471,  493,  490,  496,  479,  483,  478,  503,
+      485,  493,    0,  516,  513,  523,  510,  519,  531,    0,
+
+      519,  523,  523,  524,  532,  540,  535,  537,  529,  543,
+      543,  535,  549,  551,  552,  553,  546,    0,  541,  542,
+      558,  557,  548,  555,    0,  564,    0,  579,  583,  575,
+      574,  593,  596,  587,  581,  596,  594,  602,  603,  601,
+      591,  596,  607,    0,    0,  609,  596,  604,  604,  614,
+      609,  611,  634,  626,  619,  613,  628,  648,  646,  639,
+       30,  132,    0,  640,  645,  655,  656,  653,  652,    0,
+        0,  655,  654,  648,    0,  649,  652,  667,  652,  654,
+      671,  668,    0,    0,  659,  681,  679,  665,  676,  683,
+        0,    0,  684,    0,  690,    0,  683,  691,  692,  694,
+
+        0,    0,    0,    0,    0,  695,  696,  709,  699,  701,
+      704,    0,  714,  719,  720,  725,  709,    0,  723,    0,
+      712,  707,  712,    0,  730,  721,  734,  722,  721,  723,
+      744,    0,    0,  745,  737,  748,  744,  747,  761,  765,
+        0,  768,  759,    0,    0,  153, 1182,    0,  771,  771,
+      776,  764,  775,    0,  768,  766,  780,  781,  774,  777,
+      785,  778,  779,  776,  795,    0,    0,  777,  794,    0,
+      800,    0,    0,  788,  801,    0,  811,    0,    0,    0,
+        0,  805,  812,  824,  813,  823,    0,  828,  818,    0,
+      830,  834,  819,  822,  821,  824,    0,  824,  830,    0,
+
+      841,  842,    0,  829,    0,  827,  842,  839,  834,  840,
+      858,  856,    0,  865,    0,  869,  858,  861,    0,  879,
+      881,    0,  866,  880,  876,    0,    0,  886,  891,    0,
+      884,  876,  888,  873,  879,  886,    0,  889,    0,    0,
+        0,    0,  893,  903,  901,    0,    0,    0,    0,  892,
+        0,  899,  894,  898,  902,  907,    0,    0,    0,  908,
+      903,    0,  910,    0,  929,  924,  924,    0,  927,    0,
+      917,  941,  938,  934,  936,  945,  944,  940,  939,  940,
+      937,  944,  945,    0,  953,  942,    0,  949,  957,    0,
+      961,  954,  962,  956,  970,    0,  968,  976,  970,  985,
+
+      974,  990,    0,    0,  980,    0,  981,  993,    0,  993,
+        0,    0,  988, 1002,  990,    0,    0,    0,    0,  989,
+     1007,  993,    0,    0, 1009,    0, 1006,  998, 1012,    0,
+      999,    0, 1182, 1064, 1074, 1084, 1094, 1104, 1108, 1111,
+     1117, 1127, 1137, 1147, 1157, 1167, 1172, 1174
     } ;
 
-static const flex_int16_t yy_def[609] =
+static const flex_int16_t yy_def[549] =
     {   0,
-      594,  594,  593,    3,  595,  595,  596,  596,  597,  597,
-      598,  598,  593,  593,  593,  599,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  593,  593,  593,  593,  593,
-      593,  601,  602,  602,  593,  603,  603,  604,  605,  605,
-      593,  599,  593,  593,  606,  593,  593,  593,  593,  593,
-      593,  593,  593,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-
-      600,  600,  600,  593,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  593,  593,
-      601,  602,  593,  603,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  607,  605,  593,  606,  593,  593,  593,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  593,  593,  608,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  593,  593,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,    0,  593,  593,  593,  593,  593,  593,  593,
-
-      593,  593,  593,  593,  593,  593,  593,  593
+      534,  534,  533,    3,  535,  535,  536,  536,  537,  537,
+      538,  538,  533,  533,  533,  539,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  533,  533,  533,  533,  533,
+      533,  541,  542,  542,  533,  543,  543,  544,  545,  545,
+      533,  539,  533,  533,  546,  533,  533,  533,  533,  533,
+      533,  533,  533,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+
+      540,  540,  533,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  533,  533,  541,  542,  533,  543,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  547,
+      545,  533,  546,  533,  533,  533,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      533,  533,  548,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  533,  533,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,  540,  540,  540,  540,  540,  540,  540,  540,
+      540,  540,    0,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533
     } ;
 
-static const flex_int16_t yy_nxt[1373] =
+static const flex_int16_t yy_nxt[1256] =
     {   0,
-      593,  159,   15,   15,   64,   64,  160,  160,   70,   65,
-       65,   71,   70,  176,   73,   71,   73,   76,   76,   81,
-       82,  160,  160,   73,  163,   73,  179,  179,  159,  180,
-      180,  160,  160,  274,  275,  275,  275,  180,  180,  180,
-      180,  369,  275,   83,   16,   16,   17,   18,   19,   18,
+      533,  155,   15,   15,   64,   64,  156,  156,   70,   65,
+       65,   71,   70,  172,   73,   71,   73,   76,   76,   81,
+       82,  156,  156,   73,  159,   73,  175,  175,  155,  176,
+      176,  156,  156,  261,  262,  262,  262,  176,  176,  176,
+      176,  346,  262,   83,   16,   16,   17,   18,   19,   18,
        20,   21,   22,   23,   22,   24,   25,   26,   26,   27,
        28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
        38,   39,   40,   41,   42,   43,   44,   45,   46,   47,
@@ -874,151 +853,138 @@ static const flex_int16_t yy_nxt[1373] =
        49,   50,   51,   52,   53,   54,   55,   57,   58,   17,
        59,   60,   61,   17,   17,   17,   17,   17,   77,   78,
        78,   67,   67,   17,   17,   17,   65,   65,   85,   79,
-      114,  115,  117,  275,  275,   80,   86,  118,   87,  119,
-      120,  125,   89,   88,  127,  116,   90,  126,  137,   91,
-      128,   75,   17,   17,  275,  275,   74,   85,   79,  114,
-      115,  117,   92,   68,   68,   86,  118,   87,  119,  120,
-      125,   89,   88,  127,  116,   90,  126,  137,   91,  128,
+      112,  113,  115,  262,  262,   80,   86,  116,   87,  117,
+      118,  122,   89,   88,  124,  114,   90,  123,  134,   91,
+      125,   75,   17,   17,  262,  262,   74,   85,   79,  112,
+      113,  115,   92,   68,   68,   86,  116,   87,  117,  118,
+      122,   89,   88,  124,  114,   90,  123,  134,   91,  125,
        17,   17,   17,   59,   60,   61,   17,   17,   17,   17,
 
-       17,   92,  155,  158,  104,   99,   17,   17,   17,  100,
-      121,  134,  138,  101,  122,  135,  139,  181,  123,  102,
-      140,  182,  103,  184,  124,  105,  141,  106,  136,  183,
-      593,  155,  158,  185,   99,   17,   17,  107,  100,  121,
-      134,  138,  101,  122,  135,  139,  181,  123,  102,  140,
-      182,  103,  184,  124,  105,  141,  106,  136,  183,  129,
-      186,  142,  185,   17,   17,   93,  107,  130,  152,  143,
-      153,  131,   94,  154,  132,  133,  144,  145,  189,   95,
-      156,  157,   96,   97,  190,   98,  593,  196,  129,  186,
-      142,  593,  593,  197,   93,  198,  130,  152,  143,  153,
-
-      131,   94,  154,  132,  133,  144,  145,  189,   95,  156,
-      157,   96,   97,  190,   98,  108,  196,   76,   76,  205,
-      178,  178,  197,  109,  198,  206,  110,   79,  187,  111,
-       79,  207,  112,  208,  199,  113,   77,   78,   78,  200,
-      209,  188,  191,  593,  108,  593,  192,   79,  205,  593,
-      593,  212,  109,  593,  206,  110,   79,  187,  111,   79,
-      207,  112,  208,  199,  113,  146,  213,  210,  200,  209,
-      188,  191,  147,  148,  201,  192,   79,  202,  211,  149,
-      212,  214,  150,  203,  217,  151,  593,  193,  218,  194,
-      204,  195,  215,  219,  146,  213,  210,  220,  216,  222,
-
-      221,  147,  148,  201,  227,  593,  202,  211,  149,  228,
-      214,  150,  203,  217,  151,  166,  193,  218,  194,  204,
-      195,  215,  219,  167,  168,  223,  220,  216,  222,  221,
-      169,  229,  230,  227,  170,  224,  233,  231,  228,  232,
-      225,  226,  171,  234,  235,  236,  172,  237,  173,  238,
-      239,  240,  174,  241,  223,  242,  243,  246,  244,  169,
-      229,  230,  245,  170,  224,  233,  231,  247,  232,  225,
-      226,  171,  234,  235,  236,  172,  237,  173,  238,  239,
-      240,  174,  241,  248,  242,  243,  246,  244,  249,  250,
-      251,  245,  252,  253,  256,  257,  247,  258,  259,  260,
-
-      261,  262,  254,  263,  264,  266,  267,  268,  270,  271,
-      255,  265,  248,  269,  273,  272,  593,  249,  250,  251,
-      277,  252,  253,  256,  257,  278,  258,  259,  260,  261,
-      262,  254,  263,  264,  266,  267,  268,  270,  271,  255,
-      265,  279,  269,  273,  272,  178,  178,  280,  281,  277,
-      282,  284,  286,  287,  278,   79,  288,  289,  290,  291,
-      292,  293,  283,  294,  295,  296,  285,  297,  298,  299,
-      279,  300,  301,  302,  303,  304,  280,  281,  305,  282,
-      284,  286,  287,  306,   79,  288,  289,  290,  291,  292,
-      293,  283,  294,  295,  296,  285,  297,  298,  299,  307,
-
-      300,  301,  302,  303,  304,  308,  309,  305,  310,  311,
-      312,  313,  306,  314,  315,  316,  317,  318,  321,  319,
-      322,  323,  324,  325,  326,  327,  328,  329,  307,  320,
-      330,  331,  332,  333,  308,  309,  334,  310,  311,  312,
-      313,  335,  314,  315,  316,  317,  318,  321,  319,  322,
-      323,  324,  325,  326,  327,  328,  329,  338,  320,  330,
-      331,  332,  333,  339,  336,  334,  337,  340,  341,  342,
-      335,  343,  344,  346,  347,  348,  351,  349,  352,  353,
-      354,  355,  345,  356,  357,  360,  338,  350,  358,  361,
-      359,  362,  339,  336,  363,  337,  340,  341,  342,  366,
-
-      343,  344,  346,  347,  348,  351,  349,  352,  353,  354,
-      355,  364,  356,  357,  360,  365,  350,  358,  361,  359,
-      362,  367,  368,  363,  371,  372,  373,  374,  366,  375,
-      376,  377,  378,  379,  380,  381,  382,  383,  384,  385,
-      364,  386,  387,  388,  365,  389,  390,  391,  392,  393,
-      367,  368,  394,  371,  372,  373,  374,  395,  375,  376,
-      377,  378,  379,  380,  381,  382,  383,  384,  385,  396,
-      386,  387,  388,  397,  389,  390,  391,  392,  393,  398,
-      399,  394,  400,  401,  402,  403,  395,  406,  404,  407,
-      408,  409,  410,  411,  412,  413,  414,  415,  396,  405,
-
-      416,  417,  397,  418,  419,  420,  421,  422,  398,  399,
-      423,  400,  401,  402,  403,  424,  406,  404,  407,  408,
-      409,  410,  411,  412,  413,  414,  415,  425,  405,  416,
-      417,  426,  418,  419,  420,  421,  422,  427,  428,  423,
-      429,  430,  431,  432,  424,  433,  434,  435,  436,  437,
-      438,  439,  440,  441,  442,  443,  425,  444,  445,  447,
-      426,  446,  448,  449,  450,  451,  427,  428,  452,  429,
-      430,  431,  432,  453,  433,  434,  435,  436,  437,  438,
-      439,  440,  441,  442,  443,  454,  444,  445,  447,  455,
-      446,  448,  449,  450,  451,  456,  457,  452,  458,  459,
-
-      460,  461,  453,  462,  463,  464,  465,  466,  467,  468,
-      470,  471,  469,  472,  454,  473,  474,  475,  455,  476,
-      477,  478,  479,  480,  456,  457,  481,  458,  459,  460,
-      461,  482,  462,  463,  464,  465,  466,  467,  468,  470,
-      471,  469,  472,  483,  473,  474,  475,  484,  476,  477,
-      478,  479,  480,  485,  486,  481,  487,  488,  489,  490,
-      482,  491,  492,  493,  494,  495,  496,  497,  498,  499,
-      500,  501,  483,  502,  503,  504,  484,  505,  506,  507,
-      508,  509,  485,  486,  510,  487,  488,  489,  490,  511,
-      491,  492,  493,  494,  495,  496,  497,  498,  499,  500,
-
-      501,  512,  502,  503,  504,  513,  505,  506,  507,  508,
-      509,  514,  515,  510,  516,  517,  518,  519,  511,  520,
-      521,  522,  523,  524,  525,  526,  527,  528,  529,  530,
-      512,  531,  532,  533,  513,  534,  535,  536,  537,  538,
-      514,  515,  539,  516,  517,  518,  519,  540,  520,  521,
-      522,  523,  524,  525,  526,  527,  528,  529,  530,  541,
-      531,  532,  533,  542,  534,  535,  536,  537,  538,  543,
-      544,  539,  545,  546,  547,  548,  540,  549,  550,  551,
-      552,  553,  554,  555,  556,  557,  558,  559,  541,  560,
-      561,  562,  542,  563,  564,  565,  566,  567,  543,  544,
-
-      568,  545,  546,  547,  548,  569,  549,  550,  551,  552,
-      553,  554,  555,  556,  557,  558,  559,  570,  560,  561,
-      562,  571,  563,  564,  565,  566,  567,  572,  573,  568,
-      574,  575,  576,  577,  569,  578,  579,  580,  581,  582,
-      583,  584,  585,  586,  587,  588,  570,  589,  590,  591,
-      571,  592,  593,  593,  593,  593,  572,  573,  593,  574,
-      575,  576,  577,  593,  578,  579,  580,  581,  582,  583,
-      584,  585,  586,  587,  588,  593,  589,  590,  591,  593,
-      592,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-       14,   62,   62,   62,   62,   62,   62,   62,   62,   62,
-
-       62,   63,   63,   63,   63,   63,   63,   63,   63,   63,
-       63,   66,   66,   66,   66,   66,   66,   66,   66,   66,
-       66,   69,   69,   69,   69,   69,   69,   69,   69,   69,
-       69,   72,   72,   84,   84,   84,  593,   84,  161,  161,
-      161,  161,  593,  161,  162,  162,  162,  593,  162,  162,
-      162,  162,  162,  162,  164,  164,  164,  593,  164,  164,
-      164,  164,  593,  164,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  175,  175,  593,  175,  175,  175,
-      175,  175,  175,  175,  177,  593,  177,  177,  177,  177,
-      177,  177,  177,  177,  276,  276,  370,  370,   13,  593,
-
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593
+       17,   92,  151,  107,  103,   99,   17,   17,   17,  100,
+      119,  108,  131,  101,  120,  154,  132,  109,  121,  148,
+      110,  149,  102,  111,  150,  104,  177,  105,  180,  133,
+      533,  151,  107,  181,   99,   17,   17,  106,  100,  119,
+      108,  131,  101,  120,  154,  132,  109,  121,  148,  110,
+      149,  102,  111,  150,  104,  177,  105,  180,  133,  126,
+      152,  153,  181,   17,   17,   93,  106,  127,   76,   76,
+      182,  128,   94,  135,  129,  130,  139,  136,   79,   95,
+      183,  137,   96,   97,  140,   98,  533,  138,  126,  152,
+      153,  141,  142,  533,   93,  533,  127,  184,  533,  182,
+
+      128,   94,  135,  129,  130,  139,  136,   79,   95,  183,
+      137,   96,   97,  140,   98,  143,  138,  174,  174,  185,
+      141,  142,  144,   77,   78,   78,  184,   79,  186,  145,
+      178,  190,  146,  191,   79,  147,  533,  187,  179,  188,
+      192,  189,  193,  533,  143,  533,  197,  198,  185,  533,
+      199,  144,  200,  203,  204,  533,   79,  186,  145,  178,
+      190,  146,  191,   79,  147,  162,  187,  179,  188,  192,
+      189,  193,  194,  163,  164,  197,  198,  201,  195,  199,
+      165,  200,  203,  204,  166,  196,  207,  205,  202,  208,
+      209,  210,  167,  206,  211,  212,  168,  533,  169,  217,
+
+      218,  194,  170,  219,  220,  223,  201,  195,  221,  165,
+      222,  224,  533,  166,  196,  207,  205,  202,  208,  209,
+      210,  167,  206,  211,  212,  168,  213,  169,  217,  218,
+      225,  170,  219,  220,  223,  226,  214,  221,  227,  222,
+      224,  215,  216,  228,  229,  230,  231,  232,  233,  235,
+      236,  237,  234,  240,  241,  213,  238,  239,  245,  225,
+      246,  247,  248,  249,  226,  214,  250,  227,  251,  254,
+      215,  216,  228,  229,  230,  231,  232,  233,  235,  236,
+      237,  234,  240,  241,  242,  238,  239,  245,  255,  246,
+      247,  248,  249,  243,  256,  250,  252,  251,  254,  257,
+
+      258,  244,  260,  253,  174,  174,  259,  264,  265,  266,
+      267,  270,  268,  242,   79,  272,  273,  255,  274,  275,
+      276,  277,  243,  256,  269,  252,  271,  278,  257,  258,
+      244,  260,  253,  279,  280,  259,  264,  265,  266,  267,
+      270,  268,  281,   79,  272,  273,  282,  274,  275,  276,
+      277,  283,  284,  269,  285,  271,  278,  286,  287,  288,
+      289,  290,  279,  280,  291,  292,  293,  294,  295,  296,
+      297,  281,  298,  299,  300,  282,  302,  303,  304,  305,
+      283,  284,  306,  285,  301,  307,  286,  287,  288,  289,
+      290,  308,  309,  291,  292,  293,  294,  295,  296,  297,
+
+      310,  298,  299,  300,  311,  302,  303,  304,  305,  312,
+      313,  306,  314,  301,  307,  315,  316,  318,  317,  319,
+      308,  309,  320,  321,  322,  323,  324,  326,  327,  310,
+      328,  330,  331,  311,  332,  333,  325,  334,  312,  313,
+      329,  314,  335,  338,  315,  316,  318,  317,  319,  339,
+      340,  320,  321,  322,  323,  324,  326,  327,  341,  328,
+      330,  331,  342,  332,  333,  336,  334,  337,  343,  329,
+      344,  335,  338,  345,  348,  349,  350,  351,  339,  340,
+      352,  353,  354,  355,  356,  357,  358,  341,  359,  360,
+      361,  342,  362,  363,  336,  364,  337,  343,  365,  344,
+
+      366,  367,  345,  348,  349,  350,  351,  368,  369,  352,
+      353,  354,  355,  356,  357,  358,  370,  359,  360,  361,
+      371,  362,  363,  372,  364,  373,  374,  365,  375,  366,
+      367,  376,  377,  378,  379,  380,  368,  369,  381,  382,
+      383,  384,  385,  386,  387,  370,  388,  389,  390,  371,
+      391,  392,  372,  393,  373,  374,  394,  375,  395,  396,
+      376,  377,  378,  379,  380,  397,  398,  381,  382,  383,
+      384,  385,  386,  387,  399,  388,  389,  390,  400,  391,
+      392,  401,  393,  402,  403,  394,  404,  395,  396,  405,
+      406,  407,  408,  409,  397,  398,  410,  412,  413,  411,
+
+      414,  415,  416,  399,  417,  418,  419,  400,  420,  421,
+      401,  422,  402,  403,  423,  404,  424,  425,  405,  406,
+      407,  408,  409,  426,  427,  410,  412,  413,  411,  414,
+      415,  416,  430,  417,  418,  419,  428,  420,  421,  429,
+      422,  431,  432,  423,  433,  424,  425,  434,  435,  436,
+      437,  438,  426,  427,  439,  440,  441,  442,  443,  444,
+      445,  430,  446,  447,  448,  428,  449,  450,  429,  451,
+      431,  432,  452,  433,  453,  454,  434,  435,  436,  437,
+      438,  455,  456,  439,  440,  441,  442,  443,  444,  445,
+      457,  446,  447,  448,  458,  449,  450,  459,  451,  460,
+
+      461,  452,  462,  453,  454,  463,  464,  465,  466,  467,
+      455,  456,  468,  469,  470,  471,  472,  473,  474,  457,
+      475,  476,  477,  458,  478,  479,  459,  480,  460,  461,
+      481,  462,  482,  483,  463,  464,  465,  466,  467,  484,
+      485,  468,  469,  470,  471,  472,  473,  474,  486,  475,
+      476,  477,  487,  478,  479,  488,  480,  489,  490,  481,
+      491,  482,  483,  492,  493,  494,  495,  496,  484,  485,
+      497,  498,  499,  500,  501,  502,  503,  486,  504,  505,
+      506,  487,  507,  508,  488,  509,  489,  490,  510,  491,
+      511,  512,  492,  493,  494,  495,  496,  513,  514,  497,
+
+      498,  499,  500,  501,  502,  503,  515,  504,  505,  506,
+      516,  507,  508,  517,  509,  518,  519,  510,  520,  511,
+      512,  521,  522,  523,  524,  525,  513,  514,  526,  527,
+      528,  529,  530,  531,  532,  515,  533,  533,  533,  516,
+      533,  533,  517,  533,  518,  519,  533,  520,  533,  533,
+      521,  522,  523,  524,  525,  533,  533,  526,  527,  528,
+      529,  530,  531,  532,   14,   14,   14,   14,   14,   14,
+       14,   14,   14,   14,   62,   62,   62,   62,   62,   62,
+       62,   62,   62,   62,   63,   63,   63,   63,   63,   63,
+       63,   63,   63,   63,   66,   66,   66,   66,   66,   66,
+
+       66,   66,   66,   66,   69,   69,   69,   69,   69,   69,
+       69,   69,   69,   69,   72,   72,   84,   84,   84,  533,
+       84,  157,  157,  157,  157,  533,  157,  158,  158,  158,
+      533,  158,  158,  158,  158,  158,  158,  160,  160,  160,
+      533,  160,  160,  160,  160,  533,  160,  161,  161,  161,
+      161,  161,  161,  161,  161,  161,  161,  171,  171,  533,
+      171,  171,  171,  171,  171,  171,  171,  173,  533,  173,
+      173,  173,  173,  173,  173,  173,  173,  263,  263,  347,
+      347,   13,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533
     } ;
 
-static const flex_int16_t yy_chk[1373] =
+static const flex_int16_t yy_chk[1256] =
     {   0,
-        0,  159,    1,    2,    7,    8,   60,   60,   11,    7,
+        0,  155,    1,    2,    7,    8,   60,   60,   11,    7,
         8,   11,   12,   71,   18,   12,   18,   25,   25,   28,
        28,   61,   61,   73,   65,   73,   79,   79,   59,   79,
-       79,  160,  160,  167,  167,  168,  168,  179,  179,  180,
-      180,  274,  274,   30,    1,    2,    3,    3,    3,    3,
+       79,  156,  156,  163,  163,  164,  164,  175,  175,  176,
+      176,  261,  261,   30,    1,    2,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
@@ -1029,146 +995,133 @@ static const flex_int16_t yy_chk[1373] =
         3,    3,    3,    3,    3,    3,    3,    3,    3,    5,
         5,    5,    5,    5,    5,    5,    5,    5,   26,   26,
        26,    9,   10,    5,    5,    5,    9,   10,   31,   26,
-       37,   38,   39,  275,  275,   27,   31,   39,   31,   40,
+       37,   38,   39,  262,  262,   27,   31,   39,   31,   40,
        41,   43,   32,   31,   44,   38,   32,   43,   47,   32,
-       44,   24,    5,    5,  369,  369,   20,   31,   26,   37,
+       44,   24,    5,    5,  346,  346,   20,   31,   26,   37,
        38,   39,   32,    9,   10,   31,   39,   31,   40,   41,
        43,   32,   31,   44,   38,   32,   43,   47,   32,   44,
         5,    5,    6,    6,    6,    6,    6,    6,    6,    6,
 
-        6,   32,   52,   55,   35,   34,    6,    6,    6,   34,
-       42,   46,   48,   34,   42,   46,   48,   85,   42,   34,
-       48,   86,   34,   87,   42,   35,   48,   35,   46,   86,
-       13,   52,   55,   88,   34,    6,    6,   35,   34,   42,
-       46,   48,   34,   42,   46,   48,   85,   42,   34,   48,
-       86,   34,   87,   42,   35,   48,   35,   46,   86,   45,
-       89,   49,   88,    6,    6,   33,   35,   45,   51,   49,
-       51,   45,   33,   51,   45,   45,   49,   49,   91,   33,
-       53,   53,   33,   33,   93,   33,    0,   96,   45,   89,
-       49,    0,    0,   97,   33,   98,   45,   51,   49,   51,
-
-       45,   33,   51,   45,   45,   49,   49,   91,   33,   53,
-       53,   33,   33,   93,   33,   36,   96,   76,   76,  101,
-       77,   77,   97,   36,   98,  102,   36,   76,   90,   36,
-       77,  103,   36,  105,   99,   36,   78,   78,   78,   99,
-      106,   90,   94,    0,   36,    0,   94,   78,  101,    0,
-        0,  108,   36,    0,  102,   36,   76,   90,   36,   77,
-      103,   36,  105,   99,   36,   50,  109,  107,   99,  106,
-       90,   94,   50,   50,  100,   94,   78,  100,  107,   50,
-      108,  110,   50,  100,  112,   50,    0,   95,  113,   95,
-      100,   95,  111,  114,   50,  109,  107,  115,  111,  116,
-
-      115,   50,   50,  100,  119,    0,  100,  107,   50,  120,
-      110,   50,  100,  112,   50,   68,   95,  113,   95,  100,
-       95,  111,  114,   68,   68,  117,  115,  111,  116,  115,
-       68,  121,  122,  119,   68,  117,  124,  123,  120,  123,
-      117,  117,   68,  125,  126,  127,   68,  128,   68,  129,
-      131,  132,   68,  133,  117,  134,  135,  137,  136,   68,
-      121,  122,  136,   68,  117,  124,  123,  138,  123,  117,
-      117,   68,  125,  126,  127,   68,  128,   68,  129,  131,
-      132,   68,  133,  139,  134,  135,  137,  136,  139,  139,
-      140,  136,  141,  142,  143,  144,  138,  145,  146,  147,
-
-      148,  150,  142,  151,  152,  153,  154,  155,  156,  157,
-      142,  152,  139,  155,  158,  157,    0,  139,  139,  140,
-      183,  141,  142,  143,  144,  185,  145,  146,  147,  148,
-      150,  142,  151,  152,  153,  154,  155,  156,  157,  142,
-      152,  186,  155,  158,  157,  178,  178,  187,  188,  183,
-      189,  190,  191,  192,  185,  178,  193,  194,  195,  196,
-      197,  198,  189,  199,  201,  202,  190,  203,  204,  205,
-      186,  206,  207,  208,  210,  211,  187,  188,  212,  189,
-      190,  191,  192,  213,  178,  193,  194,  195,  196,  197,
-      198,  189,  199,  201,  202,  190,  203,  204,  205,  214,
-
-      206,  207,  208,  210,  211,  215,  216,  212,  217,  218,
-      219,  220,  213,  221,  222,  223,  224,  225,  227,  226,
-      229,  230,  231,  232,  233,  234,  235,  237,  214,  226,
-      239,  240,  241,  242,  215,  216,  243,  217,  218,  219,
-      220,  244,  221,  222,  223,  224,  225,  227,  226,  229,
-      230,  231,  232,  233,  234,  235,  237,  246,  226,  239,
-      240,  241,  242,  247,  245,  243,  245,  248,  249,  250,
-      244,  251,  252,  253,  254,  256,  258,  257,  259,  260,
-      261,  262,  252,  263,  264,  266,  246,  257,  265,  267,
-      265,  268,  247,  245,  269,  245,  248,  249,  250,  271,
-
-      251,  252,  253,  254,  256,  258,  257,  259,  260,  261,
-      262,  270,  263,  264,  266,  270,  257,  265,  267,  265,
-      268,  272,  273,  269,  277,  278,  279,  280,  271,  281,
-      282,  283,  286,  287,  288,  289,  291,  292,  293,  294,
-      270,  295,  296,  297,  270,  298,  299,  300,  303,  304,
-      272,  273,  305,  277,  278,  279,  280,  306,  281,  282,
-      283,  286,  287,  288,  289,  291,  292,  293,  294,  307,
-      295,  296,  297,  308,  298,  299,  300,  303,  304,  309,
-      312,  305,  314,  316,  317,  318,  306,  325,  319,  327,
-      328,  329,  330,  331,  333,  334,  335,  336,  307,  319,
-
-      337,  339,  308,  341,  342,  343,  345,  346,  309,  312,
-      347,  314,  316,  317,  318,  348,  325,  319,  327,  328,
-      329,  330,  331,  333,  334,  335,  336,  349,  319,  337,
-      339,  350,  341,  342,  343,  345,  346,  351,  352,  347,
-      354,  356,  357,  358,  348,  359,  360,  361,  362,  363,
-      365,  366,  368,  372,  373,  374,  349,  375,  376,  377,
-      350,  376,  378,  380,  381,  382,  351,  352,  383,  354,
-      356,  357,  358,  384,  359,  360,  361,  362,  363,  365,
-      366,  368,  372,  373,  374,  385,  375,  376,  377,  386,
-      376,  378,  380,  381,  382,  387,  388,  383,  389,  390,
-
-      391,  392,  384,  393,  397,  398,  400,  403,  404,  405,
-      407,  412,  405,  413,  385,  414,  415,  416,  386,  418,
-      419,  421,  422,  423,  387,  388,  424,  389,  390,  391,
-      392,  425,  393,  397,  398,  400,  403,  404,  405,  407,
-      412,  405,  413,  426,  414,  415,  416,  427,  418,  419,
-      421,  422,  423,  429,  430,  424,  431,  433,  434,  436,
-      425,  437,  439,  440,  441,  442,  444,  445,  446,  447,
-      448,  450,  426,  452,  453,  454,  427,  455,  456,  458,
-      459,  462,  429,  430,  463,  431,  433,  434,  436,  464,
-      437,  439,  440,  441,  442,  444,  445,  446,  447,  448,
-
-      450,  467,  452,  453,  454,  468,  455,  456,  458,  459,
-      462,  469,  471,  463,  472,  473,  474,  475,  464,  476,
-      478,  481,  484,  485,  486,  487,  491,  493,  494,  496,
-      467,  497,  498,  499,  468,  500,  501,  504,  507,  508,
-      469,  471,  510,  472,  473,  474,  475,  513,  476,  478,
-      481,  484,  485,  486,  487,  491,  493,  494,  496,  514,
-      497,  498,  499,  515,  500,  501,  504,  507,  508,  517,
-      519,  510,  520,  521,  522,  523,  513,  524,  525,  526,
-      528,  529,  530,  531,  532,  533,  534,  535,  514,  537,
-      539,  540,  515,  542,  543,  545,  546,  548,  517,  519,
-
-      549,  520,  521,  522,  523,  550,  524,  525,  526,  528,
-      529,  530,  531,  532,  533,  534,  535,  551,  537,  539,
-      540,  552,  542,  543,  545,  546,  548,  554,  555,  549,
-      556,  557,  559,  560,  550,  563,  565,  566,  569,  573,
-      574,  575,  580,  581,  582,  585,  551,  587,  588,  589,
-      552,  591,    0,    0,    0,    0,  554,  555,    0,  556,
-      557,  559,  560,    0,  563,  565,  566,  569,  573,  574,
-      575,  580,  581,  582,  585,    0,  587,  588,  589,    0,
-      591,  594,  594,  594,  594,  594,  594,  594,  594,  594,
-      594,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-
-      595,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  597,  597,  597,  597,  597,  597,  597,  597,  597,
-      597,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  599,  599,  600,  600,  600,    0,  600,  601,  601,
-      601,  601,    0,  601,  602,  602,  602,    0,  602,  602,
-      602,  602,  602,  602,  603,  603,  603,    0,  603,  603,
-      603,  603,    0,  603,  604,  604,  604,  604,  604,  604,
-      604,  604,  604,  604,  605,  605,    0,  605,  605,  605,
-      605,  605,  605,  605,  606,    0,  606,  606,  606,  606,
-      606,  606,  606,  606,  607,  607,  608,  608,  593,  593,
-
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
-      593,  593
+        6,   32,   52,   36,   35,   34,    6,    6,    6,   34,
+       42,   36,   46,   34,   42,   55,   46,   36,   42,   51,
+       36,   51,   34,   36,   51,   35,   85,   35,   87,   46,
+       13,   52,   36,   88,   34,    6,    6,   35,   34,   42,
+       36,   46,   34,   42,   55,   46,   36,   42,   51,   36,
+       51,   34,   36,   51,   35,   85,   35,   87,   46,   45,
+       53,   53,   88,    6,    6,   33,   35,   45,   76,   76,
+       89,   45,   33,   48,   45,   45,   49,   48,   76,   33,
+       90,   48,   33,   33,   49,   33,    0,   48,   45,   53,
+       53,   49,   49,    0,   33,    0,   45,   91,    0,   89,
+
+       45,   33,   48,   45,   45,   49,   48,   76,   33,   90,
+       48,   33,   33,   49,   33,   50,   48,   77,   77,   93,
+       49,   49,   50,   78,   78,   78,   91,   77,   94,   50,
+       86,   96,   50,   97,   78,   50,    0,   95,   86,   95,
+       98,   95,   99,    0,   50,    0,  101,  102,   93,    0,
+      104,   50,  105,  107,  108,    0,   77,   94,   50,   86,
+       96,   50,   97,   78,   50,   68,   95,   86,   95,   98,
+       95,   99,  100,   68,   68,  101,  102,  106,  100,  104,
+       68,  105,  107,  108,   68,  100,  110,  109,  106,  111,
+      112,  113,   68,  109,  113,  114,   68,    0,   68,  117,
+
+      118,  100,   68,  119,  120,  122,  106,  100,  121,   68,
+      121,  123,    0,   68,  100,  110,  109,  106,  111,  112,
+      113,   68,  109,  113,  114,   68,  115,   68,  117,  118,
+      124,   68,  119,  120,  122,  125,  115,  121,  126,  121,
+      123,  115,  115,  128,  129,  130,  131,  132,  133,  134,
+      135,  136,  133,  137,  138,  115,  136,  136,  140,  124,
+      141,  142,  143,  144,  125,  115,  146,  126,  147,  149,
+      115,  115,  128,  129,  130,  131,  132,  133,  134,  135,
+      136,  133,  137,  138,  139,  136,  136,  140,  150,  141,
+      142,  143,  144,  139,  151,  146,  148,  147,  149,  152,
+
+      153,  139,  154,  148,  174,  174,  153,  179,  181,  182,
+      183,  185,  184,  139,  174,  186,  187,  150,  188,  189,
+      190,  191,  139,  151,  184,  148,  185,  192,  152,  153,
+      139,  154,  148,  194,  195,  153,  179,  181,  182,  183,
+      185,  184,  196,  174,  186,  187,  197,  188,  189,  190,
+      191,  198,  199,  184,  201,  185,  192,  202,  203,  204,
+      205,  206,  194,  195,  207,  208,  209,  210,  211,  212,
+      213,  196,  214,  215,  216,  197,  217,  219,  220,  221,
+      198,  199,  222,  201,  216,  223,  202,  203,  204,  205,
+      206,  224,  226,  207,  208,  209,  210,  211,  212,  213,
+
+      228,  214,  215,  216,  229,  217,  219,  220,  221,  230,
+      231,  222,  232,  216,  223,  233,  234,  235,  234,  236,
+      224,  226,  237,  238,  239,  240,  241,  242,  243,  228,
+      246,  247,  248,  229,  249,  250,  241,  251,  230,  231,
+      246,  232,  252,  254,  233,  234,  235,  234,  236,  255,
+      256,  237,  238,  239,  240,  241,  242,  243,  257,  246,
+      247,  248,  257,  249,  250,  253,  251,  253,  258,  246,
+      259,  252,  254,  260,  264,  265,  266,  267,  255,  256,
+      268,  269,  272,  273,  274,  276,  277,  257,  278,  279,
+      280,  257,  281,  282,  253,  285,  253,  258,  286,  259,
+
+      287,  288,  260,  264,  265,  266,  267,  289,  290,  268,
+      269,  272,  273,  274,  276,  277,  293,  278,  279,  280,
+      295,  281,  282,  297,  285,  298,  299,  286,  300,  287,
+      288,  306,  307,  308,  309,  310,  289,  290,  311,  313,
+      314,  315,  316,  317,  319,  293,  321,  322,  323,  295,
+      325,  326,  297,  327,  298,  299,  328,  300,  329,  330,
+      306,  307,  308,  309,  310,  331,  334,  311,  313,  314,
+      315,  316,  317,  319,  335,  321,  322,  323,  336,  325,
+      326,  337,  327,  338,  339,  328,  340,  329,  330,  342,
+      343,  349,  350,  351,  331,  334,  352,  353,  355,  352,
+
+      356,  357,  358,  335,  359,  360,  361,  336,  362,  363,
+      337,  364,  338,  339,  365,  340,  368,  369,  342,  343,
+      349,  350,  351,  371,  374,  352,  353,  355,  352,  356,
+      357,  358,  377,  359,  360,  361,  375,  362,  363,  375,
+      364,  382,  383,  365,  384,  368,  369,  385,  386,  388,
+      389,  391,  371,  374,  392,  393,  394,  395,  396,  398,
+      399,  377,  401,  402,  404,  375,  406,  407,  375,  408,
+      382,  383,  409,  384,  410,  411,  385,  386,  388,  389,
+      391,  412,  414,  392,  393,  394,  395,  396,  398,  399,
+      416,  401,  402,  404,  417,  406,  407,  418,  408,  420,
+
+      421,  409,  423,  410,  411,  424,  425,  428,  429,  431,
+      412,  414,  432,  433,  434,  435,  436,  438,  443,  416,
+      444,  445,  450,  417,  452,  453,  418,  454,  420,  421,
+      455,  423,  456,  460,  424,  425,  428,  429,  431,  461,
+      463,  432,  433,  434,  435,  436,  438,  443,  465,  444,
+      445,  450,  466,  452,  453,  467,  454,  469,  471,  455,
+      472,  456,  460,  473,  474,  475,  476,  477,  461,  463,
+      478,  479,  480,  481,  482,  483,  485,  465,  486,  488,
+      489,  466,  491,  492,  467,  493,  469,  471,  494,  472,
+      495,  497,  473,  474,  475,  476,  477,  498,  499,  478,
+
+      479,  480,  481,  482,  483,  485,  500,  486,  488,  489,
+      501,  491,  492,  502,  493,  505,  507,  494,  508,  495,
+      497,  510,  513,  514,  515,  520,  498,  499,  521,  522,
+      525,  527,  528,  529,  531,  500,    0,    0,    0,  501,
+        0,    0,  502,    0,  505,  507,    0,  508,    0,    0,
+      510,  513,  514,  515,  520,    0,    0,  521,  522,  525,
+      527,  528,  529,  531,  534,  534,  534,  534,  534,  534,
+      534,  534,  534,  534,  535,  535,  535,  535,  535,  535,
+      535,  535,  535,  535,  536,  536,  536,  536,  536,  536,
+      536,  536,  536,  536,  537,  537,  537,  537,  537,  537,
+
+      537,  537,  537,  537,  538,  538,  538,  538,  538,  538,
+      538,  538,  538,  538,  539,  539,  540,  540,  540,    0,
+      540,  541,  541,  541,  541,    0,  541,  542,  542,  542,
+        0,  542,  542,  542,  542,  542,  542,  543,  543,  543,
+        0,  543,  543,  543,  543,    0,  543,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  544,  545,  545,    0,
+      545,  545,  545,  545,  545,  545,  545,  546,    0,  546,
+      546,  546,  546,  546,  546,  546,  546,  547,  547,  548,
+      548,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+      533,  533,  533,  533,  533
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static const flex_int32_t yy_rule_can_match_eol[169] =
+static const flex_int32_t yy_rule_can_match_eol[152] =
     {   0,
 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1176,9 +1129,8 @@ static const flex_int32_t yy_rule_can_match_eol[169] =
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 
-    1, 1, 0, 0, 0, 1, 0, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
+    0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -1273,6 +1225,7 @@ class ParseSubqueryExpression;
 class ParseSubqueryTableReference;
 class ParseTableReference;
 class ParseTableReferenceSignature;
+class ParseTypeCast;
 class ParseWindow;
 class Type;
 class UnaryOperation;
@@ -1290,14 +1243,14 @@ class UnaryOperation;
     yycolumn += yyleng;                                   \
   }
 
-#line 1293 "SqlLexer_gen.cpp"
+#line 1246 "SqlLexer_gen.cpp"
 /* FIXME(chasseur, qzeng): Add support for hexadecimal literals. */
 /**
  * These patterns are based on the SQL-2011 standard for syntax of numeric
  * literals (Part 2, Section 5.3 of the standard).
  **/
 
-#line 1300 "SqlLexer_gen.cpp"
+#line 1253 "SqlLexer_gen.cpp"
 
 #define INITIAL 0
 #define CONDITION_SQL 1
@@ -1584,10 +1537,10 @@ YY_DECL
 		}
 
 	{
-#line 133 "../SqlLexer.lpp"
+#line 134 "../SqlLexer.lpp"
 
 
-#line 1590 "SqlLexer_gen.cpp"
+#line 1543 "SqlLexer_gen.cpp"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1614,13 +1567,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 594 )
+				if ( yy_current_state >= 534 )
 					yy_c = yy_meta[yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 593 );
+		while ( yy_current_state != 533 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1654,7 +1607,7 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 136 "../SqlLexer.lpp"
+#line 137 "../SqlLexer.lpp"
 {
     /* A forward slash character represents a system command. */
     BEGIN(CONDITION_COMMAND);
@@ -1666,7 +1619,7 @@ YY_RULE_SETUP
 case 2:
 /* rule 2 can match eol */
 YY_RULE_SETUP
-#line 144 "../SqlLexer.lpp"
+#line 145 "../SqlLexer.lpp"
 {
     /* This is a SQL command. Place the char back and process normally. */
     yyless(0);
@@ -1678,7 +1631,7 @@ YY_RULE_SETUP
 
 case 3:
 YY_RULE_SETUP
-#line 153 "../SqlLexer.lpp"
+#line 154 "../SqlLexer.lpp"
 {
     /* This is a command argument. */
     yylval->string_value_ = new quickstep::ParseString(
@@ -1688,7 +1641,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 160 "../SqlLexer.lpp"
+#line 161 "../SqlLexer.lpp"
 {
     /* Ignore whitespace. */
   }
@@ -1696,7 +1649,7 @@ YY_RULE_SETUP
 case 5:
 /* rule 5 can match eol */
 YY_RULE_SETUP
-#line 164 "../SqlLexer.lpp"
+#line 165 "../SqlLexer.lpp"
 {
     /* Newline reverts the lexer to the initial state. */
     yycolumn = 0;
@@ -1708,707 +1661,622 @@ YY_RULE_SETUP
 
 case 6:
 YY_RULE_SETUP
-#line 173 "../SqlLexer.lpp"
+#line 174 "../SqlLexer.lpp"
 return TOKEN_ADD;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 174 "../SqlLexer.lpp"
+#line 175 "../SqlLexer.lpp"
 return TOKEN_ALL;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 175 "../SqlLexer.lpp"
+#line 176 "../SqlLexer.lpp"
 return TOKEN_ALTER;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 176 "../SqlLexer.lpp"
+#line 177 "../SqlLexer.lpp"
 return TOKEN_AND;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 177 "../SqlLexer.lpp"
+#line 178 "../SqlLexer.lpp"
 return TOKEN_AS;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 178 "../SqlLexer.lpp"
+#line 179 "../SqlLexer.lpp"
 return TOKEN_ASC;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 179 "../SqlLexer.lpp"
+#line 180 "../SqlLexer.lpp"
 return TOKEN_ASC;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 180 "../SqlLexer.lpp"
+#line 181 "../SqlLexer.lpp"
 return TOKEN_BETWEEN;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 181 "../SqlLexer.lpp"
-return TOKEN_BIGINT;
-	YY_BREAK
-case 15:
-YY_RULE_SETUP
 #line 182 "../SqlLexer.lpp"
-return TOKEN_BIT;
-	YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 183 "../SqlLexer.lpp"
 return TOKEN_BITWEAVING;
 	YY_BREAK
-case 17:
+case 15:
 YY_RULE_SETUP
-#line 184 "../SqlLexer.lpp"
+#line 183 "../SqlLexer.lpp"
 return TOKEN_BLOCKPROPERTIES;
 	YY_BREAK
-case 18:
+case 16:
 YY_RULE_SETUP
-#line 185 "../SqlLexer.lpp"
+#line 184 "../SqlLexer.lpp"
 return TOKEN_BLOCKSAMPLE;
 	YY_BREAK
-case 19:
+case 17:
 YY_RULE_SETUP
-#line 186 "../SqlLexer.lpp"
+#line 185 "../SqlLexer.lpp"
 return TOKEN_BLOOM_FILTER;
 	YY_BREAK
-case 20:
+case 18:
 YY_RULE_SETUP
-#line 187 "../SqlLexer.lpp"
+#line 186 "../SqlLexer.lpp"
 return TOKEN_CASE;
 	YY_BREAK
-case 21:
+case 19:
 YY_RULE_SETUP
-#line 188 "../SqlLexer.lpp"
+#line 187 "../SqlLexer.lpp"
 return TOKEN_CAST;
 	YY_BREAK
-case 22:
+case 20:
 YY_RULE_SETUP
-#line 189 "../SqlLexer.lpp"
+#line 188 "../SqlLexer.lpp"
 return TOKEN_CSB_TREE;
 	YY_BREAK
-case 23:
+case 21:
 YY_RULE_SETUP
-#line 190 "../SqlLexer.lpp"
+#line 189 "../SqlLexer.lpp"
 return TOKEN_BY;
 	YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 191 "../SqlLexer.lpp"
-return TOKEN_CHARACTER;
-	YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 192 "../SqlLexer.lpp"
-return TOKEN_CHARACTER;
-	YY_BREAK
-case 26:
+case 22:
 YY_RULE_SETUP
-#line 193 "../SqlLexer.lpp"
+#line 190 "../SqlLexer.lpp"
 return TOKEN_CHECK;
 	YY_BREAK
-case 27:
+case 23:
 YY_RULE_SETUP
-#line 194 "../SqlLexer.lpp"
+#line 191 "../SqlLexer.lpp"
 return TOKEN_COLUMN;
 	YY_BREAK
-case 28:
+case 24:
 YY_RULE_SETUP
-#line 195 "../SqlLexer.lpp"
+#line 192 "../SqlLexer.lpp"
 return TOKEN_CONSTRAINT;
 	YY_BREAK
-case 29:
+case 25:
 YY_RULE_SETUP
-#line 196 "../SqlLexer.lpp"
+#line 193 "../SqlLexer.lpp"
 return TOKEN_COPY;
 	YY_BREAK
-case 30:
+case 26:
 YY_RULE_SETUP
-#line 197 "../SqlLexer.lpp"
+#line 194 "../SqlLexer.lpp"
 return TOKEN_CREATE;
 	YY_BREAK
-case 31:
+case 27:
 YY_RULE_SETUP
-#line 198 "../SqlLexer.lpp"
+#line 195 "../SqlLexer.lpp"
 return TOKEN_CURRENT;
 	YY_BREAK
-case 32:
-YY_RULE_SETUP
-#line 199 "../SqlLexer.lpp"
-return TOKEN_DATE;
-	YY_BREAK
-case 33:
-YY_RULE_SETUP
-#line 200 "../SqlLexer.lpp"
-return TOKEN_DATETIME;
-	YY_BREAK
-case 34:
+case 28:
 YY_RULE_SETUP
-#line 201 "../SqlLexer.lpp"
+#line 196 "../SqlLexer.lpp"
 return TOKEN_DAY;
 	YY_BREAK
-case 35:
-YY_RULE_SETUP
-#line 202 "../SqlLexer.lpp"
-return TOKEN_DECIMAL;
-	YY_BREAK
-case 36:
+case 29:
 YY_RULE_SETUP
-#line 203 "../SqlLexer.lpp"
+#line 197 "../SqlLexer.lpp"
 return TOKEN_DEFAULT;
 	YY_BREAK
-case 37:
+case 30:
 YY_RULE_SETUP
-#line 204 "../SqlLexer.lpp"
+#line 198 "../SqlLexer.lpp"
 return TOKEN_DELETE;
 	YY_BREAK
-case 38:
+case 31:
 YY_RULE_SETUP
-#line 205 "../SqlLexer.lpp"
+#line 199 "../SqlLexer.lpp"
 return TOKEN_DESC;
 	YY_BREAK
-case 39:
+case 32:
 YY_RULE_SETUP
-#line 206 "../SqlLexer.lpp"
+#line 200 "../SqlLexer.lpp"
 return TOKEN_DESC;
 	YY_BREAK
-case 40:
+case 33:
 YY_RULE_SETUP
-#line 207 "../SqlLexer.lpp"
+#line 201 "../SqlLexer.lpp"
 return TOKEN_DISTINCT;
 	YY_BREAK
-case 41:
-YY_RULE_SETUP
-#line 208 "../SqlLexer.lpp"
-return TOKEN_DOUBLE;
-	YY_BREAK
-case 42:
+case 34:
 YY_RULE_SETUP
-#line 209 "../SqlLexer.lpp"
+#line 202 "../SqlLexer.lpp"
 return TOKEN_DROP;
 	YY_BREAK
-case 43:
+case 35:
 YY_RULE_SETUP
-#line 210 "../SqlLexer.lpp"
+#line 203 "../SqlLexer.lpp"
 return TOKEN_ELSE;
 	YY_BREAK
-case 44:
+case 36:
 YY_RULE_SETUP
-#line 211 "../SqlLexer.lpp"
+#line 204 "../SqlLexer.lpp"
 return TOKEN_END;
 	YY_BREAK
-case 45:
+case 37:
 YY_RULE_SETUP
-#line 212 "../SqlLexer.lpp"
+#line 205 "../SqlLexer.lpp"
 return TOKEN_EXISTS;
 	YY_BREAK
-case 46:
+case 38:
 YY_RULE_SETUP
-#line 213 "../SqlLexer.lpp"
+#line 206 "../SqlLexer.lpp"
 return TOKEN_EXTRACT;
 	YY_BREAK
-case 47:
+case 39:
 YY_RULE_SETUP
-#line 214 "../SqlLexer.lpp"
+#line 207 "../SqlLexer.lpp"
 return TOKEN_FALSE;
 	YY_BREAK
-case 48:
+case 40:
 YY_RULE_SETUP
-#line 215 "../SqlLexer.lpp"
+#line 208 "../SqlLexer.lpp"
 return TOKEN_FIRST;
 	YY_BREAK
-case 49:
-YY_RULE_SETUP
-#line 216 "../SqlLexer.lpp"
-return TOKEN_FLOAT;
-	YY_BREAK
-case 50:
+case 41:
 YY_RULE_SETUP
-#line 217 "../SqlLexer.lpp"
+#line 209 "../SqlLexer.lpp"
 return TOKEN_FOLLOWING;
 	YY_BREAK
-case 51:
+case 42:
 YY_RULE_SETUP
-#line 218 "../SqlLexer.lpp"
+#line 210 "../SqlLexer.lpp"
 return TOKEN_FOR;
 	YY_BREAK
-case 52:
+case 43:
 YY_RULE_SETUP
-#line 219 "../SqlLexer.lpp"
+#line 211 "../SqlLexer.lpp"
 return TOKEN_FOREIGN;
 	YY_BREAK
-case 53:
+case 44:
 YY_RULE_SETUP
-#line 220 "../SqlLexer.lpp"
+#line 212 "../SqlLexer.lpp"
 return TOKEN_FROM;
 	YY_BREAK
-case 54:
+case 45:
 YY_RULE_SETUP
-#line 221 "../SqlLexer.lpp"
+#line 213 "../SqlLexer.lpp"
 return TOKEN_FULL;
 	YY_BREAK
-case 55:
+case 46:
 YY_RULE_SETUP
-#line 222 "../SqlLexer.lpp"
+#line 214 "../SqlLexer.lpp"
 return TOKEN_GROUP;
 	YY_BREAK
-case 56:
+case 47:
 YY_RULE_SETUP
-#line 223 "../SqlLexer.lpp"
+#line 215 "../SqlLexer.lpp"
 return TOKEN_HASH;
 	YY_BREAK
-case 57:
+case 48:
 YY_RULE_SETUP
-#line 224 "../SqlLexer.lpp"
+#line 216 "../SqlLexer.lpp"
 return TOKEN_HAVING;
 	YY_BREAK
-case 58:
+case 49:
 YY_RULE_SETUP
-#line 225 "../SqlLexer.lpp"
+#line 217 "../SqlLexer.lpp"
 return TOKEN_HOUR;
 	YY_BREAK
-case 59:
+case 50:
 YY_RULE_SETUP
-#line 226 "../SqlLexer.lpp"
+#line 218 "../SqlLexer.lpp"
 return TOKEN_IN;
 	YY_BREAK
-case 60:
+case 51:
 YY_RULE_SETUP
-#line 227 "../SqlLexer.lpp"
+#line 219 "../SqlLexer.lpp"
 return TOKEN_INDEX;
 	YY_BREAK
-case 61:
+case 52:
 YY_RULE_SETUP
-#line 228 "../SqlLexer.lpp"
+#line 220 "../SqlLexer.lpp"
 return TOKEN_INNER;
 	YY_BREAK
-case 62:
+case 53:
 YY_RULE_SETUP
-#line 229 "../SqlLexer.lpp"
+#line 221 "../SqlLexer.lpp"
 return TOKEN_INSERT;
 	YY_BREAK
-case 63:
-YY_RULE_SETUP
-#line 230 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
-	YY_BREAK
-case 64:
-YY_RULE_SETUP
-#line 231 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
-	YY_BREAK
-case 65:
+case 54:
 YY_RULE_SETUP
-#line 232 "../SqlLexer.lpp"
+#line 222 "../SqlLexer.lpp"
 return TOKEN_INTERSECT;
 	YY_BREAK
-case 66:
+case 55:
 YY_RULE_SETUP
-#line 233 "../SqlLexer.lpp"
+#line 223 "../SqlLexer.lpp"
 return TOKEN_INTERVAL;
 	YY_BREAK
-case 67:
+case 56:
 YY_RULE_SETUP
-#line 234 "../SqlLexer.lpp"
+#line 224 "../SqlLexer.lpp"
 return TOKEN_INTO;
 	YY_BREAK
-case 68:
+case 57:
 YY_RULE_SETUP
-#line 235 "../SqlLexer.lpp"
+#line 225 "../SqlLexer.lpp"
 return TOKEN_IS;
 	YY_BREAK
-case 69:
+case 58:
 YY_RULE_SETUP
-#line 236 "../SqlLexer.lpp"
+#line 226 "../SqlLexer.lpp"
 return TOKEN_JOIN;
 	YY_BREAK
-case 70:
+case 59:
 YY_RULE_SETUP
-#line 237 "../SqlLexer.lpp"
+#line 227 "../SqlLexer.lpp"
 return TOKEN_KEY;
 	YY_BREAK
-case 71:
+case 60:
 YY_RULE_SETUP
-#line 238 "../SqlLexer.lpp"
+#line 228 "../SqlLexer.lpp"
 return TOKEN_LAST;
 	YY_BREAK
-case 72:
+case 61:
 YY_RULE_SETUP
-#line 239 "../SqlLexer.lpp"
+#line 229 "../SqlLexer.lpp"
 return TOKEN_LEFT;
 	YY_BREAK
-case 73:
+case 62:
 YY_RULE_SETUP
-#line 240 "../SqlLexer.lpp"
+#line 230 "../SqlLexer.lpp"
 return TOKEN_LIKE;
 	YY_BREAK
-case 74:
+case 63:
 YY_RULE_SETUP
-#line 241 "../SqlLexer.lpp"
+#line 231 "../SqlLexer.lpp"
 return TOKEN_LIMIT;
 	YY_BREAK
-case 75:
-YY_RULE_SETUP
-#line 242 "../SqlLexer.lpp"
-return TOKEN_LONG;
-	YY_BREAK
-case 76:
+case 64:
 YY_RULE_SETUP
-#line 243 "../SqlLexer.lpp"
+#line 232 "../SqlLexer.lpp"
 return TOKEN_MINUTE;
 	YY_BREAK
-case 77:
+case 65:
 YY_RULE_SETUP
-#line 244 "../SqlLexer.lpp"
+#line 233 "../SqlLexer.lpp"
 return TOKEN_MONTH;
 	YY_BREAK
-case 78:
+case 66:
 YY_RULE_SETUP
-#line 245 "../SqlLexer.lpp"
+#line 234 "../SqlLexer.lpp"
 return TOKEN_NOT;
 	YY_BREAK
-case 79:
+case 67:
 YY_RULE_SETUP
-#line 246 "../SqlLexer.lpp"
+#line 235 "../SqlLexer.lpp"
 return TOKEN_NULL;
 	YY_BREAK
-case 80:
+case 68:
 YY_RULE_SETUP
-#line 247 "../SqlLexer.lpp"
+#line 236 "../SqlLexer.lpp"
 return TOKEN_NULLS;
 	YY_BREAK
-case 81:
+case 69:
 YY_RULE_SETUP
-#line 248 "../SqlLexer.lpp"
+#line 237 "../SqlLexer.lpp"
 return TOKEN_OFF;
 	YY_BREAK
-case 82:
+case 70:
 YY_RULE_SETUP
-#line 249 "../SqlLexer.lpp"
+#line 238 "../SqlLexer.lpp"
 return TOKEN_ON;
 	YY_BREAK
-case 83:
+case 71:
 YY_RULE_SETUP
-#line 250 "../SqlLexer.lpp"
+#line 239 "../SqlLexer.lpp"
 return TOKEN_OR;
 	YY_BREAK
-case 84:
+case 72:
 YY_RULE_SETUP
-#line 251 "../SqlLexer.lpp"
+#line 240 "../SqlLexer.lpp"
 return TOKEN_ORDER;
 	YY_BREAK
-case 85:
+case 73:
 YY_RULE_SETUP
-#line 252 "../SqlLexer.lpp"
+#line 241 "../SqlLexer.lpp"
 return TOKEN_OUTER;
 	YY_BREAK
-case 86:
+case 74:
 YY_RULE_SETUP
-#line 253 "../SqlLexer.lpp"
+#line 242 "../SqlLexer.lpp"
 return TOKEN_OVER;
 	YY_BREAK
-case 87:
+case 75:
 YY_RULE_SETUP
-#line 254 "../SqlLexer.lpp"
+#line 243 "../SqlLexer.lpp"
 return TOKEN_PARTITION;
 	YY_BREAK
-case 88:
+case 76:
 YY_RULE_SETUP
-#line 255 "../SqlLexer.lpp"
+#line 244 "../SqlLexer.lpp"
 return TOKEN_PARTITIONS;
 	YY_BREAK
-case 89:
+case 77:
 YY_RULE_SETUP
-#line 256 "../SqlLexer.lpp"
+#line 245 "../SqlLexer.lpp"
 return TOKEN_PERCENT;
 	YY_BREAK
-case 90:
+case 78:
 YY_RULE_SETUP
-#line 257 "../SqlLexer.lpp"
+#line 246 "../SqlLexer.lpp"
 return TOKEN_PRECEDING;
 	YY_BREAK
-case 91:
+case 79:
 YY_RULE_SETUP
-#line 258 "../SqlLexer.lpp"
+#line 247 "../SqlLexer.lpp"
 return TOKEN_PRIMARY;
 	YY_BREAK
-case 92:
+case 80:
 YY_RULE_SETUP
-#line 259 "../SqlLexer.lpp"
+#line 248 "../SqlLexer.lpp"
 return TOKEN_PRIORITY;
 	YY_BREAK
-case 93:
+case 81:
 YY_RULE_SETUP
-#line 260 "../SqlLexer.lpp"
+#line 249 "../SqlLexer.lpp"
 return TOKEN_QUIT;
 	YY_BREAK
-case 94:
+case 82:
 YY_RULE_SETUP
-#line 261 "../SqlLexer.lpp"
+#line 250 "../SqlLexer.lpp"
 return TOKEN_RANGE;
 	YY_BREAK
-case 95:
+case 83:
 YY_RULE_SETUP
-#line 262 "../SqlLexer.lpp"
+#line 251 "../SqlLexer.lpp"
 return TOKEN_REAL;
 	YY_BREAK
-case 96:
+case 84:
 YY_RULE_SETUP
-#line 263 "../SqlLexer.lpp"
+#line 252 "../SqlLexer.lpp"
 return TOKEN_REFERENCES;
 	YY_BREAK
-case 97:
+case 85:
 YY_RULE_SETUP
-#line 264 "../SqlLexer.lpp"
+#line 253 "../SqlLexer.lpp"
 return TOKEN_REGEXP;
 	YY_BREAK
-case 98:
+case 86:
 YY_RULE_SETUP
-#line 265 "../SqlLexer.lpp"
+#line 254 "../SqlLexer.lpp"
 return TOKEN_RIGHT;
 	YY_BREAK
-case 99:
+case 87:
 YY_RULE_SETUP
-#line 266 "../SqlLexer.lpp"
+#line 255 "../SqlLexer.lpp"
 return TOKEN_ROW;
 	YY_BREAK
-case 100:
+case 88:
 YY_RULE_SETUP
-#line 267 "../SqlLexer.lpp"
+#line 256 "../SqlLexer.lpp"
 return TOKEN_ROW_DELIMITER;
 	YY_BREAK
-case 101:
+case 89:
 YY_RULE_SETUP
-#line 268 "../SqlLexer.lpp"
+#line 257 "../SqlLexer.lpp"
 return TOKEN_ROWS;
 	YY_BREAK
-case 102:
+case 90:
 YY_RULE_SETUP
-#line 269 "../SqlLexer.lpp"
+#line 258 "../SqlLexer.lpp"
 return TOKEN_SECOND;
 	YY_BREAK
-case 103:
+case 91:
 YY_RULE_SETUP
-#line 270 "../SqlLexer.lpp"
+#line 259 "../SqlLexer.lpp"
 return TOKEN_SELECT;
 	YY_BREAK
-case 104:
+case 92:
 YY_RULE_SETUP
-#line 271 "../SqlLexer.lpp"
+#line 260 "../SqlLexer.lpp"
 return TOKEN_SET;
 	YY_BREAK
-case 105:
+case 93:
 YY_RULE_SETUP
-#line 272 "../SqlLexer.lpp"
+#line 261 "../SqlLexer.lpp"
 return TOKEN_SMA;
 	YY_BREAK
-case 106:
-YY_RULE_SETUP
-#line 273 "../SqlLexer.lpp"
-return TOKEN_SMALLINT;
-	YY_BREAK
-case 107:
+case 94:
 YY_RULE_SETUP
-#line 274 "../SqlLexer.lpp"
+#line 262 "../SqlLexer.lpp"
 return TOKEN_STDERR;
 	YY_BREAK
-case 108:
+case 95:
 YY_RULE_SETUP
-#line 275 "../SqlLexer.lpp"
+#line 263 "../SqlLexer.lpp"
 return TOKEN_STDOUT;
 	YY_BREAK
-case 109:
+case 96:
 YY_RULE_SETUP
-#line 276 "../SqlLexer.lpp"
+#line 264 "../SqlLexer.lpp"
 return TOKEN_SUBSTRING;
 	YY_BREAK
-case 110:
+case 97:
 YY_RULE_SETUP
-#line 277 "../SqlLexer.lpp"
+#line 265 "../SqlLexer.lpp"
 return TOKEN_TABLE;
 	YY_BREAK
-case 111:
+case 98:
 YY_RULE_SETUP
-#line 278 "../SqlLexer.lpp"
+#line 266 "../SqlLexer.lpp"
 return TOKEN_THEN;
 	YY_BREAK
-case 112:
-YY_RULE_SETUP
-#line 279 "../SqlLexer.lpp"
-return TOKEN_TIME;
-	YY_BREAK
-case 113:
-YY_RULE_SETUP
-#line 280 "../SqlLexer.lpp"
-return TOKEN_TIMESTAMP;
-	YY_BREAK
-case 114:
+case 99:
 YY_RULE_SETUP
-#line 281 "../SqlLexer.lpp"
+#line 267 "../SqlLexer.lpp"
 return TOKEN_TO;
 	YY_BREAK
-case 115:
+case 100:
 YY_RULE_SETUP
-#line 282 "../SqlLexer.lpp"
+#line 268 "../SqlLexer.lpp"
 return TOKEN_TRUE;
 	YY_BREAK
-case 116:
+case 101:
 YY_RULE_SETUP
-#line 283 "../SqlLexer.lpp"
+#line 269 "../SqlLexer.lpp"
 return TOKEN_TUPLESAMPLE;
 	YY_BREAK
-case 117:
+case 102:
 YY_RULE_SETUP
-#line 284 "../SqlLexer.lpp"
+#line 270 "../SqlLexer.lpp"
 return TOKEN_UNBOUNDED;
 	YY_BREAK
-case 118:
+case 103:
 YY_RULE_SETUP
-#line 285 "../SqlLexer.lpp"
+#line 271 "../SqlLexer.lpp"
 return TOKEN_UNION;
 	YY_BREAK
-case 119:
+case 104:
 YY_RULE_SETUP
-#line 286 "../SqlLexer.lpp"
+#line 272 "../SqlLexer.lpp"
 return TOKEN_UNIQUE;
 	YY_BREAK
-case 120:
+case 105:
 YY_RULE_SETUP
-#line 287 "../SqlLexer.lpp"
+#line 273 "../SqlLexer.lpp"
 return TOKEN_UPDATE;
 	YY_BREAK
-case 121:
+case 106:
 YY_RULE_SETUP
-#line 288 "../SqlLexer.lpp"
+#line 274 "../SqlLexer.lpp"
 return TOKEN_USING;
 	YY_BREAK
-case 122:
+case 107:
 YY_RULE_SETUP
-#line 289 "../SqlLexer.lpp"
+#line 275 "../SqlLexer.lpp"
 return TOKEN_VALUES;
 	YY_BREAK
-case 123:
-YY_RULE_SETUP
-#line 290 "../SqlLexer.lpp"
-return TOKEN_VARCHAR;
-	YY_BREAK
-case 124:
+case 108:
 YY_RULE_SETUP
-#line 291 "../SqlLexer.lpp"
+#line 276 "../SqlLexer.lpp"
 return TOKEN_WHEN;
 	YY_BREAK
-case 125:
+case 109:
 YY_RULE_SETUP
-#line 292 "../SqlLexer.lpp"
+#line 277 "../SqlLexer.lpp"
 return TOKEN_WHERE;
 	YY_BREAK
-case 126:
+case 110:
 YY_RULE_SETUP
-#line 293 "../SqlLexer.lpp"
+#line 278 "../SqlLexer.lpp"
 return TOKEN_WINDOW;
 	YY_BREAK
-case 127:
+case 111:
 YY_RULE_SETUP
-#line 294 "../SqlLexer.lpp"
+#line 279 "../SqlLexer.lpp"
 return TOKEN_WITH;
 	YY_BREAK
-case 128:
+case 112:
 YY_RULE_SETUP
-#line 295 "../SqlLexer.lpp"
+#line 280 "../SqlLexer.lpp"
 return TOKEN_YEAR;
 	YY_BREAK
-case 129:
-YY_RULE_SETUP
-#line 296 "../SqlLexer.lpp"
-return TOKEN_YEARMONTH;
-	YY_BREAK
-case 130:
+case 113:
 YY_RULE_SETUP
-#line 298 "../SqlLexer.lpp"
+#line 282 "../SqlLexer.lpp"
 return TOKEN_EQ;
 	YY_BREAK
-case 131:
+case 114:
 YY_RULE_SETUP
-#line 299 "../SqlLexer.lpp"
+#line 283 "../SqlLexer.lpp"
 return TOKEN_NEQ;
 	YY_BREAK
-case 132:
+case 115:
 YY_RULE_SETUP
-#line 300 "../SqlLexer.lpp"
+#line 284 "../SqlLexer.lpp"
 return TOKEN_NEQ;
 	YY_BREAK
-case 133:
+case 116:
 YY_RULE_SETUP
-#line 301 "../SqlLexer.lpp"
+#line 285 "../SqlLexer.lpp"
 return TOKEN_LT;
 	YY_BREAK
-case 134:
+case 117:
 YY_RULE_SETUP
-#line 302 "../SqlLexer.lpp"
+#line 286 "../SqlLexer.lpp"
 return TOKEN_GT;
 	YY_BREAK
-case 135:
+case 118:
 YY_RULE_SETUP
-#line 303 "../SqlLexer.lpp"
+#line 287 "../SqlLexer.lpp"
 return TOKEN_LEQ;
 	YY_BREAK
-case 136:
+case 119:
 YY_RULE_SETUP
-#line 304 "../SqlLexer.lpp"
+#line 288 "../SqlLexer.lpp"
 return TOKEN_GEQ;
 	YY_BREAK
-case 137:
+case 120:
 YY_RULE_SETUP
-#line 305 "../SqlLexer.lpp"
+#line 289 "../SqlLexer.lpp"
 return TOKEN_DOUBLECOLON;
 	YY_BREAK
-case 138:
+case 121:
 YY_RULE_SETUP
-#line 306 "../SqlLexer.lpp"
+#line 290 "../SqlLexer.lpp"
 return TOKEN_LBRACE;
 	YY_BREAK
-case 139:
+case 122:
 YY_RULE_SETUP
-#line 307 "../SqlLexer.lpp"
+#line 291 "../SqlLexer.lpp"
 return TOKEN_RBRACE;
 	YY_BREAK
-case 140:
+case 123:
 YY_RULE_SETUP
-#line 309 "../SqlLexer.lpp"
+#line 293 "../SqlLexer.lpp"
 return yytext[0];
 	YY_BREAK
-case 141:
+case 124:
 YY_RULE_SETUP
-#line 310 "../SqlLexer.lpp"
+#line 294 "../SqlLexer.lpp"
 return yytext[0];
 	YY_BREAK
 /**
     * Quoted strings. Prefacing a string with an 'e' or 'E' causes escape
     * sequences to be processed (as in PostgreSQL).
     **/
-case 142:
+case 125:
 YY_RULE_SETUP
-#line 316 "../SqlLexer.lpp"
+#line 300 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED_ESCAPED);
   }
 	YY_BREAK
-case 143:
+case 126:
 YY_RULE_SETUP
-#line 321 "../SqlLexer.lpp"
+#line 305 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED);
   }
 	YY_BREAK
-case 144:
+case 127:
 YY_RULE_SETUP
-#line 326 "../SqlLexer.lpp"
+#line 310 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_DOUBLE_QUOTED);
@@ -2420,7 +2288,7 @@ YY_RULE_SETUP
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED):
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED_ESCAPED):
 case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
-#line 335 "../SqlLexer.lpp"
+#line 319 "../SqlLexer.lpp"
 {
     delete yylval->string_value_;
     BEGIN(INITIAL);
@@ -2431,9 +2299,9 @@ case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
 
 /* Process escape sequences. */
 
-case 145:
+case 128:
 YY_RULE_SETUP
-#line 345 "../SqlLexer.lpp"
+#line 329 "../SqlLexer.lpp"
 {
     /* Octal code */
     unsigned int code;
@@ -2447,9 +2315,9 @@ YY_RULE_SETUP
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 146:
+case 129:
 YY_RULE_SETUP
-#line 357 "../SqlLexer.lpp"
+#line 341 "../SqlLexer.lpp"
 {
     /* Hexadecimal code */
     unsigned int code;
@@ -2457,9 +2325,9 @@ YY_RULE_SETUP
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 147:
+case 130:
 YY_RULE_SETUP
-#line 363 "../SqlLexer.lpp"
+#line 347 "../SqlLexer.lpp"
 {
     /* A numeric escape sequence that isn't correctly specified. */
     delete yylval->string_value_;
@@ -2468,58 +2336,58 @@ YY_RULE_SETUP
     return TOKEN_LEX_ERROR;
   }
 	YY_BREAK
-case 148:
+case 131:
 YY_RULE_SETUP
-#line 370 "../SqlLexer.lpp"
+#line 354 "../SqlLexer.lpp"
 {
     /* Backspace */
     yylval->string_value_->push_back('\b');
   }
 	YY_BREAK
-case 149:
+case 132:
 YY_RULE_SETUP
-#line 374 "../SqlLexer.lpp"
+#line 358 "../SqlLexer.lpp"
 {
     /* Form-feed */
     yylval->string_value_->push_back('\f');
   }
 	YY_BREAK
-case 150:
+case 133:
 YY_RULE_SETUP
-#line 378 "../SqlLexer.lpp"
+#line 362 "../SqlLexer.lpp"
 {
     /* Newline */
     yylval->string_value_->push_back('\n');
   }
 	YY_BREAK
-case 151:
+case 134:
 YY_RULE_SETUP
-#line 382 "../SqlLexer.lpp"
+#line 366 "../SqlLexer.lpp"
 {
     /* Carriage-return */
     yylval->string_value_->push_back('\r');
   }
 	YY_BREAK
-case 152:
+case 135:
 YY_RULE_SETUP
-#line 386 "../SqlLexer.lpp"
+#line 370 "../SqlLexer.lpp"
 {
     /* Horizontal Tab */
     yylval->string_value_->push_back('\t');
   }
 	YY_BREAK
-case 153:
-/* rule 153 can match eol */
+case 136:
+/* rule 136 can match eol */
 YY_RULE_SETUP
-#line 390 "../SqlLexer.lpp"
+#line 374 "../SqlLexer.lpp"
 {
     /* Any other character (including actual newline or carriage return) */
     yylval->string_value_->push_back(yytext[1]);
   }
 	YY_BREAK
-case 154:
+case 137:
 YY_RULE_SETUP
-#line 394 "../SqlLexer.lpp"
+#line 378 "../SqlLexer.lpp"
 {
     /* This should only be encountered right before an EOF. */
     delete yylval->string_value_;
@@ -2530,17 +2398,17 @@ YY_RULE_SETUP
 	YY_BREAK
 
 
-case 155:
+case 138:
 YY_RULE_SETUP
-#line 404 "../SqlLexer.lpp"
+#line 388 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('\'');
   }
 	YY_BREAK
-case 156:
+case 139:
 YY_RULE_SETUP
-#line 408 "../SqlLexer.lpp"
+#line 392 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2549,17 +2417,17 @@ YY_RULE_SETUP
 	YY_BREAK
 
 
-case 157:
+case 140:
 YY_RULE_SETUP
-#line 416 "../SqlLexer.lpp"
+#line 400 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('"');
   }
 	YY_BREAK
-case 158:
+case 141:
 YY_RULE_SETUP
-#line 420 "../SqlLexer.lpp"
+#line 404 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2567,94 +2435,94 @@ YY_RULE_SETUP
   }
 	YY_BREAK
 
-case 159:
-/* rule 159 can match eol */
+case 142:
+/* rule 142 can match eol */
 YY_RULE_SETUP
-#line 427 "../SqlLexer.lpp"
+#line 411 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 160:
-/* rule 160 can match eol */
+case 143:
+/* rule 143 can match eol */
 YY_RULE_SETUP
-#line 432 "../SqlLexer.lpp"
+#line 416 "../SqlLexer.lpp"
 {
   /* Scan up to a quote or escape sequence. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 161:
-/* rule 161 can match eol */
+case 144:
+/* rule 144 can match eol */
 YY_RULE_SETUP
-#line 437 "../SqlLexer.lpp"
+#line 421 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
 
-case 162:
+case 145:
 YY_RULE_SETUP
-#line 443 "../SqlLexer.lpp"
+#line 427 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(
         yylloc->first_line, yylloc->first_column, std::string(yytext, yyleng));
     return TOKEN_NAME;
   }
 	YY_BREAK
-case 163:
+case 146:
 YY_RULE_SETUP
-#line 449 "../SqlLexer.lpp"
+#line 433 "../SqlLexer.lpp"
 {
     yylval->numeric_literal_value_ = new quickstep::NumericParseLiteralValue(
         yylloc->first_line, yylloc->first_column, yytext);
     return TOKEN_UNSIGNED_NUMVAL;
   }
 	YY_BREAK
-case 164:
+case 147:
 YY_RULE_SETUP
-#line 455 "../SqlLexer.lpp"
+#line 439 "../SqlLexer.lpp"
 /* comment */
 	YY_BREAK
-case 165:
-/* rule 165 can match eol */
+case 148:
+/* rule 148 can match eol */
 YY_RULE_SETUP
-#line 457 "../SqlLexer.lpp"
+#line 441 "../SqlLexer.lpp"
 { yycolumn = 0; }
 	YY_BREAK
-case 166:
+case 149:
 YY_RULE_SETUP
-#line 459 "../SqlLexer.lpp"
+#line 443 "../SqlLexer.lpp"
 ; /* ignore white space */
 	YY_BREAK
 /* CONDITION_SQL */
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(CONDITION_COMMAND):
 case YY_STATE_EOF(CONDITION_SQL):
-#line 463 "../SqlLexer.lpp"
+#line 447 "../SqlLexer.lpp"
 {
   /* All conditions except for mutli-state string extracting conditions. */
   BEGIN(INITIAL);
   return TOKEN_EOF;
 }
 	YY_BREAK
-case 167:
+case 150:
 YY_RULE_SETUP
-#line 469 "../SqlLexer.lpp"
+#line 453 "../SqlLexer.lpp"
 {
   BEGIN(INITIAL);
   quickstep_yyerror(NULL, yyscanner, NULL, "illegal character");
   return TOKEN_LEX_ERROR;
 }
 	YY_BREAK
-case 168:
+case 151:
 YY_RULE_SETUP
-#line 475 "../SqlLexer.lpp"
+#line 459 "../SqlLexer.lpp"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 2657 "SqlLexer_gen.cpp"
+#line 2525 "SqlLexer_gen.cpp"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2952,7 +2820,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 594 )
+			if ( yy_current_state >= 534 )
 				yy_c = yy_meta[yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -2981,11 +2849,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 594 )
+		if ( yy_current_state >= 534 )
 			yy_c = yy_meta[yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-	yy_is_jam = (yy_current_state == 593);
+	yy_is_jam = (yy_current_state == 533);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -3815,6 +3683,6 @@ void yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 475 "../SqlLexer.lpp"
+#line 459 "../SqlLexer.lpp"
 
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/preprocessed/SqlLexer_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.hpp b/parser/preprocessed/SqlLexer_gen.hpp
index 6d3c441..ba92557 100644
--- a/parser/preprocessed/SqlLexer_gen.hpp
+++ b/parser/preprocessed/SqlLexer_gen.hpp
@@ -733,7 +733,7 @@ extern int yylex \
 #undef yyTABLES_NAME
 #endif
 
-#line 475 "../SqlLexer.lpp"
+#line 459 "../SqlLexer.lpp"
 
 
 #line 739 "SqlLexer_gen.hpp"


[07/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/SubstringOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/SubstringOperation.hpp b/types/operations/unary_operations/SubstringOperation.hpp
index 66f311f..afaf74d 100644
--- a/types/operations/unary_operations/SubstringOperation.hpp
+++ b/types/operations/unary_operations/SubstringOperation.hpp
@@ -22,22 +22,27 @@
 
 #include <algorithm>
 #include <cstddef>
+#include <cstdint>
 #include <cstdlib>
 #include <cstring>
+#include <limits>
 #include <memory>
-#include <unordered_map>
 #include <utility>
 #include <vector>
 
 #include "catalog/CatalogTypedefs.hpp"
+#include "storage/ValueAccessor.hpp"
+#include "storage/ValueAccessorUtil.hpp"
+#include "types/CharType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
-#include "types/operations/Operation.pb.h"
+#include "types/VarCharType.hpp"
+#include "types/containers/ColumnVector.hpp"
+#include "types/containers/ColumnVectorUtil.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
-#include "utility/HashPair.hpp"
+#include "types/port/strnlen.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
@@ -53,116 +58,81 @@ class ValueAccessor;
  */
 class SubstringOperation : public UnaryOperation {
  public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation for
-   *        the given (start_position, substring_length) pair.
-   **/
-  static const SubstringOperation& Instance(const std::size_t start_position,
-                                            const std::size_t substring_length) {
-    // TODO(jianqiao): This is a temporary solution that creates a new instance
-    // for each distinct pair of start_position and substring_length arguments.
-    // The number of instances may be unbounded if quickstep continuously accepts
-    // queries that call SUBSTRING with different arguments. It still remains to
-    // design a better long-term solution.
-    const auto hash = [](const auto &pair) {
-      return hash_combine_detail::HashCombiner<std::size_t>::CombineHashes(pair.first, pair.second);
-    };
-    static std::unordered_map<std::pair<std::size_t, std::size_t>,
-                              std::unique_ptr<const SubstringOperation>,
-                              decltype(hash)> instance_map(10, hash);
-
-    const std::pair<std::size_t, std::size_t> key_pair =
-        std::make_pair(start_position, substring_length);
-    auto imit = instance_map.find(key_pair);
-    if (imit != instance_map.end()) {
-      return *imit->second;
-    } else {
-      const SubstringOperation *instance =
-          new SubstringOperation(start_position, substring_length);
-      instance_map.emplace(key_pair,
-                           std::unique_ptr<const SubstringOperation>(instance));
-      return *instance;
-    }
-  }
-
-  serialization::UnaryOperation getProto() const override;
+  SubstringOperation() {}
 
-  bool canApplyToType(const Type &type) const override {
-    return (type.getSuperTypeID() == Type::kAsciiString);
+  std::string getName() const override {
+    return "Substring";
   }
 
-  const Type *resultTypeForArgumentType(const Type &type) const override {
-    if (type.getSuperTypeID() == Type::kAsciiString) {
-      // Result is a Char string.
-      return &TypeFactory::GetType(TypeID::kChar,
-                                   computeMaximumSubstringLength(type),
-                                   type.isNullable());
-    }
-    return nullptr;
+  std::string getShortName() const override {
+    return "Substring";
   }
 
-  const Type* fixedNullableResultType() const override {
-    // Result type is not fixed (i.e. can have various lengths).
-    return nullptr;
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    return {
+        OperationSignature::Create(getName(), {kChar}, {kLong, kLong}),
+        OperationSignature::Create(getName(), {kVarChar}, {kLong, kLong})
+    };
   }
 
-  bool resultTypeIsPlausible(const Type &result_type) const override {
-    // Result can be coerced to Char or VarChar.
-    return (result_type.getSuperTypeID() == Type::kAsciiString);
-  }
+  bool canApplyTo(const Type &type,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK(type.getTypeID() == kChar || type.getTypeID() == kVarChar);
+    DCHECK(!static_arguments.empty() && static_arguments[0].getTypeID() == kLong);
+    DCHECK(static_arguments.size() <= 2);
 
-  const Type* pushDownTypeHint(const Type *type_hint) const override {
-    // Input can only be a string, but we don't know the length.
-    return nullptr;
-  }
+    if (static_arguments[0].getLiteral<std::int64_t>() <= 0) {
+      *message = "The start position must be greater than 0";
+      return false;
+    }
 
-  TypedValue applyToChecked(const TypedValue &argument,
-                            const Type &argument_type) const override {
-    DCHECK(canApplyToType(argument_type));
+    if (static_arguments.size() == 2) {
+      DCHECK(static_arguments[1].getTypeID() == kLong);
+      if (static_arguments[1].getLiteral<std::int64_t>() <= 0) {
+        *message = "The substring length must be greater than 0";
+        return false;
+      }
+    }
 
-    const Type *result_type = resultTypeForArgumentType(argument_type);
-    DCHECK(result_type != nullptr);
+    return true;
+  }
 
-    if (argument_type.isNullable() && argument.isNull()) {
-      return result_type->makeNullValue();
-    } else {
-      const std::size_t result_length = computeMaximumSubstringLength(argument_type);
-      char *output_ptr = static_cast<char*>(std::malloc(result_length));
-      const char *input_ptr = static_cast<const char*>(argument.getOutOfLineData());
+  const Type* getResultType(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(UnaryOperation::canApplyTo(type, static_arguments));
 
-      const std::size_t string_length = argument.getAsciiStringLength();
-      if (start_position_ >= string_length) {
-        *output_ptr = '\0';
-      } else {
-        const std::size_t actual_substring_length =
-            std::min(string_length - start_position_, substring_length_);
-        std::memcpy(output_ptr, input_ptr + start_position_, actual_substring_length);
-        if (actual_substring_length < result_length) {
-          output_ptr[actual_substring_length] = '\0';
-        }
-      }
+    std::size_t start_position;
+    std::size_t substring_length;
+    ExtractStaticArguments(static_arguments, &start_position, &substring_length);
 
-      return TypedValue::CreateWithOwnedData(result_type->getTypeID(),
-                                             output_ptr,
-                                             result_length);
-    }
+    return &TypeFactory::GetType(TypeID::kChar,
+                                 ComputeMaximumSubstringLength(type, start_position, substring_length),
+                                 type.isNullable());
   }
 
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override;
+  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override;
 
  private:
-  /**
-   * @brief Constructor.
-   *
-   * @param input_type The data type of the input argument for substring.
-   * @param start_position The 0-base starting position of the substring.
-   * @param substring_length The substring length.
-   */
-  SubstringOperation(const std::size_t start_position,
-                     const std::size_t substring_length)
-      : UnaryOperation(UnaryOperationID::kSubstring),
-        start_position_(start_position),
-        substring_length_(substring_length) {
+  inline static void ExtractStaticArguments(
+      const std::vector<TypedValue> &static_arguments,
+      std::size_t *start_position,
+      std::size_t *substring_length) {
+    DCHECK_LE(1u, static_arguments.size());
+    DCHECK_GE(2u, static_arguments.size());
+
+    DCHECK(static_arguments[0].getTypeID() == kLong);
+    *start_position =
+        static_cast<std::size_t>(static_arguments[0].getLiteral<std::int64_t>() - 1);
+
+    DCHECK(static_arguments.size() < 2u || static_arguments[1].getTypeID() == kLong);
+    *substring_length =
+        static_arguments.size() < 2u
+            ? std::numeric_limits<std::size_t>::max()
+            : static_cast<std::size_t>(static_arguments[1].getLiteral<std::int64_t>());
   }
 
   /**
@@ -171,19 +141,23 @@ class SubstringOperation : public UnaryOperation {
    *
    * @param type The type of the input, must be either CharType or VarCharType.
    */
-  inline std::size_t computeMaximumSubstringLength(const Type& type) const {
-      DCHECK(type.getSuperTypeID() == Type::kAsciiString);
-
-      // Substring result should have length no greater than the minimum of
-      // (1) the input string length subtract the start position, and
-      // (2) the specified substring length.
-     return std::min(static_cast<const AsciiStringSuperType&>(type).getStringLength() - start_position_,
-                     substring_length_);
+  inline static std::size_t ComputeMaximumSubstringLength(
+      const Type& type,
+      const std::size_t start_position,
+      const std::size_t substring_length) {
+    DCHECK(type.getTypeID() == kChar || type.getTypeID() == kVarChar);
+
+    const std::size_t input_maximum_length =
+        type.getTypeID() == kChar
+            ? static_cast<const CharType&>(type).getStringLength()
+            : static_cast<const VarCharType&>(type).getStringLength();
+
+    // Substring result should have length no greater than the minimum of
+    // (1) the input string length subtract the start position, and
+    // (2) the specified substring length.
+    return std::min(input_maximum_length - start_position, substring_length);
   }
 
-  const std::size_t start_position_;
-  const std::size_t substring_length_;
-
  private:
   DISALLOW_COPY_AND_ASSIGN(SubstringOperation);
 };
@@ -203,8 +177,6 @@ class SubstringUncheckedOperator : public UncheckedUnaryOperator {
 
   TypedValue applyToTypedValue(const TypedValue& argument) const override;
 
-  TypedValue applyToDataPtr(const void *argument) const override;
-
   ColumnVector* applyToColumnVector(const ColumnVector &argument) const override;
 
 #ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
@@ -231,6 +203,100 @@ class SubstringUncheckedOperator : public UncheckedUnaryOperator {
   DISALLOW_COPY_AND_ASSIGN(SubstringUncheckedOperator);
 };
 
+template <bool null_terminated, bool input_nullable>
+inline void SubstringUncheckedOperator<null_terminated, input_nullable>
+    ::computeSubstring(const char *input,
+                       char *output) const {
+  std::size_t string_length =
+      (null_terminated ? strlen(input) : strnlen(input, maximum_input_length_));
+
+  if (start_position_ >= string_length) {
+    *output = '\0';
+    return;
+  }
+
+  const std::size_t actual_substring_length =
+      std::min(string_length - start_position_, substring_length_);
+  std::memcpy(output, input + start_position_, actual_substring_length);
+
+  if (actual_substring_length < substring_length_) {
+    output[actual_substring_length] = '\0';
+  }
+}
+
+template <bool null_terminated, bool input_nullable>
+TypedValue SubstringUncheckedOperator<null_terminated,
+                                      input_nullable>
+    ::applyToTypedValue(const TypedValue& argument) const {
+  if (input_nullable && argument.isNull()) {
+    return TypedValue(result_type_.getTypeID());
+  }
+
+  char *output_ptr = static_cast<char*>(std::malloc(substring_length_));
+  computeSubstring(static_cast<const char*>(argument.getOutOfLineData()),
+                   output_ptr);
+
+  return TypedValue::CreateWithOwnedData(result_type_.getTypeID(),
+                                         output_ptr,
+                                         substring_length_);
+}
+
+template <bool null_terminated, bool input_nullable>
+ColumnVector* SubstringUncheckedOperator<null_terminated,
+                                         input_nullable>
+    ::applyToColumnVector(const ColumnVector &argument) const {
+  return InvokeOnColumnVector(
+      argument,
+      [&](const auto &column_vector) -> ColumnVector* {  // NOLINT(build/c++11)
+    NativeColumnVector *result =
+        new NativeColumnVector(result_type_, column_vector.size());
+
+    for (std::size_t cv_pos = 0;
+         cv_pos < column_vector.size();
+         ++cv_pos) {
+      const char *input_ptr = static_cast<const char *>(
+          column_vector.template getUntypedValue<input_nullable>(cv_pos));
+
+      if (input_nullable && input_ptr == nullptr) {
+        result->appendNullValue();
+      } else {
+        this->computeSubstring(input_ptr,
+                               static_cast<char *>(result->getPtrForDirectWrite()));
+      }
+    }
+    return result;
+  });
+}
+
+#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
+template <bool null_terminated, bool input_nullable>
+ColumnVector* SubstringUncheckedOperator<null_terminated,
+                                         input_nullable>
+    ::applyToValueAccessor(ValueAccessor *accessor,
+                           const attribute_id argument_attr_id) const {
+  return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+      accessor,
+      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+    NativeColumnVector *result =
+        new NativeColumnVector(result_type_, accessor->getNumTuples());
+
+    accessor->beginIteration();
+    while (accessor->next()) {
+      const char *input_ptr = static_cast<const char *>(
+          accessor->template getUntypedValue<input_nullable>(argument_attr_id));
+
+      if (input_nullable && (input_ptr == nullptr)) {
+        result->appendNullValue();
+      } else {
+        this->computeSubstring(input_ptr,
+                               static_cast<char *>(result->getPtrForDirectWrite()));
+      }
+    }
+    return result;
+  });
+}
+#endif
+
 }  // namespace quickstep
 
 #endif /* QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_SUBSTRING_OPERATION_HPP_ */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/UnaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperation.cpp b/types/operations/unary_operations/UnaryOperation.cpp
index af150b3..09b27d9 100644
--- a/types/operations/unary_operations/UnaryOperation.cpp
+++ b/types/operations/unary_operations/UnaryOperation.cpp
@@ -20,28 +20,8 @@
 #include "types/operations/unary_operations/UnaryOperation.hpp"
 
 #include "types/operations/Operation.pb.h"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
 
-serialization::UnaryOperation UnaryOperation::getProto() const {
-  serialization::UnaryOperation proto;
-  switch (operation_id_) {
-    case UnaryOperationID::kNegate:
-      proto.set_operation_id(serialization::UnaryOperation::NEGATE);
-      break;
-    case UnaryOperationID::kCast:
-      FATAL_ERROR("Must use the overridden NumericCastOperation::getProto");
-    case UnaryOperationID::kDateExtract:
-      FATAL_ERROR("Must use the overridden DateExtractOperation::getProto");
-    case UnaryOperationID::kSubstring:
-      FATAL_ERROR("Must use the overridden SubstringOperation::getProto");
-    default:
-      FATAL_ERROR("Unrecognized UnaryOperationID in UnaryOperation::getProto");
-  }
-
-  return proto;
-}
-
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/UnaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperation.hpp b/types/operations/unary_operations/UnaryOperation.hpp
index 30a2961..70cb6f9 100644
--- a/types/operations/unary_operations/UnaryOperation.hpp
+++ b/types/operations/unary_operations/UnaryOperation.hpp
@@ -24,18 +24,10 @@
 #include <string>
 #include <type_traits>
 
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <utility>
-#include <vector>
-
-#include "storage/StorageBlockInfo.hpp"
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
 #include "catalog/CatalogTypedefs.hpp"
-#include "types/operations/Operation.hpp"
-#include "types/operations/Operation.pb.h"
 #include "types/TypedValue.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
+#include "types/operations/Operation.hpp"
+#include "types/operations/OperationSignature.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -48,6 +40,9 @@ class ValueAccessor;
  *  @{
  */
 
+class UnaryOperation;
+typedef std::shared_ptr<const UnaryOperation> UnaryOperationPtr;
+
 /**
  * @brief A unary operator which can be quickly applied to data items WITHOUT
  *        checking their type.
@@ -69,14 +64,6 @@ class UncheckedUnaryOperator {
   virtual TypedValue applyToTypedValue(const TypedValue &argument) const = 0;
 
   /**
-   * @brief Apply to a data item via a pointer without type-checking.
-   *
-   * @param argument The data item to apply to.
-   * @return The literal result of the operation.
-   **/
-  virtual TypedValue applyToDataPtr(const void *argument) const = 0;
-
-  /**
    * @brief Apply to a vector of values without type-checking.
    *
    * @param argument The argument ColumnVector to apply to.
@@ -96,27 +83,6 @@ class UncheckedUnaryOperator {
                                              const attribute_id argument_attr_id) const = 0;
 #endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
 
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  /**
-   * @brief Apply to an attribute of a list of joined tuples in a
-   *        ValueAccessor.
-   *
-   * @param accessor The ValueAccessor to apply to.
-   * @param use_left_relation If true, this UnaryOperation's argument is
-   *        assumed to be taken from the left relation in the pairs of
-   *        joined_tuple_ids. If false, the right relation.
-   * @param argument_attr_id The attribute ID of the argument in accessor.
-   * @param joined_tuple_ids A series of pairs of tuple ids from the left and
-   *        right relations in a join.
-   * @return A ColumnVector of literal results of the operation.
-   **/
-  virtual ColumnVector* applyToValueAccessorForJoin(
-      ValueAccessor *accessor,
-      const bool use_left_relation,
-      const attribute_id argument_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const = 0;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
  protected:
   UncheckedUnaryOperator() {
   }
@@ -134,30 +100,11 @@ class UncheckedUnaryOperator {
 class UnaryOperation : public Operation {
  public:
   /**
-   * @brief Generate a serialized Protocol Buffer representation of
-   *        this UnaryOperation.
-   *
-   * @return The serialized Protocol Buffer representation of this UnaryOperation.
-   **/
-  virtual serialization::UnaryOperation getProto() const;
-
-  /**
-   * @brief Determine the ID of this UnaryOperation.
-   *
-   * @return The ID of this UnaryOperation.
-   **/
-  inline UnaryOperationID getUnaryOperationID() const {
-    return operation_id_;
-  }
-
-  /**
    * @brief Get a human-readable name for this UnaryOperation.
    *
    * @return A human-readable name for this UnaryOperation.
    **/
-  virtual std::string getName() const {
-    return kUnaryOperationNames[static_cast<std::size_t>(operation_id_)];
-  }
+  virtual std::string getName() const = 0;
 
   /**
    * @brief Get a human-readable short name (e.g. "-") for this UnaryOperation.
@@ -165,113 +112,32 @@ class UnaryOperation : public Operation {
    * @return A human-readable short name for this BinaryOperation.
    **/
   virtual std::string getShortName() const {
-    return kUnaryOperationShortNames[static_cast<std::size_t>(operation_id_)];
+    return getName();
   }
 
-  /**
-   * @brief Determine whether this UnaryOperation can apply to the specified
-   *        Type.
-   *
-   * @param type The argument Type to check.
-   * @return Whether this UnaryOperation can apply to type.
-   **/
-  virtual bool canApplyToType(const Type &type) const = 0;
+  virtual bool canApplyTo(const Type &argument_type,
+                          const std::vector<TypedValue> &static_arguments,
+                          std::string *message) const = 0;
 
-  /**
-   * @brief Determine the Type of the result from applying this UnaryOperation
-   *        to an argument of the specified Type.
-   *
-   * @param type The argument Type to check.
-   * @return The Type of the result from applying this UnaryOperation to type
-   *         (NULL if not applicable).
-   **/
-  virtual const Type* resultTypeForArgumentType(const Type &type) const = 0;
-
-  /**
-   * @brief If this UnaryOperation always yields the same Type (or if the ONLY
-   *        difference between 2 possible return Types is nullability), return
-   *        that Type, otherwise return NULL.
-   *
-   * @return The nullable version of this UnaryOperation's fixed result Type,
-   *         if applicable.
-   **/
-  virtual const Type* fixedNullableResultType() const = 0;
+  virtual const Type* getResultType(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments) const = 0;
 
-  /**
-   * @brief Check if a particular Type might possibly be returned by this
-   *        UnaryOperation, assuming an appropriate argument type.
-   * @note A nullable result type may be considered plausible even if a
-   *       particular UnaryOperation never actually returns NULL values, so
-   *       long as the non-nullable version of the type would otherwise be
-   *       plausible.
-   *
-   * @param result_type Check whether this Type can possibly be returned by
-   *        this UnaryOperation.
-   * @return true if result_type can be returned by this UnaryOperation, false
-   *         otherwise.
-   **/
-  virtual bool resultTypeIsPlausible(const Type &result_type) const = 0;
+  virtual UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments) const = 0;
 
-  /**
-   * @brief Get a "hint" Type for the argument to this UnaryOperation based on
-   *        a hint for this UnaryOperation's result type. If possible, returns
-   *        a pointer to a Type that, when given to this UnaryOperation as an
-   *        argument, yields values of the desired type (i.e. calling
-   *        resultTypeForArgumentType() on the returned type should return the
-   *        original type_hint).
-   * @note In some cases (e.g. NumericCastOperation) there may be multiple
-   *       types that can be used as arguments to this UnaryOperation that will
-   *       all yield the desired type_hint. In such cases, this method will
-   *       pick one Type based on its own implementation-specific preference.
-   *
-   * @param type_hint A hint about what Type the result of this UnaryOperation
-   *        should have. May be NULL to indicate no preference.
-   * @return A type hint for the argument to this UnaryOperation based on
-   *         type_hint, or NULL if no suitable Type exists.
-   **/
-  virtual const Type* pushDownTypeHint(const Type *type_hint) const = 0;
-
-  /**
-   * @brief Apply this UnaryOperation to a TypedValue.
-   * @warning It is an error to call this method if this UnaryOperation can not
-   *          be applied to argument_type. If in doubt, check canApplyToType()
-   *          first.
-   *
-   * @param argument The TypedValue to apply to.
-   * @param argument_type The Type that argument belongs to.
-   * @return The literal result of the operation.
-   **/
-  virtual TypedValue applyToChecked(const TypedValue &argument,
-                                    const Type &argument_type) const = 0;
-
-  /**
-   * @brief Create an UncheckedUnaryOperator which can apply to items of the
-   *        specified type.
-   * @warning The resulting UncheckedUnaryOperator performs no type-checking
-   *          whatsoever. Nonetheless, it is useful in situations where many
-   *          data items of the same, known type are to be operated on (for
-   *          example, over many tuples in the same relation).
-   *
-   * @param type The Type of argument to apply to.
-   * @return An UncheckedUnaryOperator which applies this UnaryOperation to
-   *         the specified Type.
-   * @exception OperationInapplicableToType This UnaryOperation is not
-   *            applicable to type.
-   **/
-  virtual UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const = 0;
+  bool canApplyTo(const Type &argument_type,
+                  const std::vector<TypedValue> &static_arguments) const {
+    std::string message;
+    return canApplyTo(argument_type, static_arguments, &message);
+  }
 
  protected:
-  explicit UnaryOperation(const UnaryOperationID operation_id)
-      : Operation(Operation::kUnaryOperation,
-                  kUnaryOperationNames[
-                      static_cast<typename std::underlying_type<UnaryOperationID>::type>(operation_id)],
-                  kUnaryOperationShortNames[
-                      static_cast<typename std::underlying_type<UnaryOperationID>::type>(operation_id)]),
-        operation_id_(operation_id) {
+  UnaryOperation()
+      : Operation(Operation::kUnaryOperation) {
   }
 
-  const UnaryOperationID operation_id_;
-
  private:
   DISALLOW_COPY_AND_ASSIGN(UnaryOperation);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/UnaryOperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationFactory.cpp b/types/operations/unary_operations/UnaryOperationFactory.cpp
deleted file mode 100644
index b306061..0000000
--- a/types/operations/unary_operations/UnaryOperationFactory.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/unary_operations/UnaryOperationFactory.hpp"
-
-#include <string>
-
-#include "types/TypeFactory.hpp"
-#include "types/operations/Operation.pb.h"
-#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp"
-#include "types/operations/unary_operations/NumericCastOperation.hpp"
-#include "types/operations/unary_operations/DateExtractOperation.hpp"
-#include "types/operations/unary_operations/SubstringOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-const UnaryOperation& UnaryOperationFactory::GetUnaryOperation(const UnaryOperationID id) {
-  switch (id) {
-    case UnaryOperationID::kNegate:
-      return NegateUnaryOperation::Instance();
-    case UnaryOperationID::kCast:
-      FATAL_ERROR("Getting a CastOperation through GetUnaryOperation is not supported");
-    case UnaryOperationID::kDateExtract:
-      FATAL_ERROR("Getting a DateExtractOperation through GetUnaryOperation is not supported");
-    case UnaryOperationID::kSubstring:
-      FATAL_ERROR("Getting a SubstringOperation through GetUnaryOperation is not supported");
-    default:
-      FATAL_ERROR("Unknown UnaryOperationID");
-  }
-}
-
-bool UnaryOperationFactory::ProtoIsValid(const serialization::UnaryOperation &proto) {
-  // Check that UnaryOperation is fully initialized.
-  if (!proto.IsInitialized()) {
-    return false;
-  }
-
-  // Check that the operation_id is a valid UnaryOperation.
-  if (!proto.UnaryOperationID_IsValid(proto.operation_id())) {
-    return false;
-  }
-
-  switch (proto.operation_id()) {
-    case serialization::UnaryOperation::NEGATE:
-      return true;
-    case serialization::UnaryOperation::CAST:
-      return proto.HasExtension(serialization::CastOperation::target_type)
-          && TypeFactory::ProtoIsValid(proto.GetExtension(serialization::CastOperation::target_type));
-    case serialization::UnaryOperation::DATE_EXTRACT:
-      return proto.HasExtension(serialization::DateExtractOperation::unit)
-          && DateExtractOperation_Unit_IsValid(proto.GetExtension(serialization::DateExtractOperation::unit));
-    case serialization::UnaryOperation::SUBSTRING:
-      return proto.HasExtension(serialization::SubstringOperation::start_position)
-          && proto.HasExtension(serialization::SubstringOperation::substring_length);
-    default:
-      return false;
-  }
-}
-
-const UnaryOperation& UnaryOperationFactory::ReconstructFromProto(
-    const serialization::UnaryOperation &proto) {
-  DCHECK(ProtoIsValid(proto))
-      << "Attempted to create UnaryOperation from an invalid proto description:\n"
-      << proto.DebugString();
-
-  switch (proto.operation_id()) {
-    case serialization::UnaryOperation::NEGATE:
-      return GetUnaryOperation(UnaryOperationID::kNegate);
-    case serialization::UnaryOperation::CAST:
-      return NumericCastOperation::Instance(
-          TypeFactory::ReconstructFromProto(
-              proto.GetExtension(
-                  serialization::CastOperation::target_type)));
-    case serialization::UnaryOperation::DATE_EXTRACT:
-      switch (proto.GetExtension(serialization::DateExtractOperation::unit)) {
-        case serialization::DateExtractOperation::YEAR:
-          return DateExtractOperation::Instance(DateExtractUnit::kYear);
-        case serialization::DateExtractOperation::MONTH:
-          return DateExtractOperation::Instance(DateExtractUnit::kMonth);
-        case serialization::DateExtractOperation::DAY:
-          return DateExtractOperation::Instance(DateExtractUnit::kDay);
-        case serialization::DateExtractOperation::HOUR:
-          return DateExtractOperation::Instance(DateExtractUnit::kHour);
-        case serialization::DateExtractOperation::MINUTE:
-          return DateExtractOperation::Instance(DateExtractUnit::kMinute);
-        case serialization::DateExtractOperation::SECOND:
-          return DateExtractOperation::Instance(DateExtractUnit::kSecond);
-        default:
-          FATAL_ERROR("Unrecognized DateExtractOperation unit in UnaryOperation::ReconstructFromProto");
-      }
-    case serialization::UnaryOperation::SUBSTRING:
-      return SubstringOperation::Instance(
-          proto.GetExtension(serialization::SubstringOperation::start_position),
-          proto.GetExtension(serialization::SubstringOperation::substring_length));
-    default:
-      FATAL_ERROR("Unrecognized UnaryOperationID in UnaryOperation::ReconstructFromProto");
-  }
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/UnaryOperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationFactory.hpp b/types/operations/unary_operations/UnaryOperationFactory.hpp
deleted file mode 100644
index 2ce83d4..0000000
--- a/types/operations/unary_operations/UnaryOperationFactory.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_FACTORY_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_FACTORY_HPP_
-
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class UnaryOperation;
-namespace serialization { class UnaryOperation; }
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief All-static factory object that provides access to UnaryOperations.
- **/
-class UnaryOperationFactory {
- public:
-  /**
-   * @brief Convenience factory method to get a pointer to a UnaryOperation
-   *        from that UnaryOperation's ID.
-   *
-   * @param id The ID of the desired UnaryOperation.
-   * @return The UnaryOperation corresponding to id.
-   **/
-  static const UnaryOperation& GetUnaryOperation(const UnaryOperationID id);
-
-  /**
-   * @brief Get a reference to a UnaryOperation from that UnaryOperation's
-   *        serialized Protocol Buffer representation.
-   *
-   * @param proto A serialized Protocol Buffer representation of a UnaryOperation,
-   *        originally generated by getProto().
-   * @return The UnaryOperation described by proto.
-   **/
-  static const UnaryOperation& ReconstructFromProto(const serialization::UnaryOperation &proto);
-
-  /**
-   * @brief Check whether a serialization::UnaryOperation is fully-formed and
-   *        all parts are valid.
-   *
-   * @param proto A serialized Protocol Buffer representation of a UnaryOperation,
-   *        originally generated by getProto().
-   * @return Whether proto is fully-formed and valid.
-   **/
-  static bool ProtoIsValid(const serialization::UnaryOperation &proto);
-
- private:
-  UnaryOperationFactory();
-
-  DISALLOW_COPY_AND_ASSIGN(UnaryOperationFactory);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_FACTORY_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/UnaryOperationID.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationID.cpp b/types/operations/unary_operations/UnaryOperationID.cpp
deleted file mode 100644
index b47a848..0000000
--- a/types/operations/unary_operations/UnaryOperationID.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
-
-namespace quickstep {
-
-const char *kUnaryOperationNames[] = {
-  "Negate", "Cast", "DateExtract", "Substring"
-};
-
-const char *kUnaryOperationShortNames[] = {
-  "-", "Cast", "DateExtract", "Substring"
-};
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/UnaryOperationID.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationID.hpp b/types/operations/unary_operations/UnaryOperationID.hpp
deleted file mode 100644
index fa50f50..0000000
--- a/types/operations/unary_operations/UnaryOperationID.hpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_ID_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_ID_HPP_
-
-#include <type_traits>
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief Concrete UnaryOperations.
- **/
-enum class UnaryOperationID {
-  kNegate = 0,
-  kCast,
-  kDateExtract,
-  kSubstring,
-  kNumUnaryOperationIDs  // Not a real UnaryOperationID, exists for counting purposes.
-};
-
-/**
- * @brief Names of comparisons in the same order as UnaryOperationID.
- * @note Defined out-of-line in UnaryOperation.cpp
- **/
-extern const char *kUnaryOperationNames[
-    static_cast<typename std::underlying_type<UnaryOperationID>::type>(
-        UnaryOperationID::kNumUnaryOperationIDs)];
-
-/**
- * @brief Short names (i.e. mathematical symbols) of comparisons in the same
- *        order as UnaryOperationID.
- * @note Defined out-of-line in UnaryOperation.cpp
- **/
-extern const char *kUnaryOperationShortNames[
-    static_cast<typename std::underlying_type<UnaryOperationID>::type>(
-        UnaryOperationID::kNumUnaryOperationIDs)];
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_ID_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/UnaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp
new file mode 100644
index 0000000..59b2cf0
--- /dev/null
+++ b/types/operations/unary_operations/UnaryOperationWrapper.hpp
@@ -0,0 +1,250 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_
+
+#include <cstddef>
+#include <string>
+#include <type_traits>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "storage/ValueAccessor.hpp"
+#include "storage/ValueAccessorUtil.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT, typename ResultT>
+struct UnaryFunctor {
+  typedef ArgumentT ArgumentType;
+  typedef ResultT ResultType;
+
+  static constexpr Operation
+      ::OperationSuperTypeID kOperationSuperTypeID = Operation::kUnaryOperation;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+class UncheckedUnaryOperatorWrapperCodegen : public UncheckedUnaryOperator {
+ public:
+  template <typename ...ConstructorArgs>
+  UncheckedUnaryOperatorWrapperCodegen(const Type &argument_type,
+                                       const Type &result_type,
+                                       ConstructorArgs &&...args)
+      : functor_(std::forward<ConstructorArgs>(args)...),
+        impl_(functor_, argument_type, result_type) {}
+
+  TypedValue applyToTypedValue(const TypedValue &argument) const override {
+    return impl_.applyToTypedValue(argument);
+  }
+
+  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
+    using ArgumentCVT = typename ArgumentGen::ColumnVectorType;
+    DCHECK_EQ(argument.isNative(), ArgumentCVT::kNative);
+
+    using ArgumentAccessorT = ColumnVectorValueAccessor<ArgumentCVT>;
+    ArgumentAccessorT accessor(static_cast<const ArgumentCVT&>(argument));
+    return impl_.applyToValueAccessor(&accessor, 0);
+  }
+
+  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
+                                     const attribute_id attr_id) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToValueAccessor(accessor, attr_id);
+    });
+  }
+
+ private:
+  using ArgumentType = typename FunctorT::ArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
+  using ArgumentGen = Codegen<FuncSpec, ArgumentType>;
+  using ResultGen = Codegen<FuncSpec, ResultType>;
+
+  template <bool argument_nullable>
+  struct Implementation;
+
+  const FunctorT functor_;
+  const Implementation<true> impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(UncheckedUnaryOperatorWrapperCodegen);
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool argument_nullable>
+struct UncheckedUnaryOperatorWrapperCodegen<FunctorT, SpecArgs...>
+    ::Implementation {
+  Implementation(const FunctorT &functor_in,
+                 const Type &argument_type_in,
+                 const Type &result_type_in)
+      : functor(functor_in),
+        argument_type(argument_type_in),
+        result_type(result_type_in) {}
+
+  inline TypedValue applyToTypedValue(const TypedValue &argument) const {
+    if (argument_nullable && argument.isNull()) {
+      return TypedValue(ResultType::kStaticTypeID);
+    }
+
+    return ResultGen::template ApplyUnaryTypedValue<ArgumentGen>(
+        ArgumentGen::ToNativeValueConst(argument),
+        result_type,
+        functor);
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToValueAccessor(AccessorT *accessor,
+                                            const attribute_id attr_id) const {
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename ArgumentGen::NativeTypeConstPtr arg_value =
+          ArgumentGen::template GetValuePtr<
+              argument_nullable, AccessorT>(accessor, attr_id);
+
+      if (argument_nullable && ArgumentGen::IsNull(arg_value)) {
+        result_cv->appendNullValue();
+      } else {
+        ResultGen::template ApplyUnaryColumnVector<ArgumentGen>(
+            ArgumentGen::Dereference(arg_value), functor, result_cv);
+      }
+    }
+    return result_cv;
+  }
+
+  const FunctorT &functor;
+  const Type &argument_type;
+  const Type &result_type;
+};
+
+template <typename FunctorT>
+class UnaryOperationWrapper : public UnaryOperation {
+ public:
+  UnaryOperationWrapper()
+      : UnaryOperation(),
+        operation_name_(FunctorT::GetName()) {}
+
+  std::string getName() const override {
+    return operation_name_;
+  }
+
+  std::string getShortName() const override {
+    return getName();
+  }
+
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    return {
+        OperationSignature::Create(getName(), {ArgumentType::kStaticTypeID}, 0)
+    };
+  }
+
+  bool canApplyTo(const Type &argument_type,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return true;
+  }
+
+  const Type* getResultType(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return getResultTypeImpl<ResultType::kParameterized>(
+        argument_type, static_arguments);
+  }
+
+  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return makeUncheckedUnaryOperatorImpl<
+        std::is_default_constructible<FunctorT>::value>(
+            argument_type, static_arguments);
+  }
+
+ private:
+  using ArgumentType = typename FunctorT::ArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<functor_use_default_constructor>* = 0) const {
+    return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>(
+        argument_type, *getResultType(argument_type, static_arguments));
+  }
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedUnaryOperator* makeUncheckedUnaryOperatorImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!functor_use_default_constructor>* = 0) const {
+    return new UncheckedUnaryOperatorWrapperCodegen<FunctorT>(
+        argument_type, *getResultType(argument_type, static_arguments),
+        static_cast<const ArgumentType&>(argument_type));
+  }
+
+  template <bool result_type_has_parameter>
+  inline const Type* getResultTypeImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!result_type_has_parameter>* = 0) const {
+    return &TypeFactory::GetType(ResultType::kStaticTypeID,
+                                 argument_type.isNullable());
+  }
+
+  template <bool result_type_has_parameter>
+  inline const Type* getResultTypeImpl(
+      const Type &argument_type,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<result_type_has_parameter>* = 0) const {
+    return FunctorT::GetResultType(argument_type);
+  }
+
+  const std::string operation_name_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnaryOperationWrapper);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt
index c5c9dd8..9093910 100644
--- a/utility/CMakeLists.txt
+++ b/utility/CMakeLists.txt
@@ -159,6 +159,7 @@ QS_PROTOBUF_GENERATE_CPP(quickstep_utility_SortConfiguration_proto_srcs
                          SortConfiguration.proto)
 
 add_subdirectory(lip_filter)
+add_subdirectory(meta)
 
 # Declare micro-libs:
 add_library(quickstep_utility_Alignment ../empty_src.cpp Alignment.hpp)
@@ -204,7 +205,6 @@ add_library(quickstep_utility_SortConfiguration_proto
             ${quickstep_utility_SortConfiguration_proto_hdrs})
 add_library(quickstep_utility_SqlError SqlError.cpp SqlError.hpp)
 add_library(quickstep_utility_StringUtil StringUtil.cpp StringUtil.hpp)
-add_library(quickstep_utility_TemplateUtil ../empty_src.cpp TemplateUtil.hpp)
 # Note that TextBasedTest.{hpp, cpp} are not in this static library.
 # Any tests that use them need to include them in the
 # executable.
@@ -336,7 +336,6 @@ target_link_libraries(quickstep_utility_ShardedLockManager
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_utility_StringUtil
                       glog)
-target_link_libraries(quickstep_utility_TemplateUtil)
 target_link_libraries(quickstep_utility_TextBasedTestDriver
                       glog
                       gtest
@@ -388,7 +387,6 @@ target_link_libraries(quickstep_utility
                       quickstep_utility_SortConfiguration_proto
                       quickstep_utility_SqlError
                       quickstep_utility_StringUtil
-                      quickstep_utility_TemplateUtil
                       quickstep_utility_TextBasedTestDriver
                       quickstep_utility_ThreadSafeQueue
                       quickstep_utility_TreeStringSerializable
@@ -509,14 +507,6 @@ target_link_libraries(TreeStringSerializable_unittest
                       quickstep_utility_TreeStringSerializable)
 add_test(TreeStringSerializable_unittest TreeStringSerializable_unittest)
 
-add_executable(TemplateUtil_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/TemplateUtil_unittest.cpp")
-target_link_libraries(TemplateUtil_unittest
-                      gtest
-                      gtest_main
-                      quickstep_utility_Macros
-                      quickstep_utility_TemplateUtil)
-add_test(TemplateUtil_unittest TemplateUtil_unittest)
-
 # Benchmarks:
 if (UNIX)
   add_executable(EqualsAnyConstant_benchmark

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/StringUtil.cpp
----------------------------------------------------------------------
diff --git a/utility/StringUtil.cpp b/utility/StringUtil.cpp
index 2745457..9fca695 100644
--- a/utility/StringUtil.cpp
+++ b/utility/StringUtil.cpp
@@ -52,6 +52,12 @@ std::string ToLower(const std::string& str) {
   return lower_str;
 }
 
+std::string ToUpper(const std::string& str) {
+  std::string upper_str(str.size(), ' ');
+  std::transform(str.begin(), str.end(), upper_str.begin(), toupper);
+  return upper_str;
+}
+
 std::string EscapeSpecialChars(const std::string& text) {
   std::string new_text;
   for (const char& c : text) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/StringUtil.hpp
----------------------------------------------------------------------
diff --git a/utility/StringUtil.hpp b/utility/StringUtil.hpp
index abda8f3..e928225 100644
--- a/utility/StringUtil.hpp
+++ b/utility/StringUtil.hpp
@@ -35,11 +35,21 @@ namespace quickstep {
  * @brief Convert a string \p str to lower case.
  *
  * @param str The string to be converted.
- * @return The converted string with all lower case characters bing converted to upper case characters.
+ * @return The converted string with all lower case characters being converted
+ *         to upper case characters.
  */
 extern std::string ToLower(const std::string &str);
 
 /**
+ * @brief Convert a string \p str to upper case.
+ *
+ * @param str The string to be converted.
+ * @return The converted string with all upper case characters being converted
+ *         to lower case characters.
+ */
+extern std::string ToUpper(const std::string &str);
+
+/**
  * @brief Converts special characters to escape characters.
  *
  * @param text The string to be unescaped.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/TemplateUtil.hpp
----------------------------------------------------------------------
diff --git a/utility/TemplateUtil.hpp b/utility/TemplateUtil.hpp
index dfae8e4..587336d 100644
--- a/utility/TemplateUtil.hpp
+++ b/utility/TemplateUtil.hpp
@@ -30,204 +30,6 @@ namespace quickstep {
  *  @{
  */
 
-namespace template_util_inner {
-
-/**
- * @brief Represents a compile-time sequence of integers.
- *
- * Sequence is defined here for C++11 compatibility. For C++14 and above,
- * std::integer_sequence can be used to achieve the same functionality.
- *
- * TODO(jianqiao): directly use std::integer_sequence if having C++14 support.
- */
-template<std::size_t ...>
-struct Sequence {};
-
-/**
- * @brief The helper class for creating Sequence. MakeSequence<N>::type is
- *        equivalent to Sequence<1,2,...,N>.
- *
- * MakeSequence is defined here for C++11 compatibility. For C++14 and above,
- * std::make_index_sequence can be used to achieve the same functionality.
- *
- * TODO(jianqiao): directly use std::make_index_sequence if having C++14 support.
- */
-template<std::size_t N, std::size_t ...S>
-struct MakeSequence : MakeSequence<N-1, N-1, S...> {};
-
-template<std::size_t ...S>
-struct MakeSequence<0, S...> {
-  typedef Sequence<S...> type;
-};
-
-/**
- * @brief Final step of CreateBoolInstantiatedInstance. Now all bool_values are
- *        ready. Instantiate the template and create (i.e. new) an instance.
- */
-template <template <bool ...> class T, class ReturnT,
-          bool ...bool_values, std::size_t ...i,
-          typename Tuple>
-inline ReturnT* CreateBoolInstantiatedInstanceInner(Tuple &&args,
-                                                    Sequence<i...> &&indices) {
-  return new T<bool_values...>(std::get<i>(std::forward<Tuple>(args))...);
-}
-
-/**
- * @brief Invoke the functor with the compile-time bool values wrapped as
- *        integral_constant types.
- */
-template <typename FunctorT, bool ...bool_values>
-inline auto InvokeOnBoolsInner(const FunctorT &functor) {
-  return functor(std::integral_constant<bool, bool_values>()...);
-}
-
-/**
- * @brief Recursive dispatching.
- */
-template <typename FunctorT, bool ...bool_values, typename ...Bools>
-inline auto InvokeOnBoolsInner(const FunctorT &functor,
-                               const bool tparam,
-                               const Bools ...rest_params) {
-  if (tparam) {
-    return InvokeOnBoolsInner<FunctorT, bool_values..., true>(
-        functor, rest_params...);
-  } else {
-    return InvokeOnBoolsInner<FunctorT, bool_values..., false>(
-        functor, rest_params...);
-  }
-}
-
-/**
- * @brief Move the functor to the first position in argument list.
- */
-template <std::size_t last, std::size_t ...i, typename TupleT>
-inline auto InvokeOnBoolsInner(TupleT &&args, Sequence<i...> &&indices) {
-  return InvokeOnBoolsInner(std::get<last>(std::forward<TupleT>(args)),
-                            std::get<i>(std::forward<TupleT>(args))...);
-}
-
-}  // namespace template_util_inner
-
-/**
- * @brief Edge case of the recursive CreateBoolInstantiatedInstance function
- *        when all bool variables have been branched and replaced with compile-time
- *        bool constants.
- */
-template <template <bool ...> class T, class ReturnT,
-          bool ...bool_values,
-          typename Tuple>
-inline ReturnT* CreateBoolInstantiatedInstance(Tuple &&args) {
-  // Note that the constructor arguments have been forwarded as a tuple (args).
-  // Here we generate a compile-time index sequence (i.e. typename MakeSequence<n_args>::type())
-  // for the tuple, so that the tuple can be unpacked as a sequence of constructor
-  // parameters in CreateBoolInstantiatedInstanceInner.
-  constexpr std::size_t n_args = std::tuple_size<Tuple>::value;
-  return template_util_inner::CreateBoolInstantiatedInstanceInner<
-      T, ReturnT, bool_values...>(
-          std::forward<Tuple>(args),
-          typename template_util_inner::MakeSequence<n_args>::type());
-}
-
-/**
- * @brief A helper function for creating bool branched templates.
- *
- * The scenario for using this helper function is that, suppose we have a class
- * where all template parameters are bools:
- * --
- * template <bool c1, bool c2, bool c3>
- * class SomeClass : public BaseClass {
- *   // This simple function will be invoked in computationally-intensive loops.
- *   inline SomeType someSimpleFunction(...) {
- *     if (c1) {
- *       doSomeThing1();
- *     }
- *     if (c2) {
- *       doSomeThing2();
- *     }
- *     if (c3) {
- *       doSomeThing3();
- *     }
- *   }
- * };
- * --
- * Typically, this bool-paramterized template is for performance consideration.
- * That is, we would like to make a copy of code for each configuration of bool
- * values, so that there will be no branchings in someSimpleFunction().
- *
- * The problem is that, to conditionally instantiate the template, given bool
- * variables c1, c2, c3, we have to do something like this:
- * --
- * if (c1) {
- *   if (c2) {
- *     if (c3) {
- *       return new SomeClass<true, true, true>(some_args...);
- *     } else {
- *       return new SomeClass<true, true, false>(some_args...);
- *     }
- *   } else {
- *     if (c3) {
- *       return new SomeClass<true, false, true>(some_args...);
- *     } else {
- *       return new SomeClass<true, false, false>(some_args...);
- *     }
- * } else {
- *   ...
- * }
- * --
- * Then there will be power(2,N) branches if the template has N bool parameters,
- * making it tedious to do the instantiating.
- *
- * Now, this helper function can achieve the branched instantiation in one
- * statement as:
- * --
- * return CreateBoolInstantiatedInstance<SomeClass,BaseClass>(
- *     std::forward_as_tuple(some_args...), c1, c2, c3);
- * --
- */
-template <template <bool ...> class T, class ReturnT,
-          bool ...bool_values, typename ...Bools,
-          typename Tuple>
-inline ReturnT* CreateBoolInstantiatedInstance(Tuple &&args,
-                                               const bool tparam,
-                                               const Bools ...rest_tparams) {
-  if (tparam) {
-    return CreateBoolInstantiatedInstance<T, ReturnT, bool_values..., true>(
-        std::forward<Tuple>(args), rest_tparams...);
-  } else {
-    return CreateBoolInstantiatedInstance<T, ReturnT, bool_values..., false>(
-        std::forward<Tuple>(args), rest_tparams...);
-  }
-}
-
-/**
- * @brief A helper function for bool branched template specialization.
- *
- * Usage example:
- * --
- * bool c1 = true, c2 = false;
- *
- * InvokeOnBools(
- *     c1, c2,
- *     [&](auto c1, auto c2) -> SomeBaseClass* {
- *   using T1 = decltype(c1);  // T1 == std::true_type
- *   using T2 = decltype(c2);  // T2 == std::false_type
- *
- *   constexpr bool cv1 = T1::value;  // cv1 == true
- *   constexpr bool cv2 = T2::value;  // cv2 == false
- *
- *   SomeFunction<cv1, cv2>(...);
- *   return new SomeClass<cv1, cv2>(...);
- * });
- * --
- */
-template <typename ...ArgTypes>
-inline auto InvokeOnBools(ArgTypes ...args) {
-  constexpr std::size_t last = sizeof...(args) - 1;
-  return template_util_inner::InvokeOnBoolsInner<last>(
-      std::forward_as_tuple(args...),
-      typename template_util_inner::MakeSequence<last>::type());
-}
-
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/meta/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/utility/meta/CMakeLists.txt b/utility/meta/CMakeLists.txt
new file mode 100644
index 0000000..1b72dd9
--- /dev/null
+++ b/utility/meta/CMakeLists.txt
@@ -0,0 +1,41 @@
+# 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.
+
+# Declare micro-libs:
+add_library(quickstep_utility_meta_Common ../../empty_src.cpp Common.hpp)
+add_library(quickstep_utility_meta_Dispatchers ../../empty_src.cpp Dispatchers.hpp)
+add_library(quickstep_utility_meta_TMP ../../empty_src.cpp TMP.hpp)
+add_library(quickstep_utility_meta_TransitiveClosure ../../empty_src.cpp TransitiveClosure.hpp)
+add_library(quickstep_utility_meta_TypeList ../../empty_src.cpp TypeList.hpp)
+add_library(quickstep_utility_meta_TypeListMetaFunctions ../../empty_src.cpp TypeListMetaFunctions.hpp)
+
+# Link dependencies:
+target_link_libraries(quickstep_utility_meta_Dispatchers
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_utility_meta_TMP
+                      quickstep_utility_meta_Common
+                      quickstep_utility_meta_Dispatchers
+                      quickstep_utility_meta_TransitiveClosure
+                      quickstep_utility_meta_TypeList)
+target_link_libraries(quickstep_utility_meta_TransitiveClosure
+                      quickstep_utility_meta_TypeList)
+target_link_libraries(quickstep_utility_meta_TypeList
+                      quickstep_utility_meta_Common
+                      quickstep_utility_meta_TypeListMetaFunctions)
+target_link_libraries(quickstep_utility_meta_TypeListMetaFunctions
+                      quickstep_utility_meta_Common)
+

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/meta/Common.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp
new file mode 100644
index 0000000..39c513e
--- /dev/null
+++ b/utility/meta/Common.hpp
@@ -0,0 +1,143 @@
+/**
+ * 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_UTILITY_META_COMMON_HPP_
+#define QUICKSTEP_UTILITY_META_COMMON_HPP_
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+template <typename T, T ...s>
+struct Sequence {
+  template <template <typename ...> class Host>
+  using bind_to = Host<std::integral_constant<T, s>...>;
+
+  template <template <T ...> class Host>
+  using bind_values_to = Host<s...>;
+
+  template <typename U>
+  using cast_to = Sequence<U, static_cast<U>(s)...>;
+
+  template <typename CollectionT>
+  inline static CollectionT Instantiate() {
+    return { s... };
+  }
+};
+
+template <std::size_t ...s>
+using IntegerSequence = Sequence<std::size_t, s...>;
+
+
+template <std::size_t n, std::size_t ...s>
+struct MakeSequence : MakeSequence<n-1, n-1, s...> {};
+
+template <std::size_t ...s>
+struct MakeSequence<0, s...> {
+  using type = IntegerSequence<s...>;
+};
+
+
+template <typename ...> struct Conjunction : std::true_type {};
+template <typename B> struct Conjunction<B> : B {};
+template <typename B, typename ...Bs>
+struct Conjunction<B, Bs...>
+    : std::conditional_t<B::value, Conjunction<Bs...>, B> {};
+
+template <typename ...> struct Disjunction : std::false_type {};
+template <typename B> struct Disjunction<B> : B {};
+template <typename B, typename ...Bs>
+struct Disjunction<B, Bs...>
+    : std::conditional_t<B::value, B, Disjunction<Bs...>> {};
+
+template <typename check, typename ...cases>
+struct EqualsAny {
+  static constexpr bool value =
+     Disjunction<std::is_same<check, cases>...>::value;
+};
+
+
+template <typename T, typename Enable = void>
+struct IsTrait {
+  static constexpr bool value = false;
+};
+
+template <typename T>
+struct IsTrait<T, std::enable_if_t<
+    std::is_same<typename T::type, typename T::type>::value>> {
+  static constexpr bool value = true;
+};
+
+template <typename T, template <typename> class Op, typename Enable = void>
+struct IsWellFormed {
+  static constexpr bool value = false;
+};
+
+template <typename T, template <typename> class Op>
+struct IsWellFormed<T, Op, std::enable_if_t<std::is_same<Op<T>, Op<T>>::value>> {
+  static constexpr bool value = true;
+};
+
+
+template <typename LeftT, typename RightT>
+struct PairSelectorLeft {
+  typedef LeftT type;
+};
+
+template <typename LeftT, typename RightT>
+struct PairSelectorRight {
+  typedef RightT type;
+};
+
+
+template <char ...c>
+struct StringLiteral {
+  inline static std::string ToString() {
+    return std::string({c...});
+  }
+};
+
+template <template <typename ...> class Op>
+class TraitWrapper {
+ private:
+  template <typename ...ArgTypes>
+  struct Implemenation {
+    using type = Op<ArgTypes...>;
+  };
+
+ public:
+  template <typename ...ArgTypes>
+  using type = Implemenation<ArgTypes...>;
+};
+
+template <template <typename ...> class Op>
+struct TraitUnwrapper {
+  template <typename ...ArgTypes>
+  using type = typename Op<ArgTypes...>::type;
+};
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_COMMON_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/meta/Dispatchers.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Dispatchers.hpp b/utility/meta/Dispatchers.hpp
new file mode 100644
index 0000000..5b0ee48
--- /dev/null
+++ b/utility/meta/Dispatchers.hpp
@@ -0,0 +1,107 @@
+/**
+ * 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_UTILITY_META_DISPATCHERS_HPP_
+#define QUICKSTEP_UTILITY_META_DISPATCHERS_HPP_
+
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+/**
+ * @brief A helper function for bool branched template specialization.
+ *
+ * Usage example:
+ * --
+ * bool c1 = true, c2 = false;
+ *
+ * InvokeOnBools(
+ *     c1, c2,
+ *     [&](auto c1, auto c2) -> SomeBaseClass* {
+ *   using T1 = decltype(c1);  // T1 == std::true_type
+ *   using T2 = decltype(c2);  // T2 == std::false_type
+ *
+ *   constexpr bool cv1 = T1::value;  // cv1 == true
+ *   constexpr bool cv2 = T2::value;  // cv2 == false
+ *
+ *   SomeFunction<cv1, cv2>(...);
+ *   return new SomeClass<cv1, cv2>(...);
+ * });
+ * --
+ */
+template <typename ...ArgTypes>
+inline auto InvokeOnBools(ArgTypes ...args);
+
+
+namespace internal {
+
+/**
+ * @brief Invoke the functor with the compile-time bool values wrapped as
+ *        integral_constant types.
+ */
+template <typename FunctorT, bool ...bool_values>
+inline auto InvokeOnBoolsInner(const FunctorT &functor) {
+  return functor(std::integral_constant<bool, bool_values>()...);
+}
+
+/**
+ * @brief Recursive dispatching.
+ */
+template <typename FunctorT, bool ...bool_values, typename ...Bools>
+inline auto InvokeOnBoolsInner(const FunctorT &functor,
+                               const bool tparam,
+                               const Bools ...rest_params) {
+  if (tparam) {
+    return InvokeOnBoolsInner<FunctorT, bool_values..., true>(
+        functor, rest_params...);
+  } else {
+    return InvokeOnBoolsInner<FunctorT, bool_values..., false>(
+        functor, rest_params...);
+  }
+}
+
+/**
+ * @brief Move the functor to the first position in argument list.
+ */
+template <std::size_t last, std::size_t ...i, typename TupleT>
+inline auto InvokeOnBoolsInner(TupleT &&args, IntegerSequence<i...> &&indices) {
+  return InvokeOnBoolsInner(std::get<last>(std::forward<TupleT>(args)),
+                            std::get<i>(std::forward<TupleT>(args))...);
+}
+
+}  // namespace internal
+
+template <typename ...ArgTypes>
+inline auto InvokeOnBools(ArgTypes ...args) {
+  constexpr std::size_t last = sizeof...(args) - 1;
+  return internal::InvokeOnBoolsInner<last>(std::forward_as_tuple(args...),
+                                            typename MakeSequence<last>::type());
+}
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_DISPATCHERS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/meta/TMP.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TMP.hpp b/utility/meta/TMP.hpp
new file mode 100644
index 0000000..5456479
--- /dev/null
+++ b/utility/meta/TMP.hpp
@@ -0,0 +1,28 @@
+/**
+ * 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_UTILITY_META_TMP_HPP_
+#define QUICKSTEP_UTILITY_META_TMP_HPP_
+
+#include "utility/meta/Common.hpp"
+#include "utility/meta/Dispatchers.hpp"
+#include "utility/meta/TransitiveClosure.hpp"
+#include "utility/meta/TypeList.hpp"
+
+#endif  // QUICKSTEP_UTILITY_META_TMP_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/meta/TransitiveClosure.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TransitiveClosure.hpp b/utility/meta/TransitiveClosure.hpp
new file mode 100644
index 0000000..a5362bb
--- /dev/null
+++ b/utility/meta/TransitiveClosure.hpp
@@ -0,0 +1,97 @@
+/**
+ * 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_UTILITY_META_TRANSITIVE_CLOSURE_HPP_
+#define QUICKSTEP_UTILITY_META_TRANSITIVE_CLOSURE_HPP_
+
+#include "utility/meta/TypeList.hpp"
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+template <typename Edges>
+struct TransitiveClosure;
+
+
+namespace internal {
+
+template <typename TL, typename Enable = void>
+struct EdgeMatcher {};
+
+template <typename TL>
+struct EdgeMatcher<
+    TL,
+    std::enable_if_t<std::is_same<typename TL::template at<0, 1>,
+                                  typename TL::template at<1, 0>>::value>> {
+  using type = TypeList<typename TL::template at<0, 0>,
+                        typename TL::template at<1, 1>>;
+};
+
+template <typename LeftEdges, typename RightEdges>
+struct JoinPath {
+  using type = typename LeftEdges::template cartesian_product<RightEdges>
+                                 ::template filtermap<EdgeMatcher>;
+};
+
+// Semi-naive
+template <typename Out, typename WorkSet, typename Edges, typename Enable = void>
+struct TransitiveClosureInner;
+
+template <typename Out, typename WorkSet, typename Edges>
+struct TransitiveClosureInner<Out, WorkSet, Edges,
+                              std::enable_if_t<WorkSet::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename WorkSet, typename Edges>
+struct TransitiveClosureInner<Out, WorkSet, Edges,
+                              std::enable_if_t<WorkSet::length != 0>>
+    : TransitiveClosureInner<typename Out::template append<WorkSet>,
+                             typename JoinPath<WorkSet, Edges>::type::template subtract<
+                                 typename Out::template append<WorkSet>>::template unique<>,
+                             Edges> {};
+
+template <typename Edge>
+struct TransitiveClosureInitializer {
+  using type = TypeList<TypeList<typename Edge::head, typename Edge::head>,
+                        TypeList<typename Edge::tail::head, typename Edge::tail::head>>;
+};
+
+template <typename Edges>
+using TransitiveClosureHelper =
+    typename TransitiveClosureInner<TypeList<>,
+                                    typename Edges::template flatmap<
+                                        TransitiveClosureInitializer>::template unique<>,
+                                    Edges>::type;
+
+}  // namespace internal
+
+template <typename Edges>
+struct TransitiveClosure : internal::TransitiveClosureHelper<Edges> {};
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_TRANSITIVE_CLOSURE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/meta/TypeList.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeList.hpp b/utility/meta/TypeList.hpp
new file mode 100644
index 0000000..fac3ce5
--- /dev/null
+++ b/utility/meta/TypeList.hpp
@@ -0,0 +1,124 @@
+/**
+ * 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_UTILITY_META_TYPE_LIST_HPP_
+#define QUICKSTEP_UTILITY_META_TYPE_LIST_HPP_
+
+#include "utility/meta/Common.hpp"
+#include "utility/meta/TypeListMetaFunctions.hpp"
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+template <typename ...Ts>
+class TypeList;
+
+template <typename ...Ts>
+class TypeListCommon {
+ private:
+  template <typename ...Tail> struct AppendHelper {
+    using type = TypeList<Ts..., Tail...>;
+  };
+
+ public:
+  static constexpr std::size_t length = sizeof...(Ts);
+
+  using type = TypeList<Ts...>;
+
+  template <template <typename ...> class Host>
+  using bind_to = Host<Ts...>;
+
+  template <std::size_t ...pos>
+  using at = typename internal::ElementAtImpl<
+      TypeList<Ts...>, TypeList<std::integral_constant<std::size_t, pos>...>>::type;
+
+  template <typename T>
+  using push_front = TypeList<T, Ts...>;
+
+  template <typename T>
+  using push_back = TypeList<Ts..., T>;
+
+  template <typename T>
+  using contains = EqualsAny<T, Ts...>;
+
+  template <typename ...DumbT>
+  using unique = typename internal::UniqueImpl<TypeList<>, TypeList<Ts...>, DumbT...>::type;
+
+  template <typename TL>
+  using append = typename TL::template bind_to<AppendHelper>::type;
+
+  template <typename TL>
+  using cartesian_product = typename internal::CartesianProductImpl<TypeList<Ts...>, TL>::type;
+
+  template <typename Subtrahend>
+  using subtract = typename internal::SubtractImpl<TypeList<>, TypeList<Ts...>, Subtrahend>::type;
+
+  template <template <typename ...> class Op>
+  using map = TypeList<typename Op<Ts>::type...>;
+
+  template <template <typename ...> class Op>
+  using flatmap = typename internal::FlatmapImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+
+  template <template <typename ...> class Op>
+  using filter = typename internal::FilterImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+
+  template <template <typename ...> class Op>
+  using filtermap = typename internal::FiltermapImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+
+  template <typename ...DumbT>
+  using flatten_once = typename internal::FlattenOnceImpl<TypeList<>, TypeList<Ts...>, DumbT...>::type;
+
+  template <typename TL>
+  using zip = typename internal::ZipImpl<TypeList<>, TypeList<Ts...>, TL>::type;
+
+  template <typename TL, template <typename ...> class Op>
+  using zip_with = typename internal::ZipWithImpl<TypeList<>, TypeList<Ts...>, TL, Op>::type;
+
+  template <typename T>
+  using as_sequence = typename internal::AsSequenceImpl<T, Ts...>::type;
+};
+
+template <typename ...Ts>
+class TypeList : public TypeListCommon<Ts...> {
+ private:
+  template <typename Head, typename ...Tail>
+  struct HeadTailHelper {
+    using head = Head;
+    using tail = TypeList<Tail...>;
+  };
+
+ public:
+  using head = typename HeadTailHelper<Ts...>::head;
+  using tail = typename HeadTailHelper<Ts...>::tail;
+};
+
+template <>
+class TypeList<> : public TypeListCommon<> {
+};
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_TYPE_LIST_HPP_


[30/38] incubator-quickstep git commit: Continue the work

Posted by ji...@apache.org.
Continue the work


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/a7ccb467
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/a7ccb467
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/a7ccb467

Branch: refs/heads/refactor-type
Commit: a7ccb4679fd9f183244a2c471cfacc346d8fa13a
Parents: 1792b9f
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Mon Oct 2 15:36:22 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 expressions/table_generator/GenerateSeries.hpp  |  10 +-
 parser/ParseLiteralValue.cpp                    |  12 +-
 .../expressions/BinaryExpression.cpp            |  14 +-
 .../expressions/BinaryExpression.hpp            |  22 +-
 query_optimizer/expressions/Scalar.hpp          |  14 +
 query_optimizer/expressions/ScalarLiteral.cpp   |  16 +-
 query_optimizer/expressions/ScalarLiteral.hpp   |  18 +-
 query_optimizer/expressions/UnaryExpression.cpp |  14 +-
 query_optimizer/expressions/UnaryExpression.hpp |  20 +-
 query_optimizer/resolver/Resolver.cpp           |  45 ++--
 relational_operators/TextScanOperator.cpp       |   2 +-
 storage/SMAIndexSubBlock.cpp                    |   2 +-
 types/ArrayType.hpp                             |   4 +-
 types/BoolType.cpp                              |   4 +-
 types/BoolType.hpp                              |   4 +-
 types/CharType.cpp                              |   8 +-
 types/CharType.hpp                              |   8 +-
 types/DateType.cpp                              |   4 +-
 types/DateType.hpp                              |   4 +-
 types/DatetimeIntervalType.cpp                  |   4 +-
 types/DatetimeIntervalType.hpp                  |   4 +-
 types/DatetimeType.cpp                          |   4 +-
 types/DatetimeType.hpp                          |   4 +-
 types/DoubleType.cpp                            |   4 +-
 types/DoubleType.hpp                            |   4 +-
 types/FloatType.cpp                             |   4 +-
 types/FloatType.hpp                             |   4 +-
 types/GenericValue.hpp                          |  51 +++-
 types/IntType.cpp                               |   4 +-
 types/IntType.hpp                               |   4 +-
 types/LongType.cpp                              |   4 +-
 types/LongType.hpp                              |   4 +-
 types/MetaType.hpp                              |   4 +-
 types/NullType.hpp                              |   4 +-
 types/NumericSuperType.hpp                      |   4 +-
 types/Type.cpp                                  |   4 +-
 types/Type.hpp                                  |  38 +--
 types/TypeSynthesizer.hpp                       | 257 ++++++++++++-------
 types/VarCharType.cpp                           |   8 +-
 types/VarCharType.hpp                           |   8 +-
 types/YearMonthIntervalType.cpp                 |   4 +-
 types/YearMonthIntervalType.hpp                 |   4 +-
 types/operations/OperationFactory.cpp           |  52 ++--
 types/operations/OperationFactory.hpp           |  20 +-
 .../operations/comparisons/BasicComparison.hpp  |   4 +-
 .../unary_operations/CastOperation.hpp          |   2 +-
 46 files changed, 413 insertions(+), 324 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/expressions/table_generator/GenerateSeries.hpp
----------------------------------------------------------------------
diff --git a/expressions/table_generator/GenerateSeries.hpp b/expressions/table_generator/GenerateSeries.hpp
index d749810..19523f5 100644
--- a/expressions/table_generator/GenerateSeries.hpp
+++ b/expressions/table_generator/GenerateSeries.hpp
@@ -118,11 +118,11 @@ class GenerateSeries : public GeneratorFunction {
     DCHECK(args.size() == 2 || args.size() == 3);
 
     // Coerce all arguments to the unified type.
-    TypedValue start = type.coerceValue(args[0], *arg_types[0]);
-    TypedValue end = type.coerceValue(args[1], *arg_types[1]);
-    TypedValue step =
-        args.size() > 2 ? type.coerceValue(args[2], *arg_types[2])
-                        : type.coerceValue(TypedValue(1), TypeFactory::GetType(TypeID::kInt));
+    TypedValue start = type.coerceTypedValue(args[0], *arg_types[0]);
+    TypedValue end = type.coerceTypedValue(args[1], *arg_types[1]);
+    TypedValue step = args.size() > 2
+        ? type.coerceTypedValue(args[2], *arg_types[2])
+        : type.coerceTypedValue(TypedValue(1), TypeFactory::GetType(TypeID::kInt));
 
     // Check that step is not 0, and (end - start) / step is positive
     const GreaterComparison &gt_comparator = GreaterComparison::Instance();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/parser/ParseLiteralValue.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseLiteralValue.cpp b/parser/ParseLiteralValue.cpp
index 04e8a55..caa21e3 100644
--- a/parser/ParseLiteralValue.cpp
+++ b/parser/ParseLiteralValue.cpp
@@ -88,14 +88,14 @@ TypedValue NumericParseLiteralValue::concretize(
   TypedValue parsed_value;
   if ((type_hint != nullptr)
       && (type_hint->getSuperTypeID() == SuperTypeID::kNumeric)
-      && (type_hint->parseValueFromString(numeric_string_, &parsed_value))) {
+      && (type_hint->parseTypedValueFromString(numeric_string_, &parsed_value))) {
     *concretized_type = &(type_hint->getNonNullableVersion());
     return parsed_value;
   }
 
   if (float_like_) {
     *concretized_type = &DoubleType::InstanceNonNullable();
-    CHECK((*concretized_type)->parseValueFromString(numeric_string_, &parsed_value))
+    CHECK((*concretized_type)->parseTypedValueFromString(numeric_string_, &parsed_value))
         << "Failed to parse double from numeric string \""
         << numeric_string_ << "\"";
     return parsed_value;
@@ -153,7 +153,7 @@ TypedValue StringParseLiteralValue::concretize(const Type *type_hint,
   if (explicit_type_ != nullptr) {
     if ((type_hint != nullptr) && (type_hint->isSafelyCoercibleFrom(*explicit_type_))) {
       *concretized_type = type_hint;
-      return type_hint->coerceValue(explicit_parsed_value_, *explicit_type_);
+      return type_hint->coerceTypedValue(explicit_parsed_value_, *explicit_type_);
     } else {
       *concretized_type = explicit_type_;
       return explicit_parsed_value_;
@@ -161,12 +161,12 @@ TypedValue StringParseLiteralValue::concretize(const Type *type_hint,
   } else {
     TypedValue parsed_value;
     if ((type_hint != nullptr)
-        && (type_hint->parseValueFromString(value_->value(), &parsed_value))) {
+        && (type_hint->parseTypedValueFromString(value_->value(), &parsed_value))) {
       *concretized_type = &(type_hint->getNonNullableVersion());
       return parsed_value;
     } else {
       *concretized_type = &VarCharType::InstanceNonNullable(value_->value().length());
-      CHECK((*concretized_type)->parseValueFromString(value_->value(), &parsed_value));
+      CHECK((*concretized_type)->parseTypedValueFromString(value_->value(), &parsed_value));
       return parsed_value;
     }
   }
@@ -189,7 +189,7 @@ std::string StringParseLiteralValue::generateName() const {
 
 bool StringParseLiteralValue::tryExplicitTypeParse() {
   DCHECK(explicit_type_ != nullptr);
-  return explicit_type_->parseValueFromString(value_->value(), &explicit_parsed_value_);
+  return explicit_type_->parseTypedValueFromString(value_->value(), &explicit_parsed_value_);
 }
 
 void StringParseLiteralValue::getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/BinaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/BinaryExpression.cpp b/query_optimizer/expressions/BinaryExpression.cpp
index 24fee40..634c189 100644
--- a/query_optimizer/expressions/BinaryExpression.cpp
+++ b/query_optimizer/expressions/BinaryExpression.cpp
@@ -58,8 +58,7 @@ ExpressionPtr BinaryExpression::copyWithNewChildren(
       operation_,
       std::static_pointer_cast<const Scalar>(new_children[0]),
       std::static_pointer_cast<const Scalar>(new_children[1]),
-      static_arguments_,
-      static_argument_types_);
+      static_arguments_);
 }
 
 std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() const {
@@ -80,7 +79,7 @@ std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() c
       operation_,
       left_->concretize(substitution_map),
       right_->concretize(substitution_map),
-      static_arguments_);
+      static_arguments_cache_);
 }
 
 std::size_t BinaryExpression::computeHash() const {
@@ -94,10 +93,8 @@ std::size_t BinaryExpression::computeHash() const {
   hash_code = CombineHashes(hash_code, left_hash);
   hash_code = CombineHashes(hash_code, right_hash);
 
-  for (const TypedValue &st_arg : *static_arguments_) {
-    if (!st_arg.isNull()) {
-      hash_code = CombineHashes(hash_code, st_arg.getHash());
-    }
+  for (const GenericValue &st_arg : *static_arguments_) {
+    hash_code = CombineHashes(hash_code, st_arg.getHash());
   }
   return hash_code;
 }
@@ -147,8 +144,7 @@ void BinaryExpression::getFieldStringItems(
     container_child_fields->emplace_back();
     for (std::size_t i = 0; i < static_arguments_->size(); ++i) {
       container_child_fields->back().emplace_back(
-          ScalarLiteral::Create(static_arguments_->at(i),
-                                *static_argument_types_->at(i)));
+          ScalarLiteral::Create(static_arguments_->at(i)));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/BinaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/BinaryExpression.hpp b/query_optimizer/expressions/BinaryExpression.hpp
index 6ee6690..5e59e48 100644
--- a/query_optimizer/expressions/BinaryExpression.hpp
+++ b/query_optimizer/expressions/BinaryExpression.hpp
@@ -31,6 +31,7 @@
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/ExpressionType.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
+#include "types/GenericValue.hpp"
 #include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
 #include "utility/Macros.hpp"
@@ -101,15 +102,13 @@ class BinaryExpression : public Scalar {
       const BinaryOperationPtr &operation,
       const ScalarPtr &left,
       const ScalarPtr &right,
-      const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
-      const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) {
+      const std::shared_ptr<const std::vector<GenericValue>> &static_arguments) {
     return BinaryExpressionPtr(
         new BinaryExpression(op_signature,
                              operation,
                              left,
                              right,
-                             static_arguments,
-                             static_argument_types));
+                             static_arguments));
   }
 
   static BinaryExpressionPtr Create(
@@ -122,8 +121,7 @@ class BinaryExpression : public Scalar {
                              operation,
                              left,
                              right,
-                             std::make_shared<const std::vector<TypedValue>>(),
-                             std::make_shared<const std::vector<const Type*>>()));
+                             std::make_shared<const std::vector<GenericValue>>()));
   }
 
  protected:
@@ -142,17 +140,16 @@ class BinaryExpression : public Scalar {
                    const BinaryOperationPtr &operation,
                    const ScalarPtr &left,
                    const ScalarPtr &right,
-                   const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
-                   const std::shared_ptr<const std::vector<const Type*>> &static_argument_types)
+                   const std::shared_ptr<const std::vector<GenericValue>> &static_arguments)
       : op_signature_(op_signature),
         operation_(operation),
         left_(left),
         right_(right),
         static_arguments_(static_arguments),
-        static_argument_types_(static_argument_types),
+        static_arguments_cache_(ToTypedValue(*static_arguments_)),
         result_type_(*(operation_->getResultType(left_->getValueType(),
                                                  right_->getValueType(),
-                                                 *static_arguments))) {
+                                                 *static_arguments_cache_))) {
     addChild(left);
     addChild(right);
   }
@@ -161,8 +158,9 @@ class BinaryExpression : public Scalar {
   const BinaryOperationPtr operation_;
   const ScalarPtr left_;
   const ScalarPtr right_;
-  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_;
-  const std::shared_ptr<const std::vector<const Type*>> static_argument_types_;
+  const std::shared_ptr<const std::vector<GenericValue>> static_arguments_;
+  // TODO(refactor-type): Remove this.
+  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_cache_;
   const Type &result_type_;
 
   DISALLOW_COPY_AND_ASSIGN(BinaryExpression);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/Scalar.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Scalar.hpp b/query_optimizer/expressions/Scalar.hpp
index a163b21..23df7c1 100644
--- a/query_optimizer/expressions/Scalar.hpp
+++ b/query_optimizer/expressions/Scalar.hpp
@@ -29,6 +29,10 @@
 #include "utility/HashError.hpp"
 #include "utility/Macros.hpp"
 
+// TODO(refactor-type): Remove this.
+#include "types/TypedValue.hpp"
+#include "types/GenericValue.hpp"
+
 namespace quickstep {
 
 class CatalogAttribute;
@@ -107,6 +111,16 @@ class Scalar : public Expression {
     throw HashNotSupported("Unsupported computeHash() in " + getName());
   }
 
+  // TODO(refactor-type): Remove this.
+  inline static std::shared_ptr<const std::vector<TypedValue>> ToTypedValue(
+      const std::vector<GenericValue> &input) {
+    std::vector<TypedValue> values;
+    for (const auto &item : input) {
+      values.emplace_back(item.toTypedValue());
+    }
+    return std::make_shared<const std::vector<TypedValue>>(std::move(values));
+  }
+
  private:
   mutable std::unique_ptr<std::size_t> hash_cache_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/ScalarLiteral.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ScalarLiteral.cpp b/query_optimizer/expressions/ScalarLiteral.cpp
index 278e2cc..4dd7ba3 100644
--- a/query_optimizer/expressions/ScalarLiteral.cpp
+++ b/query_optimizer/expressions/ScalarLiteral.cpp
@@ -40,18 +40,18 @@ namespace optimizer {
 namespace expressions {
 
 const Type& ScalarLiteral::getValueType() const {
-  return value_type_;
+  return value_.getType();
 }
 
 ExpressionPtr ScalarLiteral::copyWithNewChildren(
     const std::vector<ExpressionPtr> &new_children) const {
   DCHECK_EQ(new_children.size(), children().size());
-  return ScalarLiteral::Create(value_, value_type_);
+  return ScalarLiteral::Create(value_);
 }
 
 ::quickstep::Scalar *ScalarLiteral::concretize(
     const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
-  return new ::quickstep::ScalarLiteral(value_, value_type_);
+  return new ::quickstep::ScalarLiteral(value_.toTypedValue(), value_.getType());
 }
 
 std::size_t ScalarLiteral::computeHash() const {
@@ -64,12 +64,8 @@ std::size_t ScalarLiteral::computeHash() const {
 
 bool ScalarLiteral::equals(const ScalarPtr &other) const {
   ScalarLiteralPtr lit;
-  if (SomeScalarLiteral::MatchesWithConditionalCast(other, &lit) &&
-      value_type_.equals(lit->value_type_)) {
-    if (value_.isNull() || lit->value_.isNull()) {
-      return value_.isNull() && lit->value_.isNull();
-    }
-    return value_.fastEqualCheck(lit->value_);
+  if (SomeScalarLiteral::MatchesWithConditionalCast(other, &lit)) {
+    return value_.equals(lit->value_);
   }
   return false;
 }
@@ -85,7 +81,7 @@ void ScalarLiteral::getFieldStringItems(
   if (value_.isNull()) {
     inline_field_values->push_back("NULL");
   } else {
-    inline_field_values->push_back(value_type_.printTypedValueToString(value_));
+    inline_field_values->push_back(value_.toString());
   }
 
   inline_field_names->push_back("type");

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/ScalarLiteral.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ScalarLiteral.hpp b/query_optimizer/expressions/ScalarLiteral.hpp
index bff52bb..180ae39 100644
--- a/query_optimizer/expressions/ScalarLiteral.hpp
+++ b/query_optimizer/expressions/ScalarLiteral.hpp
@@ -32,7 +32,7 @@
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/ExpressionType.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
-#include "types/TypedValue.hpp"
+#include "types/GenericValue.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -70,7 +70,7 @@ class ScalarLiteral : public Scalar {
   /**
    * @return The literal value.
    */
-  const TypedValue& value() const { return value_; }
+  const GenericValue& value() const { return value_; }
 
   ExpressionPtr copyWithNewChildren(
       const std::vector<ExpressionPtr> &new_children) const override;
@@ -89,9 +89,8 @@ class ScalarLiteral : public Scalar {
    * @param literal_value The literal value.
    * @return An immutable ScalarLiteral with the given literal value.
    */
-  static const ScalarLiteralPtr Create(const TypedValue &literal_value,
-                                       const Type &literal_value_type) {
-    return ScalarLiteralPtr(new ScalarLiteral(literal_value, literal_value_type));
+  static const ScalarLiteralPtr Create(const GenericValue &literal_value) {
+    return ScalarLiteralPtr(new ScalarLiteral(literal_value));
   }
 
  protected:
@@ -106,13 +105,10 @@ class ScalarLiteral : public Scalar {
       std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
 
  private:
-  ScalarLiteral(const TypedValue &literal_value,
-                const Type &literal_value_type)
-      : value_(literal_value),
-        value_type_(literal_value_type) {}
+  ScalarLiteral(const GenericValue &literal_value)
+      : value_(literal_value) {}
 
-  const TypedValue value_;
-  const Type &value_type_;
+  const GenericValue &value_;
   DISALLOW_COPY_AND_ASSIGN(ScalarLiteral);
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/UnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.cpp b/query_optimizer/expressions/UnaryExpression.cpp
index e1ad014..38cb65c 100644
--- a/query_optimizer/expressions/UnaryExpression.cpp
+++ b/query_optimizer/expressions/UnaryExpression.cpp
@@ -52,8 +52,7 @@ ExpressionPtr UnaryExpression::copyWithNewChildren(
       op_signature_,
       operation_,
       std::static_pointer_cast<const Scalar>(new_children[0]),
-      static_arguments_,
-      static_argument_types_);
+      static_arguments_);
 }
 
 ::quickstep::Scalar* UnaryExpression::concretize(
@@ -62,16 +61,14 @@ ExpressionPtr UnaryExpression::copyWithNewChildren(
       op_signature_,
       operation_,
       operand_->concretize(substitution_map),
-      static_arguments_);
+      static_arguments_cache_);
 }
 
 std::size_t UnaryExpression::computeHash() const {
   std::size_t hash_code = CombineHashes(op_signature_->hash(),
                                         operand_->hash());
-  for (const TypedValue &st_arg : *static_arguments_) {
-    if (!st_arg.isNull()) {
-      hash_code = CombineHashes(hash_code, st_arg.getHash());
-    }
+  for (const GenericValue &st_arg : *static_arguments_) {
+    hash_code = CombineHashes(hash_code, st_arg.getHash());
   }
   return hash_code;
 }
@@ -107,8 +104,7 @@ void UnaryExpression::getFieldStringItems(
     container_child_fields->emplace_back();
     for (std::size_t i = 0; i < static_arguments_->size(); ++i) {
       container_child_fields->back().emplace_back(
-          ScalarLiteral::Create(static_arguments_->at(i),
-                                *static_argument_types_->at(i)));
+          ScalarLiteral::Create(static_arguments_->at(i)));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/expressions/UnaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.hpp b/query_optimizer/expressions/UnaryExpression.hpp
index bbb1841..9c3bf17 100644
--- a/query_optimizer/expressions/UnaryExpression.hpp
+++ b/query_optimizer/expressions/UnaryExpression.hpp
@@ -31,6 +31,7 @@
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/ExpressionType.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
+#include "types/GenericValue.hpp"
 #include "types/operations/OperationSignature.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
 #include "utility/Macros.hpp"
@@ -101,14 +102,12 @@ class UnaryExpression : public Scalar {
       const OperationSignaturePtr &op_signature,
       const UnaryOperationPtr &operation,
       const ScalarPtr &operand,
-      const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
-      const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) {
+      const std::shared_ptr<const std::vector<GenericValue>> &static_arguments) {
     return UnaryExpressionPtr(
         new UnaryExpression(op_signature,
                             operation,
                             operand,
-                            static_arguments,
-                            static_argument_types));
+                            static_arguments));
   }
 
  protected:
@@ -126,22 +125,23 @@ class UnaryExpression : public Scalar {
   UnaryExpression(const OperationSignaturePtr &op_signature,
                   const UnaryOperationPtr &operation,
                   const ScalarPtr &operand,
-                  const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
-                  const std::shared_ptr<const std::vector<const Type*>> &static_argument_types)
+                  const std::shared_ptr<const std::vector<GenericValue>> &static_arguments)
       : op_signature_(op_signature),
         operation_(operation),
         operand_(operand),
         static_arguments_(static_arguments),
-        static_argument_types_(static_argument_types),
-        result_type_(*(operation_->getResultType(operand_->getValueType(), *static_arguments_))) {
+        static_arguments_cache_(ToTypedValue(*static_arguments_)),
+        result_type_(*(operation_->getResultType(operand_->getValueType(),
+                                                 *static_arguments_cache_))) {
     addChild(operand);
   }
 
   const OperationSignaturePtr op_signature_;
   const UnaryOperationPtr operation_;
   const ScalarPtr operand_;
-  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_;
-  const std::shared_ptr<const std::vector<const Type*>> static_argument_types_;
+  const std::shared_ptr<const std::vector<GenericValue>> static_arguments_;
+  // TODO(refactor-type): Remove this.
+  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_cache_;
   const Type &result_type_;
 
   DISALLOW_COPY_AND_ASSIGN(UnaryExpression);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 7c257bb..1ed6b2e 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -115,6 +115,7 @@
 #include "query_optimizer/resolver/NameResolver.hpp"
 #include "storage/StorageBlockLayout.pb.h"
 #include "storage/StorageConstants.hpp"
+#include "types/GenericValue.hpp"
 #include "types/IntType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
@@ -1070,6 +1071,7 @@ L::LogicalPtr Resolver::resolveInsertTuple(
   std::vector<E::ScalarLiteralPtr> resolved_column_values;
   std::vector<E::AttributeReferencePtr>::size_type aid = 0;
   for (const ParseScalarLiteral &parse_literal_value : parse_column_values) {
+    const Type &attribute_type = relation_attributes[aid]->getValueType();
     E::ScalarLiteralPtr resolved_literal_value;
     ExpressionResolutionInfo expr_resolution_info(
         name_resolver,
@@ -1078,30 +1080,25 @@ L::LogicalPtr Resolver::resolveInsertTuple(
     // When resolving the literal, use the attribute's Type as a hint.
     CHECK(E::SomeScalarLiteral::MatchesWithConditionalCast(
         resolveExpression(parse_literal_value,
-                          &(relation_attributes[aid]->getValueType()),
+                          &attribute_type,
                           &expr_resolution_info),
         &resolved_literal_value));
 
     // Check that the resolved Type is safely coercible to the attribute's
     // Type.
-    if (!relation_attributes[aid]->getValueType().isSafelyCoercibleFrom(
-            resolved_literal_value->getValueType())) {
+    if (!attribute_type.isSafelyCoercibleFrom(resolved_literal_value->getValueType())) {
       THROW_SQL_ERROR_AT(&parse_literal_value)
           << "The assigned value for the column "
           << relation_attributes[aid]->attribute_name() << " has the type "
           << resolved_literal_value->getValueType().getName()
           << ", which cannot be safely coerced to the column's type "
-          << relation_attributes[aid]->getValueType().getName();
+          << attribute_type.getName();
     }
 
     // If the Type is not exactly right (but is safely coercible), coerce it.
-    if (!resolved_literal_value->getValueType().equals(
-            relation_attributes[aid]->getValueType())) {
+    if (!resolved_literal_value->getValueType().equals(attribute_type)) {
       resolved_literal_value = E::ScalarLiteral::Create(
-          relation_attributes[aid]->getValueType().coerceValue(
-              resolved_literal_value->value(),
-              resolved_literal_value->getValueType()),
-          relation_attributes[aid]->getValueType());
+          resolved_literal_value->value().coerce(attribute_type));
     }
 
     resolved_column_values.push_back(resolved_literal_value);
@@ -1116,8 +1113,7 @@ L::LogicalPtr Resolver::resolveInsertTuple(
     }
     // Create a NULL value.
     resolved_column_values.push_back(E::ScalarLiteral::Create(
-        relation_attributes[aid]->getValueType().makeNullValue(),
-        relation_attributes[aid]->getValueType()));
+        GenericValue(relation_attributes[aid]->getValueType())));
     ++aid;
   }
 
@@ -2452,7 +2448,7 @@ E::ScalarPtr Resolver::resolveExpression(
       const Type *concrete_type = nullptr;
       TypedValue concrete = parse_literal_scalar.literal_value()
           ->concretize(type_hint, &concrete_type);
-      return E::ScalarLiteral::Create(std::move(concrete), *concrete_type);
+      return E::ScalarLiteral::Create(GenericValue(*concrete_type, concrete));
     }
     case ParseExpression::kSearchedCaseExpression: {
       const ParseSearchedCaseExpression &parse_searched_case_expression =
@@ -2507,7 +2503,6 @@ E::ScalarPtr Resolver::resolveArray(
 //
 //    // Currently we only support homogeneous array with literal values.
 //  }
-
   LOG(FATAL) << "Not supported";
 }
 
@@ -2785,22 +2780,22 @@ E::ScalarPtr Resolver::resolveScalarFunction(
     argument_types.emplace_back(&argument->getValueType());
   }
 
-  std::vector<TypedValue> static_arguments;
+  std::vector<GenericValue> static_arguments;
   for (std::size_t i = first_static_argument_position; i < arity; ++i) {
     static_arguments.emplace_back(
         std::static_pointer_cast<const E::ScalarLiteral>(
             resolved_arguments[i])->value());
-    DCHECK(static_arguments.back().getTypeID() == argument_types[i]->getTypeID());
+    DCHECK(static_arguments.back().getType().getTypeID() == argument_types[i]->getTypeID());
   }
 
   std::shared_ptr<const std::vector<const Type*>> coerced_argument_types;
-  std::shared_ptr<const std::vector<TypedValue>> coerced_static_arguments;
+  std::shared_ptr<const std::vector<GenericValue>> coerced_static_arguments;
   std::string message;
   const OperationSignaturePtr op_signature =
       OperationFactory::Instance().resolveOperation(
           function_name,
           std::make_shared<const std::vector<const Type*>>(std::move(argument_types)),
-          std::make_shared<const std::vector<TypedValue>>(std::move(static_arguments)),
+          std::make_shared<const std::vector<GenericValue>>(std::move(static_arguments)),
           &coerced_argument_types,
           &coerced_static_arguments,
           &message);
@@ -2815,11 +2810,7 @@ E::ScalarPtr Resolver::resolveScalarFunction(
   }
 
   // TODO: add cast if neccessary.
-
-  const auto coerced_static_argument_types =
-      std::make_shared<const std::vector<const Type*>>(
-          coerced_argument_types->begin() + op_signature->getNonStaticArity(),
-          coerced_argument_types->end());
+  (void)coerced_argument_types;
 
   const OperationPtr operation =
       OperationFactory::Instance().getOperation(op_signature);
@@ -2829,16 +2820,14 @@ E::ScalarPtr Resolver::resolveScalarFunction(
           op_signature,
           std::static_pointer_cast<const UnaryOperation>(operation),
           resolved_arguments[0],
-          coerced_static_arguments,
-          coerced_static_argument_types);
+          coerced_static_arguments);
     case Operation::kBinaryOperation:
       return E::BinaryExpression::Create(
           op_signature,
           std::static_pointer_cast<const BinaryOperation>(operation),
           resolved_arguments[0],
           resolved_arguments[1],
-          coerced_static_arguments,
-          coerced_static_argument_types);
+          coerced_static_arguments);
     default: {
       const auto operation_id =
          static_cast<std::underlying_type_t<Operation::OperationSuperTypeID>>(
@@ -3337,7 +3326,7 @@ void Resolver::rewriteIfOrdinalReference(
   if (E::SomeScalarLiteral::MatchesWithConditionalCast(*expression, &literal) &&
       literal->getValueType().getTypeID() == kInt &&
       !literal->value().isNull()) {
-    int position = literal->value().getLiteral<int>();
+    int position = literal->value().getLiteral<kInt>();
     if (position < 1 ||
         position > static_cast<int>(
                        select_list_info->select_list_expressions.size())) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/relational_operators/TextScanOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/TextScanOperator.cpp b/relational_operators/TextScanOperator.cpp
index 66137d8..3885888 100644
--- a/relational_operators/TextScanOperator.cpp
+++ b/relational_operators/TextScanOperator.cpp
@@ -474,7 +474,7 @@ std::vector<TypedValue> TextScanWorkOrder::parseRow(const char **row_ptr,
       attribute_values.emplace_back(attr.getType().makeNullValue());
     } else {
       attribute_values.emplace_back();
-      if (!attr.getType().parseValueFromString(value_str, &(attribute_values.back()))) {
+      if (!attr.getType().parseTypedValueFromString(value_str, &(attribute_values.back()))) {
         // Do not abort if one of the row is faulty.
         *is_faulty = true;
         LOG(INFO) << "Failed to parse value.";

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/storage/SMAIndexSubBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/SMAIndexSubBlock.cpp b/storage/SMAIndexSubBlock.cpp
index 96a744e..5a8a747 100644
--- a/storage/SMAIndexSubBlock.cpp
+++ b/storage/SMAIndexSubBlock.cpp
@@ -640,7 +640,7 @@ Selectivity SMAIndexSubBlock::getSelectivityForPredicate(const ComparisonPredica
       SMAPredicate *replacement = new SMAPredicate(
           sma_predicate->attribute,
           sma_predicate->comparison,
-          attribute_type.coerceValue(sma_predicate->literal, literal_type));
+          attribute_type.coerceTypedValue(sma_predicate->literal, literal_type));
       sma_predicate.reset(replacement);
     } else {
       // The literal type cannot be converted, so do not evaluate with the SMA.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
index 1c66ed2..fe81c3e 100644
--- a/types/ArrayType.hpp
+++ b/types/ArrayType.hpp
@@ -46,8 +46,8 @@ class ArrayType : public TypeSynthesizer<kArray> {
 
   std::string printValueToString(const UntypedLiteral *value) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override {
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
     return false;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/BoolType.cpp
----------------------------------------------------------------------
diff --git a/types/BoolType.cpp b/types/BoolType.cpp
index 9680770..7687f06 100644
--- a/types/BoolType.cpp
+++ b/types/BoolType.cpp
@@ -47,8 +47,8 @@ void BoolType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value) ? "true" : "false");
 }
 
-bool BoolType::parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const {
+bool BoolType::parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const {
   const std::string lo_value = ToLower(value_string);
   if (lo_value == "true") {
     *value = TypedValue(true);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/BoolType.hpp
----------------------------------------------------------------------
diff --git a/types/BoolType.hpp b/types/BoolType.hpp
index 2ba380a..ed819ae 100644
--- a/types/BoolType.hpp
+++ b/types/BoolType.hpp
@@ -54,8 +54,8 @@ class BoolType : public NumericSuperType<kBool> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit BoolType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/CharType.cpp
----------------------------------------------------------------------
diff --git a/types/CharType.cpp b/types/CharType.cpp
index ea3d00e..eb3f64a 100644
--- a/types/CharType.cpp
+++ b/types/CharType.cpp
@@ -87,8 +87,8 @@ void CharType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value).getOutOfLineData());
 }
 
-bool CharType::parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const {
+bool CharType::parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const {
   if (value_string.length() > length_) {
     return false;
   }
@@ -102,8 +102,8 @@ bool CharType::parseValueFromString(const std::string &value_string,
   return true;
 }
 
-TypedValue CharType::coerceValue(const TypedValue &original_value,
-                                 const Type &original_type) const {
+TypedValue CharType::coerceTypedValue(const TypedValue &original_value,
+                                      const Type &original_type) const {
   DCHECK(isCoercibleFrom(original_type))
       << "Can't coerce value of Type " << original_type.getName()
       << " to Type " << getName();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index 32b0c7a..81a32ff 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -59,11 +59,11 @@ class CharType : public AsciiStringSuperType<kChar> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
-  TypedValue coerceValue(const TypedValue &original_value,
-                         const Type &original_type) const override;
+  TypedValue coerceTypedValue(const TypedValue &original_value,
+                              const Type &original_type) const override;
 
  private:
   CharType(const bool nullable, const std::size_t length)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DateType.cpp
----------------------------------------------------------------------
diff --git a/types/DateType.cpp b/types/DateType.cpp
index dcd779d..a88b5bd 100644
--- a/types/DateType.cpp
+++ b/types/DateType.cpp
@@ -75,8 +75,8 @@ std::string DateType::printValueToString(const UntypedLiteral *value) const {
   return std::string(datebuf);
 }
 
-bool DateType::parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const {
+bool DateType::parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const {
   std::int32_t year;
   std::uint32_t month, day;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index b7d1820..1c9eaf9 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -61,8 +61,8 @@ class DateType : public TypeSynthesizer<kDate> {
    *       fail if there are any "extra" characters at the end of the string
    *       after a parsable ISO-8601 date.
    **/
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit DateType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DatetimeIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.cpp b/types/DatetimeIntervalType.cpp
index e419ce3..a4b2896 100644
--- a/types/DatetimeIntervalType.cpp
+++ b/types/DatetimeIntervalType.cpp
@@ -110,8 +110,8 @@ std::string DatetimeIntervalType::printValueToString(const UntypedLiteral *value
   return std::string(interval_buf);
 }
 
-bool DatetimeIntervalType::parseValueFromString(const std::string &value_string,
-                                                TypedValue *value) const {
+bool DatetimeIntervalType::parseTypedValueFromString(const std::string &value_string,
+                                                     TypedValue *value) const {
   // Try simple-format parse first.
   std::int64_t count;
   std::string units;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index bf36609..cb2534d 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -53,8 +53,8 @@ class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
     return TypedValue(DatetimeIntervalLit{0});
   }
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit DatetimeIntervalType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DatetimeType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.cpp b/types/DatetimeType.cpp
index 11ffae9..6d5fc2d 100644
--- a/types/DatetimeType.cpp
+++ b/types/DatetimeType.cpp
@@ -103,8 +103,8 @@ std::string DatetimeType::printValueToString(const UntypedLiteral *value) const
   return std::string(datebuf);
 }
 
-bool DatetimeType::parseValueFromString(const std::string &value_string,
-                                        TypedValue *value) const {
+bool DatetimeType::parseTypedValueFromString(const std::string &value_string,
+                                             TypedValue *value) const {
   int year;
   int month;
   int day;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index 924ff35..d0ac1e2 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -70,8 +70,8 @@ class DatetimeType
    *       fail if there are any "extra" characters at the end of the string
    *       after a parsable ISO-8601 date/time.
    **/
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit DatetimeType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DoubleType.cpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.cpp b/types/DoubleType.cpp
index fb50957..8219955 100644
--- a/types/DoubleType.cpp
+++ b/types/DoubleType.cpp
@@ -66,8 +66,8 @@ void DoubleType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value));
 }
 
-bool DoubleType::parseValueFromString(const std::string &value_string,
-                                      TypedValue *value) const {
+bool DoubleType::parseTypedValueFromString(const std::string &value_string,
+                                           TypedValue *value) const {
   double parsed_double;
   int read_chars;
   int matched = std::sscanf(value_string.c_str(),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index ddba4e3..6959817 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -52,8 +52,8 @@ class DoubleType : public NumericSuperType<kDouble> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   static_assert((std::numeric_limits<double>::max_exponent10 < 1000)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/FloatType.cpp
----------------------------------------------------------------------
diff --git a/types/FloatType.cpp b/types/FloatType.cpp
index ca741a6..5fcefc9 100644
--- a/types/FloatType.cpp
+++ b/types/FloatType.cpp
@@ -66,8 +66,8 @@ void FloatType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value));
 }
 
-bool FloatType::parseValueFromString(const std::string &value_string,
-                                     TypedValue *value) const {
+bool FloatType::parseTypedValueFromString(const std::string &value_string,
+                                          TypedValue *value) const {
   float parsed_float;
   int read_chars;
   int matched = std::sscanf(value_string.c_str(),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 68a636b..3a7aa41 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -52,8 +52,8 @@ class FloatType : public NumericSuperType<kFloat> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   static_assert((std::numeric_limits<float>::max_exponent10 < 100)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
index 61529d6..1fcdcd6 100644
--- a/types/GenericValue.hpp
+++ b/types/GenericValue.hpp
@@ -26,8 +26,10 @@
 #include <string>
 
 #include "types/Type.hpp"
+#include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypeRegistrar.hpp"
+#include "types/TypedValue.hpp"
 #include "utility/HashPair.hpp"
 #include "utility/Macros.hpp"
 
@@ -41,16 +43,23 @@ namespace quickstep {
 
 class GenericValue {
  public:
+  GenericValue(const Type &type)
+      : type_(type), value_(nullptr), owns_(true) {}
+
   GenericValue(const Type &type, const UntypedLiteral *value, const bool owns)
       : type_(type), value_(value), owns_(owns) {}
 
+  GenericValue(const Type &type, const TypedValue &value)
+      : type_(type), value_(type.unmarshallTypedValue(value)), owns_(true) {}
+
   template <typename TypeClass>
   GenericValue(const TypeClass &type, const typename TypeClass::cpptype &value)
       : type_(type), value_(type.cloneValue(&value)), owns_(true) {}
 
   GenericValue(const GenericValue &other)
       : type_(other.type_),
-        value_(other.owns_ ? type_.cloneValue(other.value_) : other.value_),
+        value_((other.owns_ && !other.isNull()) ? type_.cloneValue(other.value_)
+                                                : other.value_),
         owns_(other.owns_) {}
 
   GenericValue(GenericValue &&other)
@@ -61,11 +70,15 @@ class GenericValue {
   }
 
   ~GenericValue() {
-    if (owns_ && value_ != nullptr) {
+    if (owns_ && !isNull()) {
       type_.destroyValue(const_cast<void*>(value_));
     }
   }
 
+  serialization::GenericValue getProto() const {
+    LOG(FATAL) << "Not implemented";
+  }
+
   inline bool isNull() const {
     DCHECK(value_ != nullptr || type_.isNullable());
     return value_ == nullptr;
@@ -86,23 +99,47 @@ class GenericValue {
   template <TypeID type_id>
   inline const typename TypeIDTrait<type_id>::cpptype& getLiteral() const {
     DCHECK_EQ(type_id, type_.getTypeID());
-    return *static_cast<typename TypeIDTrait<type_id>::cpptype*>(value_);
+    return *static_cast<const typename TypeIDTrait<type_id>::cpptype*>(value_);
   }
 
   inline void ensureNotReference() {
     if (isReference()) {
-      value_ = type_.cloneValue(value_);
+      if (!isNull()) {
+        value_ = type_.cloneValue(value_);
+      }
       owns_ = true;
     }
   }
 
+  inline GenericValue makeReferenceToThis() const {
+    return GenericValue(type_, value_, false);
+  }
+
+  inline bool equals(const GenericValue &other) const {
+    if (isNull() || other.isNull()) {
+      return isNull() && other.isNull();
+    }
+    return type_.checkValuesEqual(value_, other.value_, other.type_);
+  }
+
   inline bool operator==(const GenericValue &other) const {
-    return type_.equals(other.type_) &&
-           type_.checkValuesEqual(value_, other.value_);
+    return equals(other);
   }
 
   inline std::size_t getHash() const {
-    return CombineHashes(type_.getHash(), type_.hashValue(value_));
+    return isNull() ? 0  : type_.hashValue(value_);
+  }
+
+  inline GenericValue coerce(const Type &other_type) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  inline TypedValue toTypedValue() const {
+    return isNull() ? type_.makeNullValue() : type_.marshallValue(value_);
+  }
+
+  inline std::string toString() const {
+    return isNull() ? "NULL" : type_.printValueToString(value_);
   }
 
  private:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/IntType.cpp
----------------------------------------------------------------------
diff --git a/types/IntType.cpp b/types/IntType.cpp
index 8e3aff1..07db133 100644
--- a/types/IntType.cpp
+++ b/types/IntType.cpp
@@ -46,8 +46,8 @@ void IntType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value));
 }
 
-bool IntType::parseValueFromString(const std::string &value_string,
-                                   TypedValue *value) const {
+bool IntType::parseTypedValueFromString(const std::string &value_string,
+                                        TypedValue *value) const {
   int parsed_int;
   int read_chars;
   int matched = std::sscanf(value_string.c_str(),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index d83c257..eb5e5aa 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -54,8 +54,8 @@ class IntType : public NumericSuperType<kInt> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit IntType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/LongType.cpp
----------------------------------------------------------------------
diff --git a/types/LongType.cpp b/types/LongType.cpp
index 82dce39..ffb9eb7 100644
--- a/types/LongType.cpp
+++ b/types/LongType.cpp
@@ -52,8 +52,8 @@ void LongType::printValueToFile(const UntypedLiteral *value,
                castValueToLiteral(value));
 }
 
-bool LongType::parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const {
+bool LongType::parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const {
   std::int64_t parsed_long;
   int read_chars;
   int matched = std::sscanf(value_string.c_str(),

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index 7561975..dc75310 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -55,8 +55,8 @@ class LongType : public NumericSuperType<kLong> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit LongType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/MetaType.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType.hpp b/types/MetaType.hpp
index 0c3952b..c046771 100644
--- a/types/MetaType.hpp
+++ b/types/MetaType.hpp
@@ -46,8 +46,8 @@ class MetaType : public TypeSynthesizer<kMetaType> {
 
   std::string printValueToString(const UntypedLiteral *value) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override {
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
     return false;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index 8dd237e..1aa8a1c 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -79,8 +79,8 @@ class NullType : public TypeSynthesizer<kNullType> {
     LOG(FATAL) << "NullType is not printable";
   }
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override {
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
     return false;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index 6576cbf..f474d52 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -62,8 +62,8 @@ class NumericSuperType : public TypeSynthesizer<type_id> {
     return TypedValue(static_cast<typename TypeIDTrait<type_id>::cpptype>(0));
   }
 
-  TypedValue coerceValue(const TypedValue &original_value,
-                         const Type &original_type) const override {
+  TypedValue coerceTypedValue(const TypedValue &original_value,
+                              const Type &original_type) const override {
     if (original_type.getSuperTypeID() != SuperTypeID::kNumeric) {
       LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
                  << " (not recognized as a numeric Type) to " << Type::getName();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index 34678c7..b0b781a 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -59,8 +59,8 @@ void Type::printValueToFile(const UntypedLiteral *value,
   std::fprintf(file, "%*s", padding, printValueToString(value).c_str());
 }
 
-TypedValue Type::coerceValue(const TypedValue &original_value,
-                             const Type &original_type) const {
+TypedValue Type::coerceTypedValue(const TypedValue &original_value,
+                                  const Type &original_type) const {
   DCHECK(isCoercibleFrom(original_type))
       << "Can't coerce value of Type " << original_type.getName()
       << " to Type " << getName();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index 47f00e6..d4ed993 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -293,13 +293,13 @@ class Type {
 
   virtual std::string printValueToString(const UntypedLiteral *value) const = 0;
 
+  virtual std::string printTypedValueToString(const TypedValue &value) const = 0;
+
 
   virtual void printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding = 0) const;
 
-  virtual std::string printTypedValueToString(const TypedValue &value) const = 0;
-
   virtual void printTypedValueToFile(const TypedValue &value,
                                      FILE *file,
                                      const int padding = 0) const = 0;
@@ -379,8 +379,8 @@ class Type {
    * @return true if value_string was successfully parsed and value was
    *         written. false if value_string was not in the correct format.
    **/
-  virtual bool parseValueFromString(const std::string &value_string,
-                                    TypedValue *value) const = 0;
+  virtual bool parseTypedValueFromString(const std::string &value_string,
+                                         TypedValue *value) const = 0;
 
   /**
    * @brief Coerce a value of another Type to this Type.
@@ -398,32 +398,32 @@ class Type {
    * @return A new TypedValue that represents original_value as an instance of
    *         this Type.
    **/
-  virtual TypedValue coerceValue(const TypedValue &original_value,
-                                 const Type &original_type) const;
+  virtual TypedValue coerceTypedValue(const TypedValue &original_value,
+                                      const Type &original_type) const;
 
-  virtual std::size_t getHash() const {
-    LOG(FATAL) << "Not implemented";
-  }
 
+  virtual std::size_t getHash() const = 0;
 
   virtual bool checkValuesEqual(const UntypedLiteral *lhs,
-                                const UntypedLiteral *rhs) const {
+                                const UntypedLiteral *rhs,
+                                const Type &rhs_type) const {
     LOG(FATAL) << "Not implemented";
   }
 
-  virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
-    LOG(FATAL) << "Not implemented";
+  inline bool checkValuesEqual(const UntypedLiteral *lhs,
+                               const UntypedLiteral *rhs) const {
+    return checkValuesEqual(lhs, rhs, *this);
   }
 
-  virtual std::size_t hashValue(const UntypedLiteral *value) const {
-    LOG(FATAL) << "Not implemented";
-  }
+  virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const = 0;
+
+  virtual void destroyValue(UntypedLiteral *value) const = 0;
 
-  virtual void destroyValue(UntypedLiteral *value_ptr) const {
+  virtual std::size_t hashValue(const UntypedLiteral *value) const {
     LOG(FATAL) << "Not implemented";
   }
 
-  virtual CharStream marshallValue(const UntypedLiteral *value) const {
+  virtual TypedValue marshallValue(const UntypedLiteral *value) const {
     LOG(FATAL) << "Not implemented";
   }
 
@@ -433,9 +433,9 @@ class Type {
 
   }
 
-  virtual UntypedLiteral* unmarshallValue(const TypedValue &value) const = 0;
+  virtual UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const = 0;
 
-  virtual UntypedLiteral* unmarshallValue(TypedValue &&value) const = 0;
+  virtual UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const = 0;
 
  protected:
   Type(const SuperTypeID super_type_id,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index 7c39e47..08ab67a 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -22,6 +22,8 @@
 
 #include <cstddef>
 #include <cstdio>
+#include <cstdlib>
+#include <cstring>
 #include <memory>
 #include <string>
 #include <type_traits>
@@ -46,16 +48,16 @@ namespace quickstep {
  */
 
 template <TypeID type_id, typename Enable = void>
-class TypeInstancePolicy;
+class TypeSynthesizePolicy;
 
 
 template <TypeID type_id>
 class TypeSynthesizer
     : public Type,
-      public TypeInstancePolicy<type_id> {
+      public TypeSynthesizePolicy<type_id> {
  private:
   using Trait = TypeIDTrait<type_id>;
-  using InstancePolicy = TypeInstancePolicy<type_id>;
+  using SynthesizePolicy = TypeSynthesizePolicy<type_id>;
 
  public:
   static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
@@ -71,38 +73,41 @@ class TypeSynthesizer
 
     proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
     proto.set_nullable(nullable_);
-
-    InstancePolicy::fillProto(&proto);
+    SynthesizePolicy::mergeIntoProto(&proto);
 
     return proto;
   }
 
   const Type& getNullableVersion() const override {
-    return InstancePolicy::getInstance(true);
+    return SynthesizePolicy::getInstance(true);
   }
 
   const Type& getNonNullableVersion() const override {
-    return InstancePolicy::getInstance(false);
+    return SynthesizePolicy::getInstance(false);
   }
 
-  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
-    return *static_cast<const cpptype*>(value);
+  std::size_t getHash() const override {
+    return SynthesizePolicy::getHash();
   }
 
-  cpptype& castValueToLiteral(UntypedLiteral *value) const {
-    return *static_cast<cpptype*>(value);
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
+    return SynthesizePolicy::cloneValue(value);
   }
 
-  UntypedLiteral* unmarshallValue(const TypedValue &value) const override {
-    return unmarshallInternal<kMemoryLayout>(value);
+  void destroyValue(UntypedLiteral *value) const override {
+    return SynthesizePolicy::destroyValue(value);
   }
 
-  UntypedLiteral* unmarshallValue(TypedValue &&value) const override {
-    return unmarshallInternal<kMemoryLayout>(std::move(value));
+  UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override {
+    return SynthesizePolicy::unmarshallTypedValue(value);
+  }
+
+  UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const override {
+    return SynthesizePolicy::unmarshallTypedValue(std::move(value));
   }
 
   std::string printTypedValueToString(const TypedValue &value) const override {
-    return invokeOnUnmarshalledValue<kMemoryLayout>(
+    return SynthesizePolicy::invokeOnUnmarshalledTypedValue(
         value,
         [&](const UntypedLiteral *value) -> std::string {
       return this->printValueToString(value);
@@ -112,20 +117,28 @@ class TypeSynthesizer
   void printTypedValueToFile(const TypedValue &value,
                              FILE *file,
                              const int padding = 0) const override {
-    invokeOnUnmarshalledValue<kMemoryLayout>(
+    SynthesizePolicy::invokeOnUnmarshalledTypedValue(
         value,
         [&](const UntypedLiteral *value) -> void {
       this->printValueToFile(value, file, padding);
     });
   }
 
+  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
+    return *static_cast<const cpptype*>(value);
+  }
+
+  cpptype& castValueToLiteral(UntypedLiteral *value) const {
+    return *static_cast<cpptype*>(value);
+  }
+
  protected:
   template <MemoryLayout layout = kMemoryLayout>
   explicit TypeSynthesizer(const bool nullable,
                            std::enable_if_t<layout == kCxxInlinePod>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
              sizeof(cpptype), sizeof(cpptype)),
-        TypeInstancePolicy<type_id>() {
+        TypeSynthesizePolicy<type_id>(this) {
   }
 
   template <MemoryLayout layout = kMemoryLayout>
@@ -133,10 +146,11 @@ class TypeSynthesizer
                   const std::size_t minimum_byte_length,
                   const std::size_t maximum_byte_length,
                   const std::size_t parameter,
-                  std::enable_if_t<layout == kParInlinePod || layout == kParOutOfLinePod>* = 0)
+                  std::enable_if_t<layout == kParInlinePod ||
+                                   layout == kParOutOfLinePod>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
              minimum_byte_length, maximum_byte_length),
-        TypeInstancePolicy<type_id>(parameter) {
+        TypeSynthesizePolicy<type_id>(this, parameter) {
   }
 
   template <MemoryLayout layout = kMemoryLayout>
@@ -147,70 +161,11 @@ class TypeSynthesizer
                   std::enable_if_t<layout == kCxxGeneric>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
              minimum_byte_length, maximum_byte_length),
-        TypeInstancePolicy<type_id>(parameters) {
+        TypeSynthesizePolicy<type_id>(this, parameters) {
   }
 
  private:
-  template <MemoryLayout layout>
-  inline UntypedLiteral* unmarshallInternal(
-      const TypedValue &value,
-      std::enable_if_t<layout == kCxxInlinePod> * = 0) const {
-    return cloneValue(value.getDataPtr());
-  }
-
-  template <MemoryLayout layout>
-  inline UntypedLiteral* unmarshallInternal(
-      const TypedValue &value,
-      std::enable_if_t<layout == kParInlinePod ||
-                       layout == kParOutOfLinePod> * = 0) const {
-    return cloneValue(&value);
-  }
-
-  template <MemoryLayout layout>
-  inline UntypedLiteral* unmarshallInternal(
-      TypedValue &&value,
-      std::enable_if_t<layout == kParInlinePod ||
-                       layout == kParOutOfLinePod> * = 0) const {
-    return new TypedValue(std::move(value));
-  }
-
-  template <MemoryLayout layout>
-  inline UntypedLiteral* unmarshallInternal(
-      const TypedValue &value,
-      std::enable_if_t<layout == kCxxGeneric> * = 0) const {
-    return Type::unmarshallValue(value.getOutOfLineData(), value.getDataSize());
-  }
-
-
-  template <MemoryLayout layout, typename Functor>
-  inline auto invokeOnUnmarshalledValue(
-      const TypedValue &value,
-      const Functor &functor,
-      std::enable_if_t<layout == kCxxInlinePod> * = 0) const {
-    return functor(value.getDataPtr());
-  }
-
-  template <MemoryLayout layout, typename Functor>
-  inline auto invokeOnUnmarshalledValue(
-      const TypedValue &value,
-      const Functor &functor,
-      std::enable_if_t<layout == kParInlinePod ||
-                       layout == kParOutOfLinePod> * = 0) const {
-    return functor(&value);
-  }
-
-  template <MemoryLayout layout, typename Functor>
-  inline auto invokeOnUnmarshalledValue(
-      const TypedValue &value,
-      const Functor &functor,
-      std::enable_if_t<layout == kCxxGeneric> * = 0) const {
-    std::unique_ptr<cpptype> literal(
-        static_cast<cpptype*>(Type::unmarshallValue(value.getOutOfLineData(),
-                                                    value.getDataSize())));
-    return functor(literal.get());
-  }
-
-  template <TypeID, typename> friend class TypeInstancePolicy;
+  template <TypeID, typename> friend class TypeSynthesizePolicy;
 
   DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
@@ -229,12 +184,13 @@ constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
 
 
 template <TypeID type_id>
-class TypeInstancePolicy<
+class TypeSynthesizePolicy<
     type_id,
     std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
 
  public:
   static const TypeClass& InstanceNonNullable() {
@@ -254,13 +210,40 @@ class TypeInstancePolicy<
   }
 
  protected:
-  TypeInstancePolicy() {}
+  explicit TypeSynthesizePolicy(const Type *base)
+      : base_(*base) {}
 
   inline const Type& getInstance(const bool nullable) const {
     return nullable ? InstanceNullable() : InstanceNonNullable();
   }
 
-  inline void fillProto(serialization::Type *proto) const {}
+  inline void mergeIntoProto(serialization::Type *proto) const {}
+
+  inline std::size_t getHash() const {
+    return static_cast<std::size_t>(base_.getTypeID());
+  }
+
+  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    UntypedLiteral* clone = std::malloc(sizeof(cpptype));
+    std::memcpy(clone, value, sizeof(cpptype));
+    return clone;
+  }
+
+  inline void destroyValue(UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    std::free(value);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
+    return base_.cloneValue(value.getDataPtr());
+  }
+
+  template <typename Functor>
+  inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
+                                             const Functor &functor) const {
+    return functor(value.getDataPtr());
+  }
 
  private:
   template <bool nullable>
@@ -268,16 +251,22 @@ class TypeInstancePolicy<
     static TypeClass instance(nullable);
     return instance;
   }
+
+  const Type &base_;
 };
 
 template <TypeID type_id>
-class TypeInstancePolicy<
+class TypeSynthesizePolicy<
     type_id,
     std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod ||
                      TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
+
+  static_assert(std::is_same<cpptype, TypedValue>::value,
+                "Unexpected cpptype for paramerized PODs.");
 
  public:
   static const TypeClass& InstanceNonNullable(const std::size_t length) {
@@ -301,8 +290,9 @@ class TypeInstancePolicy<
   }
 
  protected:
-  TypeInstancePolicy(const std::size_t length)
-      : length_(length) {}
+  TypeSynthesizePolicy(const Type *base, const std::size_t length)
+      : length_(length),
+        base_(*base) {}
 
   const std::size_t length_;
 
@@ -310,10 +300,38 @@ class TypeInstancePolicy<
     return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_);
   }
 
-  inline void fillProto(serialization::Type *proto) const {
+  inline void mergeIntoProto(serialization::Type *proto) const {
     proto->set_length(length_);
   }
 
+  inline std::size_t getHash() const {
+    return CombineHashes(static_cast<std::size_t>(base_.getTypeID()), length_);
+  }
+
+  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    return new TypedValue(*static_cast<const TypedValue*>(value));
+  }
+
+  inline void destroyValue(UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    delete static_cast<TypedValue*>(value);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
+    return base_.cloneValue(&value);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const {
+    return new TypedValue(std::move(value));
+  }
+
+  template <typename Functor>
+  inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
+                                             const Functor &functor) const {
+    return functor(&value);
+  }
+
  private:
   template <bool nullable>
   inline static const TypeClass& InstanceInternal(const std::size_t length) {
@@ -325,15 +343,18 @@ class TypeInstancePolicy<
     }
     return *(imit->second);
   }
+
+  const Type &base_;
 };
 
 template <TypeID type_id>
-class TypeInstancePolicy<
+class TypeSynthesizePolicy<
     type_id,
     std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
 
  public:
   static const TypeClass& InstanceNonNullable(
@@ -361,29 +382,67 @@ class TypeInstancePolicy<
   }
 
  protected:
-  TypeInstancePolicy(const std::vector<GenericValue> &parameters)
-      : parameters_(parameters) {}
-
-  const std::vector<GenericValue> parameters_;
+  TypeSynthesizePolicy(const Type *base,
+                       const std::vector<GenericValue> &parameters)
+      : parameters_(parameters),
+        base_(*base) {}
 
   inline const Type& getInstance(const bool nullable) const {
     return nullable ? InstanceNullable(parameters_)
                     : InstanceNonNullable(parameters_);
   }
 
-  inline void fillProto(serialization::Type *proto) const {
-    LOG(FATAL) << "TODO";
+  inline void mergeIntoProto(serialization::Type *proto) const {
+    for (const auto &param : parameters_) {
+      proto->add_parameters()->MergeFrom(param.getProto());
+    }
+  }
+
+  inline std::size_t getHash() const {
+    return CombineHashes(static_cast<std::size_t>(base_.getTypeID()),
+                         ParametersHasher::ComputeHash(parameters_));
+  }
+
+  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    return new cpptype(*static_cast<const cpptype*>(value));
+  }
+
+  inline void destroyValue(UntypedLiteral *value) const {
+    DCHECK(value != nullptr);
+    delete static_cast<cpptype*>(value);
   }
 
+  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
+    return base_.unmarshallValue(value.getOutOfLineData(), value.getDataSize());
+  }
+
+  template <typename Functor>
+  inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
+                                             const Functor &functor) const {
+    std::unique_ptr<typename Trait::cpptype> literal(
+        static_cast<typename Trait::cpptype*>(
+            base_.unmarshallValue(value.getOutOfLineData(),
+                                  value.getDataSize())));
+    return functor(literal.get());
+  }
+
+  const std::vector<GenericValue> parameters_;
+
  private:
   struct ParametersHasher {
-    inline std::size_t operator()(const std::vector<GenericValue> &parameters) const {
+    inline static std::size_t ComputeHash(
+        const std::vector<GenericValue> &parameters) {
       std::size_t hash_code = 0;
       for (const GenericValue &value : parameters) {
         hash_code = CombineHashes(hash_code, value.getHash());
       }
       return hash_code;
     }
+    inline std::size_t operator()(
+        const std::vector<GenericValue> &parameters) const {
+      return ComputeHash(parameters);
+    }
   };
 
   template <typename T>
@@ -412,16 +471,18 @@ class TypeInstancePolicy<
     auto imit = instance_map.find(parameters);
     if (imit == instance_map.end()) {
       std::unique_ptr<TypeClass> instance(
-          TypeInstancePolicy<type_id>::template CreateInstance<TypeClass>(
+          TypeSynthesizePolicy<type_id>::template CreateInstance<TypeClass>(
               nullable, parameters));
       imit = instance_map.emplace(parameters, std::move(instance)).first;
     }
     return *(imit->second);
   }
+
+  const Type &base_;
 };
 
 #define QUICKSTEP_SYNTHESIZE_TYPE(type) \
-  template <TypeID, typename> friend class TypeInstancePolicy; \
+  template <TypeID, typename> friend class TypeSynthesizePolicy; \
   DISALLOW_COPY_AND_ASSIGN(type)
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/VarCharType.cpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.cpp b/types/VarCharType.cpp
index f0f677d..6f5f9fb 100644
--- a/types/VarCharType.cpp
+++ b/types/VarCharType.cpp
@@ -103,8 +103,8 @@ void VarCharType::printValueToFile(const UntypedLiteral *value,
                static_cast<const char*>(castValueToLiteral(value).getOutOfLineData()));
 }
 
-bool VarCharType::parseValueFromString(const std::string &value_string,
-                                       TypedValue *value) const {
+bool VarCharType::parseTypedValueFromString(const std::string &value_string,
+                                            TypedValue *value) const {
   if (value_string.length() > length_) {
     return false;
   }
@@ -114,8 +114,8 @@ bool VarCharType::parseValueFromString(const std::string &value_string,
   return true;
 }
 
-TypedValue VarCharType::coerceValue(const TypedValue &original_value,
-                                    const Type &original_type) const {
+TypedValue VarCharType::coerceTypedValue(const TypedValue &original_value,
+                                         const Type &original_type) const {
   DCHECK(isCoercibleFrom(original_type))
       << "Can't coerce value of Type " << original_type.getName()
       << " to Type " << getName();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index 47a2874..0b16061 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -66,11 +66,11 @@ class VarCharType : public AsciiStringSuperType<kVarChar> {
                         FILE *file,
                         const int padding = 0) const override;
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
-  TypedValue coerceValue(const TypedValue &original_value,
-                         const Type &original_type) const override;
+  TypedValue coerceTypedValue(const TypedValue &original_value,
+                              const Type &original_type) const override;
 
  private:
   VarCharType(const bool nullable, const std::size_t length)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/YearMonthIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.cpp b/types/YearMonthIntervalType.cpp
index b395dff..f266bf1 100644
--- a/types/YearMonthIntervalType.cpp
+++ b/types/YearMonthIntervalType.cpp
@@ -116,8 +116,8 @@ std::string YearMonthIntervalType::printValueToString(const UntypedLiteral *valu
   return std::string(interval_buf);
 }
 
-bool YearMonthIntervalType::parseValueFromString(const std::string &value_string,
-                                                 TypedValue *value) const {
+bool YearMonthIntervalType::parseTypedValueFromString(const std::string &value_string,
+                                                      TypedValue *value) const {
   // Try simple-format parse first.
   std::int64_t count;
   std::string units;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index ab06911..ee1eb97 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -52,8 +52,8 @@ class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
     return TypedValue(YearMonthIntervalLit{0});
   }
 
-  bool parseValueFromString(const std::string &value_string,
-                            TypedValue *value) const override;
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override;
 
  private:
   explicit YearMonthIntervalType(const bool nullable)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/operations/OperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.cpp b/types/operations/OperationFactory.cpp
index 531318b..253a75d 100644
--- a/types/operations/OperationFactory.cpp
+++ b/types/operations/OperationFactory.cpp
@@ -24,11 +24,11 @@
 #include <string>
 #include <vector>
 
+#include "types/GenericValue.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypeUtil.hpp"
-#include "types/TypedValue.hpp"
 #include "types/operations/Operation.hpp"
 #include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/ArithmeticBinaryOperations.hpp"
@@ -68,6 +68,16 @@ struct FunctorPackDispatcher {
   }
 };
 
+// TODO(refactor-type): Remove this.
+inline static std::shared_ptr<const std::vector<TypedValue>> ToTypedValue(
+    const std::vector<GenericValue> &input) {
+  std::vector<TypedValue> values;
+  for (const auto &item : input) {
+    values.emplace_back(item.toTypedValue());
+  }
+  return std::make_shared<const std::vector<TypedValue>>(std::move(values));
+}
+
 }  // namespace
 
 OperationFactory::OperationFactory() {
@@ -87,9 +97,9 @@ OperationFactory::OperationFactory() {
 OperationSignaturePtr OperationFactory::resolveOperation(
     const std::string &operation_name,
     const std::shared_ptr<const std::vector<const Type*>> &argument_types,
-    const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+    const std::shared_ptr<const std::vector<GenericValue>> &static_arguments,
     std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
-    std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+    std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
     std::string *message) const {
   const std::string lower_case_name = ToLower(operation_name);
   const std::size_t arity = argument_types->size();
@@ -151,8 +161,8 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMa
     const PartialSignatureIndex &secondary_index,
     const std::vector<TypeID> &argument_type_ids,
     const std::vector<const Type*> &argument_types,
-    const std::vector<TypedValue> &static_arguments,
-    std::shared_ptr<const std::vector<TypedValue>> *partial_static_arguments,
+    const std::vector<GenericValue> &static_arguments,
+    std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
     OperationSignaturePtr *resolved_op_signature,
     std::string *message) const {
   const std::size_t max_num_static_arguments = static_arguments.size();
@@ -163,15 +173,15 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMa
     const OperationSignaturePtr op_signature = it->second;
     const OperationPtr operation = getOperation(op_signature);
 
-    *partial_static_arguments =
-        std::make_shared<const std::vector<TypedValue>>(
+    *coerced_static_arguments =
+        std::make_shared<const std::vector<GenericValue>>(
             static_arguments.begin()
                 + (max_num_static_arguments - op_signature->getNumStaticArguments()),
             static_arguments.end());
 
     if (canApplyOperationTo(operation,
                             argument_types,
-                            **partial_static_arguments,
+                            **coerced_static_arguments,
                             message)) {
       *resolved_op_signature = op_signature;
       return ResolveStatus::kSuccess;
@@ -187,9 +197,9 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
     const PartialSignatureIndex &secondary_index,
     const std::vector<TypeID> &argument_type_ids,
     const std::vector<const Type*> &argument_types,
-    const std::vector<TypedValue> &static_arguments,
+    const std::vector<GenericValue> &static_arguments,
     std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
-    std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+    std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
     OperationSignaturePtr *resolved_op_signature,
     std::string *message) const {
   const std::size_t arity = argument_types.size();
@@ -211,18 +221,16 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
     }
 
     // Coerce static arguments
-    std::vector<const Type*> coerced_static_arg_types;
-    std::vector<TypedValue> coerced_static_args;
+    std::vector<GenericValue> coerced_static_args;
 
     bool is_coercible = true;
     for (std::size_t i = num_non_static_arguments; i < arity; ++i) {
       const Type &arg_type = *argument_types.at(i);
-      const TypedValue &arg_value =
+      const GenericValue &arg_value =
           static_arguments.at(i - first_static_argument_position);
       const TypeID &expected_type_id = expected_type_ids.at(i);
 
       if (arg_type.getTypeID() == expected_type_id) {
-        coerced_static_arg_types.emplace_back(&arg_type);
         coerced_static_args.emplace_back(arg_value);
       } else {
         const Type *expected_type = nullptr;
@@ -240,9 +248,7 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
         }
 
         if (expected_type != nullptr && expected_type->isSafelyCoercibleFrom(arg_type)) {
-          coerced_static_arg_types.emplace_back(expected_type);
-          coerced_static_args.emplace_back(
-              expected_type->coerceValue(arg_value, arg_type));
+          coerced_static_args.emplace_back(arg_value.coerce(*expected_type));
         } else {
           is_coercible = false;
           break;
@@ -254,8 +260,8 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
       std::vector<const Type*> coerced_arg_types(
           argument_types.begin(),
           argument_types.begin() + num_non_static_arguments);
-      for (const Type *type : coerced_static_arg_types) {
-        coerced_arg_types.emplace_back(type);
+      for (const auto &value : coerced_static_args) {
+        coerced_arg_types.emplace_back(&value.getType());
       }
 
       const OperationPtr operation = getOperation(it->second);
@@ -266,7 +272,7 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
         *coerced_argument_types =
             std::make_shared<const std::vector<const Type*>>(std::move(coerced_arg_types));
         *coerced_static_arguments =
-            std::make_shared<const std::vector<TypedValue>>(std::move(coerced_static_args));
+            std::make_shared<const std::vector<GenericValue>>(std::move(coerced_static_args));
         *resolved_op_signature = it->second;
         return ResolveStatus::kSuccess;
       }
@@ -281,14 +287,14 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
 bool OperationFactory::canApplyOperationTo(
     const OperationPtr operation,
     const std::vector<const Type*> &argument_types,
-    const std::vector<TypedValue> &static_arguments,
+    const std::vector<GenericValue> &static_arguments,
     std::string *message) const {
   switch (operation->getOperationSuperTypeID()) {
     case Operation::kUnaryOperation: {
       const UnaryOperationPtr unary_operation =
           std::static_pointer_cast<const UnaryOperation>(operation);
       return unary_operation->canApplyTo(*argument_types[0],
-                                         static_arguments,
+                                         *ToTypedValue(static_arguments),
                                          message);
     }
     case Operation::kBinaryOperation: {
@@ -296,7 +302,7 @@ bool OperationFactory::canApplyOperationTo(
           std::static_pointer_cast<const BinaryOperation>(operation);
       return binary_operation->canApplyTo(*argument_types[0],
                                           *argument_types[1],
-                                          static_arguments,
+                                          *ToTypedValue(static_arguments),
                                           message);
     }
     default: {


[31/38] incubator-quickstep git commit: Add text type

Posted by ji...@apache.org.
Add text type


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/93c6b7a1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/93c6b7a1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/93c6b7a1

Branch: refs/heads/refactor-type
Commit: 93c6b7a17333d17f75683b96fa9595b516f98e9d
Parents: eb156fd
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Tue Oct 3 17:03:20 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 types/ArrayType.cpp                             |  29 ++++
 types/ArrayType.hpp                             |  25 ++-
 types/CMakeLists.txt                            |  39 ++++-
 types/MetaType.cpp                              |  46 +++++
 types/MetaTypeLite.cpp                          |  11 +-
 types/MetaTypeLite.hpp                          |   4 +
 types/TextType.cpp                              |  50 ++++++
 types/TextType.hpp                              |  73 ++++++++
 types/TypeFactory.cpp                           | 136 ---------------
 types/TypeFactory.hpp                           | 110 +-----------
 types/TypeFactoryLite.cpp                       | 170 +++++++++++++++++++
 types/TypeFactoryLite.hpp                       | 141 +++++++++++++++
 types/TypeID.cpp                                |   1 +
 types/TypeID.hpp                                |   1 +
 types/TypeRegistrar.hpp                         |   3 +
 types/TypeSynthesizer.hpp                       |  20 +--
 types/TypeUtil.hpp                              |  11 +-
 .../unary_operations/CastOperation.hpp          |   5 -
 18 files changed, 602 insertions(+), 273 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
index df2b9de..30cc4a5 100644
--- a/types/ArrayType.cpp
+++ b/types/ArrayType.cpp
@@ -29,6 +29,35 @@
 
 namespace quickstep {
 
+std::string ArrayType::getName() const {
+  std::string name("Array(");
+  name.append(element_type_.getName());
+  name.push_back(')');
+  if (nullable_) {
+    name.append(" NULL");
+  }
+  return name;
+}
+
+bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs,
+                                 const UntypedLiteral *rhs,
+                                 const Type &rhs_type) const {
+  if (!equals(rhs_type)) {
+    return false;
+  }
+  const ArrayLiteral &lhs_array = castValueToLiteral(lhs);
+  const ArrayLiteral &rhs_array = castValueToLiteral(rhs);
+  if (lhs_array.size() != rhs_array.size()) {
+    return false;
+  }
+  for (std::size_t i = 0; i < lhs_array.size(); ++i) {
+    if (!element_type_.checkValuesEqual(lhs_array.at(i), rhs_array.at(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
 TypedValue ArrayType::marshallValue(const UntypedLiteral *value) const {
   const ArrayLiteral &array = *static_cast<const ArrayLiteral*>(value);
   serialization::ArrayLiteral proto;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
index a48cfa3..f7e2212 100644
--- a/types/ArrayType.hpp
+++ b/types/ArrayType.hpp
@@ -25,6 +25,7 @@
 
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "types/TypeSynthesizer.hpp"
 #include "utility/Macros.hpp"
 
@@ -41,9 +42,15 @@ class TypedValue;
 class ArrayType : public TypeSynthesizer<kArray> {
  public:
   int getPrintWidth() const override {
-    return 16;
+    return 32;
   }
 
+  std::string getName() const override;
+
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override;
+
   TypedValue marshallValue(const UntypedLiteral *value) const override;
 
   UntypedLiteral* unmarshallValue(const void *data,
@@ -76,6 +83,22 @@ class ArrayType : public TypeSynthesizer<kArray> {
   QUICKSTEP_SYNTHESIZE_TYPE(ArrayType);
 };
 
+
+template <TypeID type_id, TypeID element_type_id>
+class FirstOrderArrayType {
+ public:
+
+
+ private:
+
+  QUICKSTEP_SYNTHESIZE_TYPE(FirstOrderArrayType);
+};
+
+
+
+
+
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 69ac906..d4bc26e 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -56,9 +56,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_NumericTypeSafeCoercibility ../empty_src.cpp NumericTypeSafeCoercibility.hpp)
 add_library(quickstep_types_NumericTypeUnifier ../empty_src.cpp NumericTypeUnifier.hpp)
+add_library(quickstep_types_TextType TextType.cpp TextType.hpp)
 add_library(quickstep_types_Type Type.cpp Type.hpp)
 add_library(quickstep_types_TypeErrors ../empty_src.cpp TypeErrors.hpp)
-add_library(quickstep_types_TypeFactory TypeFactory.cpp TypeFactory.hpp)
+add_library(quickstep_types_TypeFactory ../empty_src.cpp TypeFactory.hpp)
+add_library(quickstep_types_TypeFactoryLite TypeFactoryLite.cpp TypeFactoryLite.hpp)
 add_library(quickstep_types_TypeID TypeID.cpp TypeID.hpp)
 add_library(quickstep_types_TypeIDSelectors ../empty_src.cpp TypeIDSelectors.hpp)
 add_library(quickstep_types_TypeRegistrar ../empty_src.cpp TypeRegistrar.hpp)
@@ -146,6 +148,14 @@ target_link_libraries(quickstep_types_FloatType
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_types_GenericValue
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_Type_proto
+                      quickstep_types_TypedValue
+                      quickstep_utility_HashPair
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_types_IntType
                       glog
                       quickstep_types_NumericSuperType
@@ -165,7 +175,9 @@ target_link_libraries(quickstep_types_LongType
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_MetaType
-                      quickstep_types_MetaTypeLite)
+                      quickstep_types_MetaTypeLite
+                      quickstep_types_TypeFactoryLite
+                      quickstep_types_Type_proto)
 target_link_libraries(quickstep_types_MetaTypeLite
                       quickstep_types_Type
                       quickstep_types_TypeID
@@ -191,19 +203,30 @@ target_link_libraries(quickstep_types_NumericTypeSafeCoercibility
                       quickstep_utility_meta_TMP)
 target_link_libraries(quickstep_types_NumericTypeUnifier
                       quickstep_types_NumericTypeSafeCoercibility)
+target_link_libraries(quickstep_types_TextType
+                      quickstep_types_TextType
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
+                      quickstep_types_TypedValue
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_types_Type
                       glog
                       quickstep_types_Type_proto
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_TypeFactory
+target_link_libraries(quickstep_types_TypeFactoryLite
                       glog
+                      quickstep_types_GenericValue
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeUtil
                       quickstep_types_Type_proto
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_types_TypeFactory
+                      quickstep_types_MetaType
+                      quickstep_types_TypeFactoryLite)
 target_link_libraries(quickstep_types_TypeID
                       quickstep_types_Type_proto
                       quickstep_utility_Macros)
@@ -213,6 +236,7 @@ target_link_libraries(quickstep_types_TypeIDSelectors
 target_link_libraries(quickstep_types_TypeRegistrar
                       quickstep_types_DatetimeLit
                       quickstep_types_IntervalLit
+                      quickstep_types_NullLit
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeIDSelectors
@@ -229,6 +253,7 @@ target_link_libraries(quickstep_types_TypeSynthesizer
                       quickstep_utility_PtrMap
                       quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_TypeUtil
+                      quickstep_types_ArrayType
                       quickstep_types_BoolType
                       quickstep_types_CharType
                       quickstep_types_DateType
@@ -240,6 +265,7 @@ target_link_libraries(quickstep_types_TypeUtil
                       quickstep_types_LongType
                       quickstep_types_MetaTypeLite
                       quickstep_types_NullType
+                      quickstep_types_TextType
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeRegistrar
@@ -286,6 +312,7 @@ target_link_libraries(quickstep_types_YearMonthIntervalType
 # Module all-in-one library:
 add_library(quickstep_types ../empty_src.cpp TypesModule.hpp)
 target_link_libraries(quickstep_types
+                      quickstep_types_ArrayType
                       quickstep_types_AsciiStringSuperType
                       quickstep_types_BoolType
                       quickstep_types_CharType
@@ -296,20 +323,26 @@ target_link_libraries(quickstep_types
                       quickstep_types_DatetimeType
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
+                      quickstep_types_GenericValue
                       quickstep_types_IntType
                       quickstep_types_IntervalLit
                       quickstep_types_IntervalParser
                       quickstep_types_LongType
+                      quickstep_types_MetaType
+                      quickstep_types_MetaTypeLite
                       quickstep_types_NullCoercibilityCheckMacro
+                      quickstep_types_NullLit
                       quickstep_types_NullType
                       quickstep_types_NumericSuperType
                       quickstep_types_NumericTypeSafeCoercibility
                       quickstep_types_NumericTypeUnifier
+                      quickstep_types_TextType
                       quickstep_types_Type
                       quickstep_types_TypeUtil
                       quickstep_types_Type_proto
                       quickstep_types_TypeErrors
                       quickstep_types_TypeFactory
+                      quickstep_types_TypeFactoryLite
                       quickstep_types_TypeID
                       quickstep_types_TypeIDSelectors
                       quickstep_types_TypeRegistrar

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/MetaType.cpp
----------------------------------------------------------------------
diff --git a/types/MetaType.cpp b/types/MetaType.cpp
index e69de29..f6e44ba 100644
--- a/types/MetaType.cpp
+++ b/types/MetaType.cpp
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/MetaType.hpp"
+
+#include <cstddef>
+#include <string>
+
+#include "types/Type.pb.h"
+#include "types/TypeFactoryLite.hpp"
+
+namespace quickstep {
+
+bool MetaType::checkValuesEqual(const UntypedLiteral *lhs,
+                                const UntypedLiteral *rhs,
+                                const Type &rhs_type) const {
+  if (!equals(rhs_type)) {
+    return false;
+  }
+  return castValueToLiteral(lhs)->equals(*castValueToLiteral(rhs));
+}
+
+UntypedLiteral* MetaType::unmarshallValue(const void *data,
+                                          const std::size_t data_size) const {
+  serialization::Type proto;
+  proto.ParseFromArray(data, data_size);
+  return new MetaTypeLiteral(&TypeFactory::ReconstructFromProto(proto));
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/MetaTypeLite.cpp
----------------------------------------------------------------------
diff --git a/types/MetaTypeLite.cpp b/types/MetaTypeLite.cpp
index 8022534..830f364 100644
--- a/types/MetaTypeLite.cpp
+++ b/types/MetaTypeLite.cpp
@@ -17,11 +17,13 @@
  * under the License.
  **/
 
-#include "types/MetaType.hpp"
+#include "types/MetaTypeLite.hpp"
 
+#include <cstddef>
 #include <string>
 
 #include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
 
 #include "glog/logging.h"
 
@@ -36,13 +38,6 @@ TypedValue MetaType::marshallValue(const UntypedLiteral *value) const {
   return TypedValue::CreateWithOwnedData(kMetaType, data, data_size);
 }
 
-//UntypedLiteral* MetaType::unmarshallValue(const void *data,
-//                                          const std::size_t data_size) const {
-//  serialization::Type proto;
-//  proto.ParseFromArray(data, data_size);
-//  return
-//}
-
 std::string MetaType::printValueToString(const UntypedLiteral *value) const {
   DCHECK(value != nullptr);
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/MetaTypeLite.hpp
----------------------------------------------------------------------
diff --git a/types/MetaTypeLite.hpp b/types/MetaTypeLite.hpp
index 776fe03..09f879f 100644
--- a/types/MetaTypeLite.hpp
+++ b/types/MetaTypeLite.hpp
@@ -44,6 +44,10 @@ class MetaType : public TypeSynthesizer<kMetaType> {
     return 16;
   }
 
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override;
+
   TypedValue marshallValue(const UntypedLiteral *value) const override;
 
   UntypedLiteral* unmarshallValue(const void *data,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TextType.cpp
----------------------------------------------------------------------
diff --git a/types/TextType.cpp b/types/TextType.cpp
new file mode 100644
index 0000000..ce5c3a5
--- /dev/null
+++ b/types/TextType.cpp
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/TextType.hpp"
+
+#include <cstddef>
+#include <string>
+
+namespace quickstep {
+
+bool TextType::checkValuesEqual(const UntypedLiteral *lhs,
+                                const UntypedLiteral *rhs,
+                                const Type &rhs_type) const {
+  if (!equals(rhs_type)) {
+    return false;
+  }
+  return castValueToLiteral(lhs) == castValueToLiteral(rhs);
+}
+
+TypedValue TextType::marshallValue(const UntypedLiteral *value) const {
+  const std::string &str = castValueToLiteral(value);
+  return TypedValue(kText, str.c_str(), str.length()).ensureNotReference();
+}
+
+UntypedLiteral* TextType::unmarshallValue(const void *data,
+                                          const std::size_t length) const {
+  return new std::string(static_cast<const char*>(data), length);
+}
+
+std::string TextType::printValueToString(const UntypedLiteral *value) const {
+  return castValueToLiteral(value);
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TextType.hpp
----------------------------------------------------------------------
diff --git a/types/TextType.hpp b/types/TextType.hpp
new file mode 100644
index 0000000..9ceea35
--- /dev/null
+++ b/types/TextType.hpp
@@ -0,0 +1,73 @@
+/**
+ * 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_TEXT_TYPE_HPP_
+#define QUICKSTEP_TYPES_TEXT_TYPE_HPP_
+
+#include <cstddef>
+#include <cstdio>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+#include "types/TypedValue.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class TextType : public TypeSynthesizer<kText> {
+ public:
+  int getPrintWidth() const override {
+    return 32;
+  }
+
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override;
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override;
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override;
+
+  std::string printValueToString(const UntypedLiteral *value) const override;
+
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
+    return false;
+  }
+
+ private:
+  TextType(const bool nullable)
+      : TypeSynthesizer<kText>(nullable, 0, 0x1000) {
+    // TODO(refactor-type): Possibly infinite maximum size.
+  }
+
+  QUICKSTEP_SYNTHESIZE_TYPE(TextType);
+};
+
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_TEXT_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index d60f701..e69de29 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -1,136 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/TypeFactory.hpp"
-
-#include <cstddef>
-#include <string>
-
-#include "types/GenericValue.hpp"
-#include "types/Type.hpp"
-#include "types/Type.pb.h"
-#include "types/TypeID.hpp"
-#include "types/TypeUtil.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
-  return TypeUtil::IsParameterizedPod(id);
-}
-
-const Type& TypeFactory::GetType(const TypeID id,
-                                 const bool nullable) {
-  DCHECK(!TypeRequiresLengthParameter(id))
-      << "Called TypeFactory::GetType() for a type which requires "
-      << " a length parameter without specifying one.";
-
-  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxInlinePod>>(
-      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) {
-  DCHECK(TypeRequiresLengthParameter(id))
-      << "Provided a length parameter to TypeFactory::GetType() for "
-      << "a type which does not take one.";
-
-  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kParInlinePod, kParOutOfLinePod>>(
-      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) {
-  // Check that proto is fully initialized.
-  if (!proto.IsInitialized()) {
-    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) {
-  DCHECK(ProtoIsValid(proto))
-      << "Attempted to create Type from an invalid proto description:\n"
-      << proto.DebugString();
-
-  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());
-  }
-}
-
-const Type* TypeFactory::GetMostSpecificType(const Type &first, const Type &second) {
-  if (first.isSafelyCoercibleFrom(second)) {
-    return &first;
-  } else if (second.isSafelyCoercibleFrom(first)) {
-    return &second;
-  } else {
-    return nullptr;
-  }
-}
-
-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());
-    if (unifier == nullptr) {
-      if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
-            || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
-        unifier = &(DoubleType::Instance(true));
-      }
-    }
-  } else {
-    unifier = GetMostSpecificType(first, second);
-    if (unifier == nullptr) {
-      if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
-            || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
-        unifier = &(DoubleType::Instance(false));
-      }
-    }
-  }
-
-  return unifier;
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeFactory.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.hpp b/types/TypeFactory.hpp
index 89ff497..3992b6c 100644
--- a/types/TypeFactory.hpp
+++ b/types/TypeFactory.hpp
@@ -20,113 +20,7 @@
 #ifndef QUICKSTEP_TYPES_TYPE_FACTORY_HPP_
 #define QUICKSTEP_TYPES_TYPE_FACTORY_HPP_
 
-#include <cstddef>
-
-#include "types/TypeID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-
-namespace serialization { class Type; }
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief All-static factory object that provides access to Types, as well as
- *        methods for determining coercibility of Types.
- **/
-class TypeFactory {
- public:
-  /**
-   * @brief Determine if a length parameter is required when getting a Type of
-   *        the specified TypeID.
-   *
-   * @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);
-
-  /**
-   * @brief Factory method to get a Type by its TypeID.
-   * @note This version is for Types without a length parameter (currently
-   *       IntType, LongType, FloatType, and DoubleType). It is an error to
-   *       call this with a Type which requires a length parameter.
-   *
-   * @param id The id of the desired Type.
-   * @param nullable Whether to get the nullable version of the Type.
-   * @return The Type corresponding to id.
-   **/
-  static const Type& GetType(const TypeID id, const bool nullable = false);
-
-  /**
-   * @brief Factory method to get a Type by its TypeID and length.
-   * @note This version is for Types with a length parameter (currently
-   *       CharType and VarCharType). It is an error to call this with a Type
-   *       which does not require a length parameter.
-   *
-   * @param id The id of the desired Type.
-   * @param length The length parameter of the desired Type.
-   * @param nullable Whether to get the nullable version of the Type.
-   * @return The Type corresponding to id and length.
-   **/
-  static const Type& GetType(const TypeID id, const std::size_t length, const bool nullable = false);
-
-  /**
-   * @brief Get a reference to a Type from that Type's serialized Protocol Buffer
-   *        representation.
-   *
-   * @param proto A serialized Protocol Buffer representation of a Type,
-   *        originally generated by getProto().
-   * @return The Type described by proto.
-   **/
-  static const Type& ReconstructFromProto(const serialization::Type &proto);
-
-  /**
-   * @brief Check whether a serialization::Type is fully-formed and
-   *        all parts are valid.
-   *
-   * @param proto A serialized Protocol Buffer representation of a Type,
-   *        originally generated by getProto().
-   * @return Whether proto is fully-formed and valid.
-   **/
-  static bool ProtoIsValid(const serialization::Type &proto);
-
-  /**
-   * @brief Determine which of two types is most specific, i.e. which
-   *        isSafelyCoercibleFrom() the other.
-   *
-   * @param first The first type to check.
-   * @param second The second type to check.
-   * @return The most precise type, or NULL if neither Type
-   *         isSafelyCoercibleFrom() the other.
-   **/
-  static const Type* GetMostSpecificType(const Type &first, const Type &second);
-
-  /**
-   * @brief Determine a type, if any exists, which both arguments can be safely
-   *        coerced to. It is possible that the resulting type may not be
-   *        either argument.
-   *
-   * @param first The first type to check.
-   * @param second The second type to check.
-   * @return The unifying type, or NULL if none exists.
-   **/
-  static const Type* GetUnifyingType(const Type &first, const Type &second);
-
- private:
-  // Undefined default constructor. Class is all-static and should not be
-  // instantiated.
-  TypeFactory();
-
-  DISALLOW_COPY_AND_ASSIGN(TypeFactory);
-};
-
-/** @} */
-
-}  // namespace quickstep
+#include "types/MetaType.hpp"
+#include "types/TypeFactoryLite.hpp"
 
 #endif  // QUICKSTEP_TYPES_TYPE_FACTORY_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeFactoryLite.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactoryLite.cpp b/types/TypeFactoryLite.cpp
new file mode 100644
index 0000000..c7c6b3b
--- /dev/null
+++ b/types/TypeFactoryLite.cpp
@@ -0,0 +1,170 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/TypeFactoryLite.hpp"
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "types/GenericValue.hpp"
+#include "types/Type.hpp"
+#include "types/Type.pb.h"
+#include "types/TypeID.hpp"
+#include "types/TypeUtil.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
+  return TypeUtil::IsParameterizedPod(id);
+}
+
+const Type& TypeFactory::GetType(const TypeID id,
+                                 const bool nullable) {
+  DCHECK(TypeUtil::GetMemoryLayout(id) == kCxxInlinePod)
+      << "Called TypeFactory::GetType() with incorrect parameters.";
+
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxInlinePod>>(
+      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) {
+  DCHECK(TypeRequiresLengthParameter(id))
+      << "Called TypeFactory::GetType() with incorrect parameters.";
+
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kParInlinePod, kParOutOfLinePod>>(
+      id,
+      [&](auto id) -> const Type* {  // NOLINT(build/c++11)
+    return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, length);
+  });
+}
+
+const Type& TypeFactory::GetType(const TypeID id,
+                                 const std::vector<GenericValue> &parameters,
+                                 const bool nullable) {
+  DCHECK(TypeUtil::GetMemoryLayout(id) == kCxxGeneric)
+      << "Called TypeFactory::GetType() with incorrect parameters.";
+
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxGeneric>>(
+      id,
+      [&](auto id) -> const Type* {  // NOLINT(build/c++11)
+    return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, parameters);
+  });
+}
+
+bool TypeFactory::ProtoIsValid(const serialization::Type &proto) {
+  // Check that proto is fully initialized.
+  if (!proto.IsInitialized()) {
+    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) {
+  DCHECK(ProtoIsValid(proto))
+      << "Attempted to create Type from an invalid proto description:\n"
+      << proto.DebugString();
+
+  const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
+
+  switch (TypeUtil::GetMemoryLayout(type_id)) {
+    case kCxxInlinePod:
+      return GetType(type_id, proto.nullable());
+    case kParInlinePod:  // Fall through
+    case kParOutOfLinePod:
+      return GetType(type_id, proto.length(), proto.nullable());
+    case kCxxGeneric: {
+      std::vector<GenericValue> parameters;
+      for (int i = 0; i < proto.parameters_size(); ++i) {
+        parameters.emplace_back(ReconstructValueFromProto(proto.parameters(i)));
+      }
+      return GetType(type_id, parameters, proto.nullable());
+    }
+  }
+}
+
+GenericValue TypeFactory::ReconstructValueFromProto(
+    const serialization::GenericValue &proto) {
+  const Type &type = ReconstructFromProto(proto.type());
+  if (proto.has_data()) {
+    return GenericValue(type,
+                        type.unmarshallValue(proto.data().c_str(),
+                                             proto.data().size()),
+                        true /* take_ownership */);
+  } else {
+    return GenericValue(type);
+  }
+}
+
+const Type* TypeFactory::GetMostSpecificType(const Type &first, const Type &second) {
+  if (first.isSafelyCoercibleFrom(second)) {
+    return &first;
+  } else if (second.isSafelyCoercibleFrom(first)) {
+    return &second;
+  } else {
+    return nullptr;
+  }
+}
+
+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());
+    if (unifier == nullptr) {
+      if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
+            || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
+        unifier = &(DoubleType::Instance(true));
+      }
+    }
+  } else {
+    unifier = GetMostSpecificType(first, second);
+    if (unifier == nullptr) {
+      if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
+            || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
+        unifier = &(DoubleType::Instance(false));
+      }
+    }
+  }
+
+  return unifier;
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeFactoryLite.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactoryLite.hpp b/types/TypeFactoryLite.hpp
new file mode 100644
index 0000000..eeafbf2
--- /dev/null
+++ b/types/TypeFactoryLite.hpp
@@ -0,0 +1,141 @@
+/**
+ * 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_FACTORY_LITE_HPP_
+#define QUICKSTEP_TYPES_TYPE_FACTORY_LITE_HPP_
+
+#include <cstddef>
+
+#include "types/GenericValue.hpp"
+#include "types/TypeID.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+class Type;
+
+namespace serialization { class Type; }
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief All-static factory object that provides access to Types, as well as
+ *        methods for determining coercibility of Types.
+ **/
+class TypeFactory {
+ public:
+  /**
+   * @brief Determine if a length parameter is required when getting a Type of
+   *        the specified TypeID.
+   *
+   * @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);
+
+  /**
+   * @brief Factory method to get a Type by its TypeID.
+   * @note This version is for Types without a length parameter (currently
+   *       IntType, LongType, FloatType, and DoubleType). It is an error to
+   *       call this with a Type which requires a length parameter.
+   *
+   * @param id The id of the desired Type.
+   * @param nullable Whether to get the nullable version of the Type.
+   * @return The Type corresponding to id.
+   **/
+  static const Type& GetType(const TypeID id, const bool nullable = false);
+
+  /**
+   * @brief Factory method to get a Type by its TypeID and length.
+   * @note This version is for Types with a length parameter (currently
+   *       CharType and VarCharType). It is an error to call this with a Type
+   *       which does not require a length parameter.
+   *
+   * @param id The id of the desired Type.
+   * @param length The length parameter of the desired Type.
+   * @param nullable Whether to get the nullable version of the Type.
+   * @return The Type corresponding to id and length.
+   **/
+  static const Type& GetType(const TypeID id,
+                             const std::size_t length,
+                             const bool nullable = false);
+
+  static const Type& GetType(const TypeID id,
+                             const std::vector<GenericValue> &parameters,
+                             const bool nullable = false);
+
+  /**
+   * @brief Get a reference to a Type from that Type's serialized Protocol Buffer
+   *        representation.
+   *
+   * @param proto A serialized Protocol Buffer representation of a Type,
+   *        originally generated by getProto().
+   * @return The Type described by proto.
+   **/
+  static const Type& ReconstructFromProto(const serialization::Type &proto);
+
+  static GenericValue ReconstructValueFromProto(const serialization::GenericValue &proto);
+
+  /**
+   * @brief Check whether a serialization::Type is fully-formed and
+   *        all parts are valid.
+   *
+   * @param proto A serialized Protocol Buffer representation of a Type,
+   *        originally generated by getProto().
+   * @return Whether proto is fully-formed and valid.
+   **/
+  static bool ProtoIsValid(const serialization::Type &proto);
+
+  /**
+   * @brief Determine which of two types is most specific, i.e. which
+   *        isSafelyCoercibleFrom() the other.
+   *
+   * @param first The first type to check.
+   * @param second The second type to check.
+   * @return The most precise type, or NULL if neither Type
+   *         isSafelyCoercibleFrom() the other.
+   **/
+  static const Type* GetMostSpecificType(const Type &first, const Type &second);
+
+  /**
+   * @brief Determine a type, if any exists, which both arguments can be safely
+   *        coerced to. It is possible that the resulting type may not be
+   *        either argument.
+   *
+   * @param first The first type to check.
+   * @param second The second type to check.
+   * @return The unifying type, or NULL if none exists.
+   **/
+  static const Type* GetUnifyingType(const Type &first, const Type &second);
+
+ private:
+  // Undefined default constructor. Class is all-static and should not be
+  // instantiated.
+  TypeFactory();
+
+  DISALLOW_COPY_AND_ASSIGN(TypeFactory);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_TYPE_FACTORY_LITE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeID.cpp
----------------------------------------------------------------------
diff --git a/types/TypeID.cpp b/types/TypeID.cpp
index ce29455..08c619a 100644
--- a/types/TypeID.cpp
+++ b/types/TypeID.cpp
@@ -33,6 +33,7 @@ const char *kTypeNames[] = {
   "Datetime",
   "DatetimeInterval",
   "YearMonthInterval",
+  "Text",
   "Array",
   "MetaType",
   "NullType"

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeID.hpp
----------------------------------------------------------------------
diff --git a/types/TypeID.hpp b/types/TypeID.hpp
index 8203253..13e0e3c 100644
--- a/types/TypeID.hpp
+++ b/types/TypeID.hpp
@@ -54,6 +54,7 @@ enum TypeID {
   kDatetime,
   kDatetimeInterval,
   kYearMonthInterval,
+  kText,
   kArray,
   kMetaType,
   kNullType,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
index 9e6c50b..3a25226 100644
--- a/types/TypeRegistrar.hpp
+++ b/types/TypeRegistrar.hpp
@@ -22,6 +22,7 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <string>
 #include <type_traits>
 #include <vector>
 
@@ -85,6 +86,8 @@ REGISTER_TYPE(CharType, kChar,
               SuperTypeID::kAsciiString, kParInlinePod, TypedValue);
 REGISTER_TYPE(VarCharType, kVarChar,
               SuperTypeID::kAsciiString, kParOutOfLinePod, TypedValue);
+REGISTER_TYPE(TextType, kText,
+              SuperTypeID::kOther, kCxxGeneric, std::string);
 REGISTER_TYPE(ArrayType, kArray,
               SuperTypeID::kOther, kCxxGeneric, ArrayLiteral);
 REGISTER_TYPE(MetaType, kMetaType,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index 29267f8..f0761d1 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -338,9 +338,7 @@ class TypeSynthesizePolicy<
   bool checkValuesEqual(const UntypedLiteral *lhs,
                         const UntypedLiteral *rhs,
                         const Type &rhs_type) const override {
-    // LOG(FATAL) << "Not implemented";
-    // TODO.
-    return false;
+    LOG(FATAL) << "Not implemented";
   }
 
   UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
@@ -358,14 +356,14 @@ class TypeSynthesizePolicy<
     return util::Hash(static_cast<const char*>(value), sizeof(cpptype));
   }
 
-  TypedValue marshallValue(const UntypedLiteral *value) const override {
-    LOG(FATAL) << "Not implemented";
-  }
-
-  UntypedLiteral* unmarshallValue(const void *data,
-                                  const std::size_t length) const override {
-    LOG(FATAL) << "Not implemented";
-  }
+//  TypedValue marshallValue(const UntypedLiteral *value) const override {
+//    LOG(FATAL) << "Not implemented";
+//  }
+//
+//  UntypedLiteral* unmarshallValue(const void *data,
+//                                  const std::size_t length) const override {
+//    LOG(FATAL) << "Not implemented";
+//  }
 
  protected:
   TypeSynthesizePolicy(const bool nullable,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
index 3b16c70..52fe9ae 100644
--- a/types/TypeUtil.hpp
+++ b/types/TypeUtil.hpp
@@ -32,8 +32,9 @@
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
-#include "types/MetaType.hpp"
+#include "types/MetaTypeLite.hpp"
 #include "types/NullType.hpp"
+#include "types/TextType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypeRegistrar.hpp"
@@ -51,6 +52,14 @@ namespace quickstep {
 
 class TypeUtil {
  public:
+  static MemoryLayout GetMemoryLayout(const TypeID type_id) {
+    return InvokeOnTypeID(
+        type_id,
+        [&](auto tid) -> MemoryLayout {  // NOLINT(build/c++11)
+      return TypeIDTrait<decltype(tid)::value>::kMemoryLayout;
+    });
+  }
+
   static bool IsParameterizedPod(const TypeID type_id) {
     return InvokeOnTypeID(
         type_id,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/93c6b7a1/types/operations/unary_operations/CastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp
index 7270dec..c0d3357 100644
--- a/types/operations/unary_operations/CastOperation.hpp
+++ b/types/operations/unary_operations/CastOperation.hpp
@@ -106,11 +106,6 @@ class CastOperation : public UnaryOperation {
     const std::string type_str =
         ToLower(std::string(static_cast<const char*>(type_arg.getOutOfLineData())));
 
-    if (type_str == "text") {
-      return &TypeFactory::GetType(
-          kVarChar, type.getPrintWidth(), type.isNullable());
-    }
-
     const re2::StringPiece type_piece(type_str);
     std::string type_name;
     std::string length_str;



[02/38] incubator-quickstep git commit: Updates to casts

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/OperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.cpp b/types/operations/OperationFactory.cpp
index 74cc3c1..df536ed 100644
--- a/types/operations/OperationFactory.cpp
+++ b/types/operations/OperationFactory.cpp
@@ -33,7 +33,7 @@
 #include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/ArithmeticBinaryFunctors.hpp"
 #include "types/operations/binary_operations/AsciiStringBinaryFunctors.hpp"
-#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "types/operations/binary_operations/BinaryOperationSynthesizer.hpp"
 #include "types/operations/binary_operations/CMathBinaryFunctors.hpp"
 #include "types/operations/unary_operations/ArithmeticUnaryFunctors.hpp"
 #include "types/operations/unary_operations/AsciiStringUnaryFunctors.hpp"
@@ -41,9 +41,11 @@
 #include "types/operations/unary_operations/CastOperation.hpp"
 #include "types/operations/unary_operations/DateExtractOperation.hpp"
 #include "types/operations/unary_operations/SubstringOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "utility/StringUtil.hpp"
 
+#include "glog/logging.h"
+
 namespace quickstep {
 
 namespace {
@@ -52,13 +54,13 @@ struct FunctorPackDispatcher {
   template <typename FunctorT>
   inline static std::list<OperationPtr> Generate(
       std::enable_if_t<FunctorT::kOperationSuperTypeID == Operation::kUnaryOperation>* = 0) {
-    return { std::make_shared<const UnaryOperationWrapper<FunctorT>>() };
+    return { std::make_shared<const UnaryOperationSynthesizer<FunctorT>>() };
   }
 
   template <typename FunctorT>
   inline static std::list<OperationPtr> Generate(
       std::enable_if_t<FunctorT::kOperationSuperTypeID == Operation::kBinaryOperation>* = 0) {
-    return { std::make_shared<const BinaryOperationWrapper<FunctorT>>() };
+    return { std::make_shared<const BinaryOperationSynthesizer<FunctorT>>() };
   }
 
   template <typename FunctorT>
@@ -94,6 +96,98 @@ OperationFactory::OperationFactory() {
   registerFunctorPack<CMathBinaryFunctorPack>();
 }
 
+bool OperationFactory::HasOperation(const std::string &operation_name,
+                                    const std::size_t arity) {
+  const auto &primary_index = Instance().primary_index_;
+  const auto indices_it =
+      primary_index.find(std::make_pair(operation_name, arity));
+  return indices_it != primary_index.end();
+}
+
+bool OperationFactory::HasOperation(const OperationSignaturePtr &op_signature) {
+  const auto &operations = Instance().operations_;
+  return operations.find(op_signature) != operations.end();
+}
+
+bool OperationFactory::CanApplyUnaryOperation(
+    const std::string &operation_name,
+    const Type &type,
+    const std::vector<GenericValue> &static_arguments) {
+  std::vector<TypeID> argument_type_ids = {type.getTypeID()};
+  std::vector<TypedValue> static_tv_arguments;
+  for (const auto &value : static_arguments) {
+    argument_type_ids.emplace_back(value.getTypeID());
+    // TODO(refactor-type): Remove this.
+    static_tv_arguments.emplace_back(value.toTypedValue());
+  }
+  const OperationSignaturePtr op_signature =
+      OperationSignature::Create(
+          operation_name, argument_type_ids, static_arguments.size());
+  if (!HasOperation(op_signature)) {
+    return false;
+  }
+  return GetUnaryOperation(op_signature)->canApplyTo(type, static_tv_arguments);
+}
+
+bool OperationFactory::CanApplyBinaryOperation(
+    const std::string &operation_name,
+    const Type &left, const Type &right,
+    const std::vector<GenericValue> &static_arguments) {
+  std::vector<TypeID> argument_type_ids = {left.getTypeID(), right.getTypeID()};
+  std::vector<TypedValue> static_tv_arguments;
+  for (const auto &value : static_arguments) {
+    argument_type_ids.emplace_back(value.getTypeID());
+    // TODO(refactor-type): Remove this.
+    static_tv_arguments.emplace_back(value.toTypedValue());
+  }
+  // TODO(refactor-type): Handle this.
+  DCHECK_EQ(0u, static_arguments.size());
+  const OperationSignaturePtr op_signature =
+      OperationSignature::Create(
+          operation_name, argument_type_ids, static_arguments.size());
+  if (!HasOperation(op_signature)) {
+    return false;
+  }
+  return GetBinaryOperation(op_signature)->canApplyTo(left, right, static_tv_arguments);
+}
+
+OperationPtr OperationFactory::GetOperation(
+    const OperationSignaturePtr &op_signature) {
+  DCHECK(HasOperation(op_signature));
+  return Instance().operations_.at(op_signature);
+}
+
+
+UnaryOperationPtr OperationFactory::GetUnaryOperation(
+    const OperationSignaturePtr &op_signature) {
+  const OperationPtr operation = GetOperation(op_signature);
+  DCHECK(operation->getOperationSuperTypeID() == Operation::kUnaryOperation);
+  return std::static_pointer_cast<const UnaryOperation>(operation);
+}
+
+BinaryOperationPtr OperationFactory::GetBinaryOperation(
+    const OperationSignaturePtr &op_signature) {
+  const OperationPtr operation = GetOperation(op_signature);
+  DCHECK(operation->getOperationSuperTypeID() == Operation::kBinaryOperation);
+  return std::static_pointer_cast<const BinaryOperation>(operation);
+}
+
+OperationSignaturePtr OperationFactory::ResolveOperation(
+    const std::string &operation_name,
+    const std::shared_ptr<const std::vector<const Type*>> &argument_types,
+    const std::shared_ptr<const std::vector<GenericValue>> &static_arguments,
+    std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+    std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
+    std::string *message) {
+  return Instance().resolveOperation(operation_name,
+                                     argument_types,
+                                     static_arguments,
+                                     coerced_argument_types,
+                                     coerced_static_arguments,
+                                     message);
+}
+
+
 OperationSignaturePtr OperationFactory::resolveOperation(
     const std::string &operation_name,
     const std::shared_ptr<const std::vector<const Type*>> &argument_types,
@@ -171,7 +265,7 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMa
 
   if (it != secondary_index.end() && *it->first.first == argument_type_ids) {
     const OperationSignaturePtr op_signature = it->second;
-    const OperationPtr operation = getOperation(op_signature);
+    const OperationPtr operation = operations_.at(op_signature);
 
     *coerced_static_arguments =
         std::make_shared<const std::vector<GenericValue>>(
@@ -264,7 +358,7 @@ OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTyp
         coerced_arg_types.emplace_back(&value.getType());
       }
 
-      const OperationPtr operation = getOperation(it->second);
+      const OperationPtr operation = operations_.at(it->second);
       if (canApplyOperationTo(operation,
                               coerced_arg_types,
                               coerced_static_args,
@@ -360,4 +454,58 @@ void OperationFactory::registerOperationInternal(const OperationPtr &operation)
 }
 
 
+// ----------------------------------------------------------------------------
+// Implemenation of utility short-cuts.
+
+bool OperationFactory::CanApplyCastOperation(const Type &source_type,
+                                             const Type &target_type) {
+  const GenericValue target_meta_type_value =
+      GenericValue::CreateWithLiteral(MetaType::InstanceNonNullable(),
+                                      &target_type);
+  return CanApplyUnaryOperation("cast", source_type, {target_meta_type_value});
+}
+
+UnaryOperationPtr OperationFactory::GetCastOperation(const TypeID source_id) {
+  const OperationSignaturePtr op_signature =
+      OperationSignature::Create("cast", {source_id, kMetaType}, 1);
+  DCHECK(HasOperation(op_signature));
+  return GetUnaryOperation(op_signature);
+}
+
+bool OperationFactory::CanApplyAddOperation(const Type &left, const Type &right) {
+  return CanApplyBinaryOperation("+", left, right);
+}
+
+BinaryOperationPtr OperationFactory::GetAddOperation(const TypeID left_id,
+                                                     const TypeID right_id) {
+  return GetBinaryOperation(OperationSignature::Create("+", {left_id, right_id}, 0));
+}
+
+bool OperationFactory::CanApplySubtractOperation(const Type &left, const Type &right) {
+  return CanApplyBinaryOperation("-", left, right);
+}
+
+BinaryOperationPtr OperationFactory::GetSubtractOperation(const TypeID left_id,
+                                                          const TypeID right_id) {
+  return GetBinaryOperation(OperationSignature::Create("-", {left_id, right_id}, 0));
+}
+
+bool OperationFactory::CanApplyMultiplyOperation(const Type &left, const Type &right) {
+  return CanApplyBinaryOperation("*", left, right);
+}
+
+BinaryOperationPtr OperationFactory::GetMultiplyOperation(const TypeID left_id,
+                                                          const TypeID right_id) {
+  return GetBinaryOperation(OperationSignature::Create("*", {left_id, right_id}, 0));
+}
+
+bool OperationFactory::CanApplyDivideOperation(const Type &left, const Type &right) {
+  return CanApplyBinaryOperation("/", left, right);
+}
+
+BinaryOperationPtr OperationFactory::GetDivideOperation(const TypeID left_id,
+                                                        const TypeID right_id) {
+  return GetBinaryOperation(OperationSignature::Create("/", {left_id, right_id}, 0));
+}
+
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/OperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.hpp b/types/operations/OperationFactory.hpp
index b3fd9b4..7fccbc5 100644
--- a/types/operations/OperationFactory.hpp
+++ b/types/operations/OperationFactory.hpp
@@ -47,71 +47,85 @@ class Type;
 
 class OperationFactory {
  public:
-  static const OperationFactory& Instance();
+  static bool HasOperation(const std::string &operation_name,
+                           const std::size_t arity);
+
+  static bool HasOperation(const OperationSignaturePtr &op_signature);
 
-  inline bool hasOperation(const std::string &operation_name,
-                           const std::size_t arity) const {
-    const auto indices_it =
-        primary_index_.find(std::make_pair(operation_name, arity));
-    return indices_it != primary_index_.end();
-  }
-
-  inline OperationPtr getOperation(const OperationSignaturePtr &op_signature) const {
-    DCHECK(operations_.find(op_signature) != operations_.end());
-    return operations_.at(op_signature);
-  }
-
-  inline OperationPtr getOperation(const std::string &operation_name,
-                                   const std::vector<TypeID> &argument_type_ids,
-                                   const std::size_t num_static_arguments = 0) const {
-    return getOperation(
-        OperationSignature::Create(
-            operation_name, argument_type_ids, num_static_arguments));
-  }
-
-  inline UnaryOperationPtr getUnaryOperation(
-      const OperationSignaturePtr &op_signature) const {
-    const OperationPtr operation = getOperation(op_signature);
-    DCHECK(operation->getOperationSuperTypeID() == Operation::kUnaryOperation);
-    return std::static_pointer_cast<const UnaryOperation>(operation);
-  }
-
-  inline UnaryOperationPtr getUnaryOperation(
+  static bool CanApplyUnaryOperation(
       const std::string &operation_name,
-      const std::vector<TypeID> &argument_type_ids,
-      const std::size_t num_static_arguments = 0) const {
-    return getUnaryOperation(
-        OperationSignature::Create(
-            operation_name, argument_type_ids, num_static_arguments));
-  }
-
-  inline BinaryOperationPtr getBinaryOperation(
-      const OperationSignaturePtr &op_signature) const {
-    const OperationPtr operation = getOperation(op_signature);
-    DCHECK(operation->getOperationSuperTypeID() == Operation::kBinaryOperation);
-    return std::static_pointer_cast<const BinaryOperation>(operation);
-  }
-
-  inline BinaryOperationPtr getBinaryOperation(
+      const Type &type,
+      const std::vector<GenericValue> &static_arguments = {});
+
+  static bool CanApplyBinaryOperation(
       const std::string &operation_name,
-      const std::vector<TypeID> &argument_type_ids,
-      const std::size_t num_static_arguments = 0) const {
-    return getBinaryOperation(
-        OperationSignature::Create(
-            operation_name, argument_type_ids, num_static_arguments));
-  }
+      const Type &left, const Type &right,
+      const std::vector<GenericValue> &static_arguments = {});
 
-  OperationSignaturePtr resolveOperation(
+  /**
+   * @brief Get the Operation for a specified operation signature.
+   */
+  static OperationPtr GetOperation(const OperationSignaturePtr &op_signature);
+
+
+  /**
+   * @brief Get the UnaryOperation for a specified operation signature.
+   */
+  static UnaryOperationPtr GetUnaryOperation(const OperationSignaturePtr &op_signature);
+
+  /**
+   * @brief Get the BinaryOperation for a specified operation signature.
+   */
+  static BinaryOperationPtr GetBinaryOperation(const OperationSignaturePtr &op_signature);
+
+  /**
+   * @brief Resolve an operation from its name and arguments.
+   */
+  static OperationSignaturePtr ResolveOperation(
       const std::string &operation_name,
       const std::shared_ptr<const std::vector<const Type*>> &argument_types,
       const std::shared_ptr<const std::vector<GenericValue>> &static_arguments,
       std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
       std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
-      std::string *message) const;
+      std::string *message);
+
+
+  // ---------------------------------------------------------------------------
+  // Utility short-cuts.
+
+
+  static bool CanApplyCastOperation(const Type &source_type, const Type &target_type);
+
+  static UnaryOperationPtr GetCastOperation(const TypeID source_id);
+
+
+  static bool CanApplyAddOperation(const Type &left, const Type &right);
+
+  static BinaryOperationPtr GetAddOperation(const TypeID left_id,
+                                            const TypeID right_id);
+
+
+  static bool CanApplySubtractOperation(const Type &left, const Type &right);
+
+  static BinaryOperationPtr GetSubtractOperation(const TypeID left_id,
+                                                 const TypeID right_id);
+
+
+  static bool CanApplyMultiplyOperation(const Type &left,  const Type &right);
+
+  static BinaryOperationPtr GetMultiplyOperation(const TypeID left_id,
+                                                 const TypeID right_id);
+
+  static bool CanApplyDivideOperation(const Type &left, const Type &right);
+
+  static BinaryOperationPtr GetDivideOperation(const TypeID left_id,
+                                               const TypeID right_id);
 
  private:
   OperationFactory();
 
+  static const OperationFactory& Instance();
+
   template <typename OperationT>
   void registerOperation();
 
@@ -151,6 +165,14 @@ class OperationFactory {
     kNotFound
   };
 
+  OperationSignaturePtr resolveOperation(
+      const std::string &operation_name,
+      const std::shared_ptr<const std::vector<const Type*>> &argument_types,
+      const std::shared_ptr<const std::vector<GenericValue>> &static_arguments,
+      std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+      std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
+      std::string *message) const;
+
   ResolveStatus resolveOperationWithFullTypeMatch(
       const PartialSignatureIndex &secondary_index,
       const std::vector<TypeID> &argument_type_ids,
@@ -170,16 +192,6 @@ class OperationFactory {
       OperationSignaturePtr *resolved_op_signature,
       std::string *message) const;
 
-//  ResolveStatus resolveOperationGeneric(
-//      const std::set<OperationSignaturePtr> signatures,
-//      const std::vector<TypeID> &argument_type_ids,
-//      const std::vector<const Type*> &argument_types,
-//      const std::vector<GenericValue> &static_arguments,
-//      std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
-//      std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
-//      OperationSignaturePtr *op_signature,
-//      std::string *message) const;
-
   bool canApplyOperationTo(const OperationPtr operation,
                            const std::vector<const Type*> &argument_types,
                            const std::vector<GenericValue> &static_arguments,
@@ -196,6 +208,8 @@ class OperationFactory {
   DISALLOW_COPY_AND_ASSIGN(OperationFactory);
 };
 
+
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp b/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp
index 402bd0a..bab71ce 100644
--- a/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp
+++ b/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp
@@ -36,7 +36,7 @@
 #include "types/TypedValue.hpp"
 #include "types/YearMonthIntervalType.hpp"
 #include "types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp"
-#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "types/operations/binary_operations/BinaryOperationSynthesizer.hpp"
 #include "utility/meta/Common.hpp"
 
 namespace quickstep {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp b/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp
index 5fd54d6..4d704a1 100644
--- a/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp
+++ b/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp
@@ -26,11 +26,12 @@
 
 #include "types/CharType.hpp"
 #include "types/IntType.hpp"
+#include "types/TextType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/VarCharType.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "types/operations/utility/OperationSynthesizeUtil.hpp"
 #include "types/port/strnlen.hpp"
 
@@ -41,8 +42,8 @@ namespace quickstep {
  */
 
 template <typename LeftT, typename RightT, typename ResultT>
-struct AsciiStringConcatFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
-  explicit AsciiStringConcatFunctor(const LeftT &left, const RightT &right)
+struct RawStringConcatFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
+  explicit RawStringConcatFunctor(const LeftT &left, const RightT &right)
       : left_max_(left.getStringLength()),
         right_max_(right.getStringLength()),
         result_max_(left_max_ + right_max_) {}
@@ -114,13 +115,22 @@ struct AsciiStringConcatFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
   const std::size_t result_max_;
 };
 
+struct CxxStringConcatFunctor : public BinaryFunctor<TextType, TextType, TextType> {
+  inline std::string apply(const std::string &left, const std::string &right) const {
+    return left + right;
+  }
+  inline static std::string GetName() {
+    return "+";
+  }
+};
 
 using AsciiStringBinaryFunctorPack = FunctorPack<
 // concat
-    AsciiStringConcatFunctor<CharType, CharType, CharType>,
-    AsciiStringConcatFunctor<CharType, VarCharType, VarCharType>,
-    AsciiStringConcatFunctor<VarCharType, CharType, VarCharType>,
-    AsciiStringConcatFunctor<VarCharType, VarCharType, VarCharType>
+    RawStringConcatFunctor<CharType, CharType, CharType>,
+    RawStringConcatFunctor<CharType, VarCharType, VarCharType>,
+    RawStringConcatFunctor<VarCharType, CharType, VarCharType>,
+    RawStringConcatFunctor<VarCharType, VarCharType, VarCharType>,
+    CxxStringConcatFunctor
 >;
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/binary_operations/BinaryOperationSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationSynthesizer.hpp b/types/operations/binary_operations/BinaryOperationSynthesizer.hpp
new file mode 100644
index 0000000..f30a3b0
--- /dev/null
+++ b/types/operations/binary_operations/BinaryOperationSynthesizer.hpp
@@ -0,0 +1,660 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_WRAPPER_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_WRAPPER_HPP_
+
+#include <cstddef>
+#include <list>
+#include <string>
+#include <tuple>
+#include <type_traits>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "storage/ValueAccessor.hpp"
+#include "storage/ValueAccessorUtil.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/binary_operations/BinaryOperation.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
+#include "utility/Macros.hpp"
+#include "utility/meta/Common.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename LeftArgumentT, typename RightArgumentT, typename ResultT>
+struct BinaryFunctor {
+  typedef LeftArgumentT LeftArgumentType;
+  typedef RightArgumentT RightArgumentType;
+  typedef ResultT ResultType;
+
+  static constexpr Operation
+      ::OperationSuperTypeID kOperationSuperTypeID = Operation::kBinaryOperation;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+class UncheckedBinaryOperatorSynthesizer : public UncheckedBinaryOperator {
+ public:
+  template <typename ...FunctorArgs>
+  UncheckedBinaryOperatorSynthesizer(const Type &left_type,
+                                     const Type &right_type,
+                                     const Type &result_type,
+                                     FunctorArgs &&...args)
+      : functor_(std::forward<FunctorArgs>(args)...),
+        impl_(functor_, left_type, right_type, result_type) {
+    DCHECK(left_type.getTypeID() == LeftType::kStaticTypeID);
+    DCHECK(right_type.getTypeID() == RightType::kStaticTypeID);
+    DCHECK(result_type.getTypeID() == ResultType::kStaticTypeID);
+  }
+
+  TypedValue applyToTypedValues(const TypedValue &left,
+                                const TypedValue &right) const override {
+    return impl_.applyToTypedValues(left, right);
+  }
+
+  ColumnVector* applyToColumnVectors(const ColumnVector &left,
+                                     const ColumnVector &right) const override {
+    using LeftCVT = typename LeftGen::ColumnVectorType;
+    DCHECK(left.getImplementation() == LeftCVT::kImplementation);
+    using LeftAccessorT = ColumnVectorAccessor<LeftCVT>;
+    LeftAccessorT left_accessor(static_cast<const LeftCVT&>(left));
+
+    using RightCVT = typename RightGen::ColumnVectorType;
+    DCHECK(right.getImplementation() == RightCVT::kImplementation);
+    using RightAccessorT = ColumnVectorAccessor<RightCVT>;
+    RightAccessorT right_accessor(static_cast<const RightCVT&>(right));
+
+    const std::size_t num_tuples = left_accessor.getNumTuples();
+    DCHECK_EQ(num_tuples, right_accessor.getNumTuples());
+
+    return impl_.applyToValueAccessors(num_tuples,
+                                       &left_accessor, kInvalidAttributeID,
+                                       &right_accessor, kInvalidAttributeID);
+  }
+
+  ColumnVector* applyToColumnVectorAndStaticValue(
+      const ColumnVector &left,
+      const TypedValue &right) const override {
+    using LeftCVT = typename LeftGen::ColumnVectorType;
+    DCHECK(left.getImplementation() == LeftCVT::kImplementation);
+
+    using LeftAccessorT = ColumnVectorAccessor<LeftCVT>;
+    LeftAccessorT accessor(static_cast<const LeftCVT&>(left));
+    return impl_.applyToValueAccessorAndStaticValue(&accessor, 0, right);
+  }
+
+  ColumnVector* applyToStaticValueAndColumnVector(
+      const TypedValue &left,
+      const ColumnVector &right) const override {
+    using RightCVT = typename RightGen::ColumnVectorType;
+    DCHECK(right.getImplementation() == RightCVT::kImplementation);
+
+    using RightAccessorT = ColumnVectorAccessor<RightCVT>;
+    RightAccessorT accessor(static_cast<const RightCVT&>(right));
+    return impl_.applyToStaticValueAndValueAccessor(left, &accessor, 0);
+  }
+
+  ColumnVector* applyToSingleValueAccessor(
+      ValueAccessor *accessor,
+      const attribute_id left_id,
+      const attribute_id right_id) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToSingleValueAccessor(accessor, left_id, right_id);
+    });
+  }
+
+  ColumnVector* applyToValueAccessorAndStaticValue(
+      ValueAccessor *left_accessor,
+      const attribute_id left_id,
+      const TypedValue &right) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        left_accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToValueAccessorAndStaticValue(accessor, left_id, right);
+    });
+  }
+
+  ColumnVector* applyToStaticValueAndValueAccessor(
+      const TypedValue &left,
+      ValueAccessor *right_accessor,
+      const attribute_id right_id) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        right_accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToStaticValueAndValueAccessor(left, accessor, right_id);
+    });
+  }
+
+  ColumnVector* applyToColumnVectorAndValueAccessor(
+      const ColumnVector &left,
+      ValueAccessor *right_accessor,
+      const attribute_id right_id) const override {
+    using LeftCVT = typename LeftGen::ColumnVectorType;
+    DCHECK(left.getImplementation() == LeftCVT::kImplementation);
+    using LeftAccessorT = ColumnVectorAccessor<LeftCVT>;
+    LeftAccessorT left_accessor(static_cast<const LeftCVT&>(left));
+
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        right_accessor,
+        [&](auto *right_accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+    const std::size_t num_tuples = left_accessor.getNumTuples();
+    DCHECK_EQ(num_tuples, right_accessor->getNumTuples());
+
+    return impl_.applyToValueAccessors(num_tuples,
+                                       &left_accessor, kInvalidAttributeID,
+                                       right_accessor, right_id);
+    });
+  }
+
+  ColumnVector* applyToValueAccessorAndColumnVector(
+      ValueAccessor *left_accessor,
+      const attribute_id left_id,
+      const ColumnVector &right) const override {
+    using RightCVT = typename RightGen::ColumnVectorType;
+    DCHECK(right.getImplementation() == RightCVT::kImplementation);
+    using RightAccessorT = ColumnVectorAccessor<RightCVT>;
+    RightAccessorT right_accessor(static_cast<const RightCVT&>(right));
+
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        left_accessor,
+        [&](auto *left_accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      const std::size_t num_tuples = right_accessor.getNumTuples();
+      DCHECK_EQ(num_tuples, left_accessor->getNumTuples());
+
+      return impl_.applyToValueAccessors(num_tuples,
+                                         left_accessor, left_id,
+                                         &right_accessor, kInvalidAttributeID);
+    });
+  }
+
+  TypedValue accumulateColumnVector(
+      const TypedValue &current,
+      const ColumnVector &column_vector,
+      std::size_t *num_tuples_applied) const override {
+    constexpr bool is_supported =
+        LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
+        LeftType::kMemoryLayout == kCxxInlinePod &&
+        std::is_copy_assignable<typename LeftType::cpptype>::value;
+
+    using RightCVT = typename RightGen::ColumnVectorType;
+    DCHECK(column_vector.getImplementation() == RightCVT::kImplementation);
+    using RightAccessorT = ColumnVectorAccessor<RightCVT>;
+    RightAccessorT accessor(static_cast<const RightCVT&>(column_vector));
+
+    return impl_.template accumulateValueAccessor<is_supported>(
+        current,
+        &accessor,
+        kInvalidAttributeID,
+        num_tuples_applied);
+  }
+
+  TypedValue accumulateValueAccessor(
+      const TypedValue &current,
+      ValueAccessor *accessor,
+      const attribute_id value_accessor_id,
+      std::size_t *num_tuples_applied) const override {
+    constexpr bool is_supported =
+        LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
+        LeftType::kMemoryLayout == kCxxInlinePod &&
+        std::is_copy_assignable<typename LeftType::cpptype>::value;
+
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        accessor,
+        [&](auto *accessor) -> TypedValue {  // NOLINT(build/c++11)
+      return impl_.template accumulateValueAccessor<is_supported>(
+          current,
+          accessor,
+          value_accessor_id,
+          num_tuples_applied);
+    });
+  }
+
+ private:
+  using LeftType = typename FunctorT::LeftArgumentType;
+  using RightType = typename FunctorT::RightArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
+  using LeftGen = OperationCodegen<FuncSpec, LeftType>;
+  using RightGen = OperationCodegen<FuncSpec, RightType>;
+  using ResultGen = OperationCodegen<FuncSpec, ResultType>;
+
+  template <bool left_nullable, bool right_nullable>
+  struct Implementation;
+
+  const FunctorT functor_;
+  const Implementation<false, false> impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(UncheckedBinaryOperatorSynthesizer);
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool left_nullable, bool right_nullable>
+struct UncheckedBinaryOperatorSynthesizer<FunctorT, SpecArgs...>
+    ::Implementation {
+  Implementation(const FunctorT &functor_in,
+                 const Type &left_type_in,
+                 const Type &right_type_in,
+                 const Type &result_type_in)
+      : functor(functor_in),
+        left_type(static_cast<const LeftType&>(left_type_in)),
+        right_type(static_cast<const RightType&>(right_type_in)),
+        result_type(static_cast<const ResultType&>(result_type_in)) {}
+
+  inline TypedValue applyToTypedValues(const TypedValue &left,
+                                       const TypedValue &right) const {
+    if ((left_nullable && left.isNull()) || (right_nullable && right.isNull())) {
+      return TypedValue(ResultType::kStaticTypeID);
+    }
+
+    return ResultGen::template ApplyBinaryTypedValue<LeftGen, RightGen>(
+        LeftGen::ToNativeValueConst(left, left_type),
+        RightGen::ToNativeValueConst(right, right_type),
+        result_type,
+        functor);
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToValueAccessorAndStaticValue(
+      AccessorT *accessor,
+      const attribute_id attr_id,
+      const TypedValue &static_value) const {
+    using AccessorGen = LeftGen;
+    using StaticValueGen = RightGen;
+
+    constexpr bool accessor_nullable = left_nullable;
+    constexpr bool static_value_nullable = right_nullable;
+
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    if (static_value_nullable && static_value.isNull()) {
+      result_cv->fillWithNulls();
+      return result_cv;
+    }
+
+    typename StaticValueGen::NativeTypeConst literal =
+        StaticValueGen::ToNativeValueConst(static_value, right_type);
+    std::unique_ptr<typename AccessorGen::NativeType> value_cache;
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename AccessorGen::NativeTypeConstPtr arg_value =
+          AccessorGen::template GetValuePtr<accessor_nullable, AccessorT>(
+              accessor, attr_id, left_type, &value_cache);
+      if (accessor_nullable && AccessorGen::IsNull(arg_value)) {
+        result_cv->appendNullValue();
+      } else {
+        ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
+            AccessorGen::Dereference(arg_value), literal, functor, result_cv);
+      }
+    }
+    return result_cv;
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToStaticValueAndValueAccessor(
+      const TypedValue &static_value,
+      AccessorT *accessor,
+      const attribute_id attr_id) const {
+    using AccessorGen = RightGen;
+    using StaticValueGen = LeftGen;
+
+    constexpr bool accessor_nullable = right_nullable;
+    constexpr bool static_value_nullable = left_nullable;
+
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    if (static_value_nullable && static_value.isNull()) {
+      result_cv->fillWithNulls();
+      return result_cv;
+    }
+
+    typename StaticValueGen::NativeTypeConst literal =
+        StaticValueGen::ToNativeValueConst(static_value, left_type);
+    std::unique_ptr<typename AccessorGen::NativeType> value_cache;
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename AccessorGen::NativeTypeConstPtr arg_value =
+          AccessorGen::template GetValuePtr<accessor_nullable, AccessorT>(
+              accessor, attr_id, right_type, &value_cache);
+      if (accessor_nullable && AccessorGen::IsNull(arg_value)) {
+        result_cv->appendNullValue();
+      } else {
+        ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
+            literal, AccessorGen::Dereference(arg_value), functor, result_cv);
+      }
+    }
+    return result_cv;
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToSingleValueAccessor(
+      AccessorT *accessor,
+      const attribute_id left_id,
+      const attribute_id right_id) const {
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    std::unique_ptr<typename LeftGen::NativeType> left_value_cache;
+    std::unique_ptr<typename RightGen::NativeType> right_value_cache;
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename LeftGen::NativeTypeConstPtr left_value =
+          LeftGen::template GetValuePtr<left_nullable, AccessorT>(
+              accessor, left_id, left_type, &left_value_cache);
+      if (left_nullable && LeftGen::IsNull(left_value)) {
+        result_cv->appendNullValue();
+        continue;
+      }
+      typename RightGen::NativeTypeConstPtr right_value =
+          RightGen::template GetValuePtr<right_nullable, AccessorT>(
+              accessor, right_id, right_type, &right_value_cache);
+      if (right_nullable && RightGen::IsNull(right_value)) {
+        result_cv->appendNullValue();
+        continue;
+      }
+      ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
+          LeftGen::Dereference(left_value),
+          RightGen::Dereference(right_value),
+          functor,
+          result_cv);
+    }
+    return result_cv;
+  }
+
+  template <typename LeftAccessorT, typename RightAccessorT>
+  inline ColumnVector* applyToValueAccessors(const std::size_t num_tuples,
+                                             LeftAccessorT *left_accessor,
+                                             const attribute_id left_id,
+                                             RightAccessorT *right_accessor,
+                                             const attribute_id right_id) const {
+    DCHECK_EQ(num_tuples, left_accessor->getNumTuples());
+    DCHECK_EQ(num_tuples, right_accessor->getNumTuples());
+
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, num_tuples);
+
+    std::unique_ptr<typename LeftGen::NativeType> left_value_cache;
+    std::unique_ptr<typename RightGen::NativeType> right_value_cache;
+    left_accessor->beginIteration();
+    right_accessor->beginIteration();
+    while (left_accessor->next()) {
+      right_accessor->next();
+      typename LeftGen::NativeTypeConstPtr left_value =
+          LeftGen::template GetValuePtr<left_nullable, LeftAccessorT>(
+              left_accessor, left_id, left_type, &left_value_cache);
+      if (left_nullable && LeftGen::IsNull(left_value)) {
+        result_cv->appendNullValue();
+        continue;
+      }
+      typename RightGen::NativeTypeConstPtr right_value =
+          RightGen::template GetValuePtr<right_nullable, RightAccessorT>(
+              right_accessor, right_id, right_type, &right_value_cache);
+      if (right_nullable && RightGen::IsNull(right_value)) {
+        result_cv->appendNullValue();
+        continue;
+      }
+      ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
+          LeftGen::Dereference(left_value),
+          RightGen::Dereference(right_value),
+          functor,
+          result_cv);
+    }
+    return result_cv;
+  }
+
+  template <bool supported, typename AccessorT>
+  inline TypedValue accumulateValueAccessor(const TypedValue &current,
+                                            AccessorT *accessor,
+                                            const attribute_id attr_id,
+                                            std::size_t *num_tuples_applied,
+                                            std::enable_if_t<supported>* = 0) const {
+    DCHECK(num_tuples_applied);
+
+    *num_tuples_applied = 0;
+    if (left_nullable && current.isNull()) {
+      return result_type.makeNullValue();
+    }
+
+    using LeftCppType = typename LeftType::cpptype;
+    using ResultCppType = typename ResultType::cpptype;
+    ResultCppType accumulated = current.getLiteral<LeftCppType>();
+
+    std::unique_ptr<typename RightGen::NativeType> value_cache;
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename RightGen::NativeTypeConstPtr right_value =
+          RightGen::template GetValuePtr<
+              right_nullable, AccessorT>(accessor, attr_id, right_type, &value_cache);
+      if (right_nullable && RightGen::IsNull(right_value)) {
+        continue;
+      }
+
+      accumulated =
+          ResultGen::FunctorSpecializer::Invoke(
+              functor, accumulated, RightGen::Dereference(right_value));
+      ++(*num_tuples_applied);
+    }
+
+    return TypedValue(accumulated);
+  }
+
+  template <bool supported, typename AccessorT>
+  inline TypedValue accumulateValueAccessor(const TypedValue &current,
+                                            AccessorT *accessor,
+                                            const attribute_id attr_id,
+                                            std::size_t *num_tuples_applied,
+                                            std::enable_if_t<!supported>* = 0) const {
+    LOG(FATAL) << "Unimplemented method UncheckedBinaryOperatorSynthesizer"
+               << "::accumulateValueAccessor() because ResultType and LeftType "
+               << "are not same or not native types.";
+  }
+
+  const FunctorT &functor;
+  const LeftType &left_type;
+  const RightType &right_type;
+  const ResultType &result_type;
+};
+
+
+template <typename FunctorT>
+class BinaryOperationSynthesizer : public BinaryOperation {
+ public:
+  BinaryOperationSynthesizer()
+      : BinaryOperation(),
+        operation_name_(FunctorT::GetName()) {}
+
+  std::string getName() const override {
+    return operation_name_;
+  }
+
+  std::string getShortName() const override {
+    return getName();
+  }
+
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    return {
+        OperationSignature::Create(
+            getName(), {LeftType::kStaticTypeID, RightType::kStaticTypeID}, 0)
+    };
+  }
+
+  bool canApplyTo(const Type &left,
+                  const Type &right,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
+    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return true;
+  }
+
+  const Type* getResultType(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
+    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return getResultTypeImpl<HasGetType<FunctorT>::value>(
+        left, right, static_arguments);
+  }
+
+  UncheckedBinaryOperator* makeUncheckedBinaryOperator(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
+    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return makeUncheckedBinaryOperatorImpl<
+        std::is_default_constructible<FunctorT>::value>(
+            left, right, static_arguments);
+  }
+
+ private:
+  using LeftType = typename FunctorT::LeftArgumentType;
+  using RightType = typename FunctorT::RightArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  QUICKSTEP_TRAIT_HAS_STATIC_METHOD(HasGetType, GetType);
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedBinaryOperator* makeUncheckedBinaryOperatorImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<functor_use_default_constructor> * = 0) const {
+    return new UncheckedBinaryOperatorSynthesizer<FunctorT>(
+        left, right, *getResultType(left, right, static_arguments));
+  }
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedBinaryOperator* makeUncheckedBinaryOperatorImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!functor_use_default_constructor> * = 0) const {
+    return new UncheckedBinaryOperatorSynthesizer<FunctorT>(
+        left, right, *getResultType(left, right, static_arguments),
+        static_cast<const LeftType&>(left),
+        static_cast<const RightType&>(right));
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!user_defined_get_type &&
+                       ResultType::kMemoryLayout == kCxxInlinePod> * = 0) const {
+    return &TypeFactory::GetType(ResultType::kStaticTypeID,
+                                 left.isNullable() || right.isNullable());
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!user_defined_get_type &&
+                       ResultType::kMemoryLayout == kCxxGeneric> * = 0) const {
+    return &TypeFactory::GetType(ResultType::kStaticTypeID,
+                                 std::vector<GenericValue>(),
+                                 left.isNullable() || right.isNullable());
+  }
+
+  template <bool user_defined_get_type>
+  inline const Type* getResultTypeImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<user_defined_get_type ||
+                       ResultType::kMemoryLayout == kParInlinePod ||
+                       ResultType::kMemoryLayout == kParOutOfLinePod> * = 0) const {
+    // TODO(refactor-type): Specialize with regard to static arguments.
+    return FunctorT::GetResultType(left, right);
+  }
+
+  const std::string operation_name_;
+
+  DISALLOW_COPY_AND_ASSIGN(BinaryOperationSynthesizer);
+};
+
+template <typename LeftPack, typename RightPack,
+          template <typename LeftT,
+                    typename RightT,
+                    typename ResultT> class FunctorT,
+          template <typename LeftT,
+                    typename RightT> class ResultGenerator>
+struct BinaryFunctorCrossProductPack {
+  template <std::size_t l, std::size_t r>
+  inline static OperationPtr GenerateInner() {
+    using LeftType = std::tuple_element_t<l, LeftPack>;
+    using RightType = std::tuple_element_t<r, RightPack>;
+    using ResultType = typename ResultGenerator<LeftType, RightType>::type;
+
+    return std::make_shared<
+        const BinaryOperationSynthesizer<
+            FunctorT<LeftType, RightType, ResultType>>>();
+  }
+
+  template <std::size_t l, std::size_t ...Rs>
+  inline static std::list<OperationPtr> GenerateRightHelper() {
+    return { GenerateInner<l, Rs>()... };
+  }
+
+  template <std::size_t ...Ls, std::size_t ...Rs>
+  inline static std::vector<std::list<OperationPtr>> GenerateLeftHelper(
+      meta::IntegerSequence<Ls...> &&l_seq, meta::IntegerSequence<Rs...> &&r_seq) {
+    return { GenerateRightHelper<Ls, Rs...>()... };
+  }
+
+  template <typename Dispatcher>
+  inline static std::list<OperationPtr> GenerateOperations() {
+    std::vector<std::list<OperationPtr>> op_list_groups =
+        GenerateLeftHelper(typename meta::MakeSequence<std::tuple_size<LeftPack>::value>::type(),
+                           typename meta::MakeSequence<std::tuple_size<RightPack>::value>::type());
+
+    std::list<OperationPtr> operations;
+    for (std::list<OperationPtr> &op_list : op_list_groups) {
+      operations.splice(operations.end(), std::move(op_list));
+    }
+    return operations;
+  }
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/binary_operations/BinaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationWrapper.hpp b/types/operations/binary_operations/BinaryOperationWrapper.hpp
deleted file mode 100644
index 3a336ee..0000000
--- a/types/operations/binary_operations/BinaryOperationWrapper.hpp
+++ /dev/null
@@ -1,629 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_WRAPPER_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_WRAPPER_HPP_
-
-#include <cstddef>
-#include <list>
-#include <string>
-#include <tuple>
-#include <type_traits>
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
-#include "types/Type.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/OperationSignature.hpp"
-#include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/utility/OperationSynthesizeUtil.hpp"
-#include "utility/Macros.hpp"
-#include "utility/meta/Common.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename LeftArgumentT, typename RightArgumentT, typename ResultT>
-struct BinaryFunctor {
-  typedef LeftArgumentT LeftArgumentType;
-  typedef RightArgumentT RightArgumentType;
-  typedef ResultT ResultType;
-
-  static constexpr Operation
-      ::OperationSuperTypeID kOperationSuperTypeID = Operation::kBinaryOperation;
-};
-
-template <typename FunctorT, typename ...SpecArgs>
-class UncheckedBinaryOperatorWrapperCodegen : public UncheckedBinaryOperator {
- public:
-  template <typename ...ConstructorArgs>
-  UncheckedBinaryOperatorWrapperCodegen(const Type &left_type,
-                                        const Type &right_type,
-                                        const Type &result_type,
-                                        ConstructorArgs &&...args)
-      : functor_(std::forward<ConstructorArgs>(args)...),
-        impl_(functor_, left_type, right_type, result_type) {}
-
-  TypedValue applyToTypedValues(const TypedValue &left,
-                                const TypedValue &right) const override {
-    return impl_.applyToTypedValues(left, right);
-  }
-
-  ColumnVector* applyToColumnVectors(const ColumnVector &left,
-                                     const ColumnVector &right) const override {
-    using LeftCVT = typename LeftGen::ColumnVectorType;
-    DCHECK_EQ(left.isNative(), LeftCVT::kNative);
-    using LeftAccessorT = ColumnVectorValueAccessor<LeftCVT>;
-    LeftAccessorT left_accessor(static_cast<const LeftCVT&>(left));
-
-    using RightCVT = typename RightGen::ColumnVectorType;
-    DCHECK_EQ(right.isNative(), RightCVT::kNative);
-    using RightAccessorT = ColumnVectorValueAccessor<RightCVT>;
-    RightAccessorT right_accessor(static_cast<const RightCVT&>(right));
-
-    const std::size_t num_tuples = left_accessor.getNumTuples();
-    DCHECK_EQ(num_tuples, right_accessor.getNumTuples());
-
-    return impl_.applyToValueAccessors(num_tuples,
-                                       &left_accessor, kInvalidAttributeID,
-                                       &right_accessor, kInvalidAttributeID);
-  }
-
-  ColumnVector* applyToColumnVectorAndStaticValue(
-      const ColumnVector &left,
-      const TypedValue &right) const override {
-    using LeftCVT = typename LeftGen::ColumnVectorType;
-    DCHECK_EQ(left.isNative(), LeftCVT::kNative);
-
-    using LeftAccessorT = ColumnVectorValueAccessor<LeftCVT>;
-    LeftAccessorT accessor(static_cast<const LeftCVT&>(left));
-    return impl_.applyToValueAccessorAndStaticValue(&accessor, 0, right);
-  }
-
-  ColumnVector* applyToStaticValueAndColumnVector(
-      const TypedValue &left,
-      const ColumnVector &right) const override {
-    using RightCVT = typename RightGen::ColumnVectorType;
-    DCHECK_EQ(right.isNative(), RightCVT::kNative);
-
-    using RightAccessorT = ColumnVectorValueAccessor<RightCVT>;
-    RightAccessorT accessor(static_cast<const RightCVT&>(right));
-    return impl_.applyToStaticValueAndValueAccessor(left, &accessor, 0);
-  }
-
-  ColumnVector* applyToSingleValueAccessor(
-      ValueAccessor *accessor,
-      const attribute_id left_id,
-      const attribute_id right_id) const override {
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      return impl_.applyToSingleValueAccessor(accessor, left_id, right_id);
-    });
-  }
-
-  ColumnVector* applyToValueAccessorAndStaticValue(
-      ValueAccessor *left_accessor,
-      const attribute_id left_id,
-      const TypedValue &right) const override {
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        left_accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      return impl_.applyToValueAccessorAndStaticValue(accessor, left_id, right);
-    });
-  }
-
-  ColumnVector* applyToStaticValueAndValueAccessor(
-      const TypedValue &left,
-      ValueAccessor *right_accessor,
-      const attribute_id right_id) const override {
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        right_accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      return impl_.applyToStaticValueAndValueAccessor(left, accessor, right_id);
-    });
-  }
-
-  ColumnVector* applyToColumnVectorAndValueAccessor(
-      const ColumnVector &left,
-      ValueAccessor *right_accessor,
-      const attribute_id right_id) const override {
-    using LeftCVT = typename LeftGen::ColumnVectorType;
-    DCHECK_EQ(left.isNative(), LeftCVT::kNative);
-    using LeftAccessorT = ColumnVectorValueAccessor<LeftCVT>;
-    LeftAccessorT left_accessor(static_cast<const LeftCVT&>(left));
-
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        right_accessor,
-        [&](auto *right_accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    const std::size_t num_tuples = left_accessor.getNumTuples();
-    DCHECK_EQ(num_tuples, right_accessor->getNumTuples());
-
-    return impl_.applyToValueAccessors(num_tuples,
-                                       &left_accessor, kInvalidAttributeID,
-                                       right_accessor, right_id);
-    });
-  }
-
-  ColumnVector* applyToValueAccessorAndColumnVector(
-      ValueAccessor *left_accessor,
-      const attribute_id left_id,
-      const ColumnVector &right) const override {
-    using RightCVT = typename RightGen::ColumnVectorType;
-    DCHECK_EQ(right.isNative(), RightCVT::kNative);
-    using RightAccessorT = ColumnVectorValueAccessor<RightCVT>;
-    RightAccessorT right_accessor(static_cast<const RightCVT&>(right));
-
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        left_accessor,
-        [&](auto *left_accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      const std::size_t num_tuples = right_accessor.getNumTuples();
-      DCHECK_EQ(num_tuples, left_accessor->getNumTuples());
-
-      return impl_.applyToValueAccessors(num_tuples,
-                                         left_accessor, left_id,
-                                         &right_accessor, kInvalidAttributeID);
-    });
-  }
-
-  TypedValue accumulateColumnVector(
-      const TypedValue &current,
-      const ColumnVector &column_vector,
-      std::size_t *num_tuples_applied) const override {
-    constexpr bool is_supported =
-        LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
-        LeftType::kMemoryLayout == kCxxInlinePod &&
-        std::is_copy_assignable<typename LeftType::cpptype>::value;
-
-    using RightCVT = typename RightGen::ColumnVectorType;
-    DCHECK_EQ(column_vector.isNative(), RightCVT::kNative);
-    using RightAccessorT = ColumnVectorValueAccessor<RightCVT>;
-    RightAccessorT accessor(static_cast<const RightCVT&>(column_vector));
-
-    return impl_.template accumulateValueAccessor<is_supported>(
-        current,
-        &accessor,
-        kInvalidAttributeID,
-        num_tuples_applied);
-  }
-
-  TypedValue accumulateValueAccessor(
-      const TypedValue &current,
-      ValueAccessor *accessor,
-      const attribute_id value_accessor_id,
-      std::size_t *num_tuples_applied) const override {
-    constexpr bool is_supported =
-        LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
-        LeftType::kMemoryLayout == kCxxInlinePod &&
-        std::is_copy_assignable<typename LeftType::cpptype>::value;
-
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> TypedValue {  // NOLINT(build/c++11)
-      return impl_.template accumulateValueAccessor<is_supported>(
-          current,
-          accessor,
-          value_accessor_id,
-          num_tuples_applied);
-    });
-  }
-
- private:
-  using LeftType = typename FunctorT::LeftArgumentType;
-  using RightType = typename FunctorT::RightArgumentType;
-  using ResultType = typename FunctorT::ResultType;
-
-  using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
-  using LeftGen = OperationCodegen<FuncSpec, LeftType>;
-  using RightGen = OperationCodegen<FuncSpec, RightType>;
-  using ResultGen = OperationCodegen<FuncSpec, ResultType>;
-
-  template <bool left_nullable, bool right_nullable>
-  struct Implementation;
-
-  const FunctorT functor_;
-  const Implementation<false, false> impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(UncheckedBinaryOperatorWrapperCodegen);
-};
-
-template <typename FunctorT, typename ...SpecArgs>
-template <bool left_nullable, bool right_nullable>
-struct UncheckedBinaryOperatorWrapperCodegen<FunctorT, SpecArgs...>
-    ::Implementation {
-  Implementation(const FunctorT &functor_in,
-                 const Type &left_type_in,
-                 const Type &right_type_in,
-                 const Type &result_type_in)
-      : functor(functor_in),
-        left_type(left_type_in),
-        right_type(right_type_in),
-        result_type(result_type_in) {}
-
-  inline TypedValue applyToTypedValues(const TypedValue &left,
-                                       const TypedValue &right) const {
-    if ((left_nullable && left.isNull()) || (right_nullable && right.isNull())) {
-      return TypedValue(ResultType::kStaticTypeID);
-    }
-
-    return ResultGen::template ApplyBinaryTypedValue<LeftGen, RightGen>(
-        LeftGen::ToNativeValueConst(left),
-        RightGen::ToNativeValueConst(right),
-        result_type,
-        functor);
-  }
-
-  template <typename AccessorT>
-  inline ColumnVector* applyToValueAccessorAndStaticValue(
-      AccessorT *accessor,
-      const attribute_id attr_id,
-      const TypedValue &static_value) const {
-    using AccessorGen = LeftGen;
-    using StaticValueGen = RightGen;
-
-    constexpr bool accessor_nullable = left_nullable;
-    constexpr bool static_value_nullable = right_nullable;
-
-    using ResultCVT = typename ResultGen::ColumnVectorType;
-    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
-
-    if (static_value_nullable && static_value.isNull()) {
-      result_cv->fillWithNulls();
-      return result_cv;
-    }
-
-    typename StaticValueGen::NativeTypeConst literal =
-        StaticValueGen::ToNativeValueConst(static_value);
-    accessor->beginIteration();
-    while (accessor->next()) {
-      typename AccessorGen::NativeTypeConstPtr arg_value =
-          AccessorGen::template GetValuePtr<
-              accessor_nullable, AccessorT>(accessor, attr_id);
-      if (accessor_nullable && AccessorGen::IsNull(arg_value)) {
-        result_cv->appendNullValue();
-      } else {
-        ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
-            AccessorGen::Dereference(arg_value), literal, functor, result_cv);
-      }
-    }
-    return result_cv;
-  }
-
-  template <typename AccessorT>
-  inline ColumnVector* applyToStaticValueAndValueAccessor(
-      const TypedValue &static_value,
-      AccessorT *accessor,
-      const attribute_id attr_id) const {
-    using AccessorGen = RightGen;
-    using StaticValueGen = LeftGen;
-
-    constexpr bool accessor_nullable = right_nullable;
-    constexpr bool static_value_nullable = left_nullable;
-
-    using ResultCVT = typename ResultGen::ColumnVectorType;
-    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
-
-    if (static_value_nullable && static_value.isNull()) {
-      result_cv->fillWithNulls();
-      return result_cv;
-    }
-
-    typename StaticValueGen::NativeTypeConst literal =
-        StaticValueGen::ToNativeValueConst(static_value);
-    accessor->beginIteration();
-    while (accessor->next()) {
-      typename AccessorGen::NativeTypeConstPtr arg_value =
-          AccessorGen::template GetValuePtr<
-              accessor_nullable, AccessorT>(accessor, attr_id);
-      if (accessor_nullable && AccessorGen::IsNull(arg_value)) {
-        result_cv->appendNullValue();
-      } else {
-        ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
-            literal, AccessorGen::Dereference(arg_value), functor, result_cv);
-      }
-    }
-    return result_cv;
-  }
-
-  template <typename AccessorT>
-  inline ColumnVector* applyToSingleValueAccessor(
-      AccessorT *accessor,
-      const attribute_id left_id,
-      const attribute_id right_id) const {
-    using ResultCVT = typename ResultGen::ColumnVectorType;
-    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
-
-    accessor->beginIteration();
-    while (accessor->next()) {
-      typename LeftGen::NativeTypeConstPtr left_value =
-          LeftGen::template GetValuePtr<
-              left_nullable, AccessorT>(accessor, left_id);
-      if (left_nullable && LeftGen::IsNull(left_value)) {
-        result_cv->appendNullValue();
-        continue;
-      }
-      typename RightGen::NativeTypeConstPtr right_value =
-          RightGen::template GetValuePtr<
-              right_nullable, AccessorT>(accessor, right_id);
-      if (right_nullable && RightGen::IsNull(right_value)) {
-        result_cv->appendNullValue();
-        continue;
-      }
-      ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
-          LeftGen::Dereference(left_value),
-          RightGen::Dereference(right_value),
-          functor,
-          result_cv);
-    }
-    return result_cv;
-  }
-
-  template <typename LeftAccessorT, typename RightAccessorT>
-  inline ColumnVector* applyToValueAccessors(const std::size_t num_tuples,
-                                             LeftAccessorT *left_accessor,
-                                             const attribute_id left_id,
-                                             RightAccessorT *right_accessor,
-                                             const attribute_id right_id) const {
-    DCHECK_EQ(num_tuples, left_accessor->getNumTuples());
-    DCHECK_EQ(num_tuples, right_accessor->getNumTuples());
-
-    using ResultCVT = typename ResultGen::ColumnVectorType;
-    ResultCVT *result_cv = new ResultCVT(result_type, num_tuples);
-
-    left_accessor->beginIteration();
-    right_accessor->beginIteration();
-    while (left_accessor->next()) {
-      right_accessor->next();
-      typename LeftGen::NativeTypeConstPtr left_value =
-          LeftGen::template GetValuePtr<
-              left_nullable, LeftAccessorT>(left_accessor, left_id);
-      if (left_nullable && LeftGen::IsNull(left_value)) {
-        result_cv->appendNullValue();
-        continue;
-      }
-      typename RightGen::NativeTypeConstPtr right_value =
-          RightGen::template GetValuePtr<
-              right_nullable, RightAccessorT>(right_accessor, right_id);
-      if (right_nullable && RightGen::IsNull(right_value)) {
-        result_cv->appendNullValue();
-        continue;
-      }
-      ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
-          LeftGen::Dereference(left_value),
-          RightGen::Dereference(right_value),
-          functor,
-          result_cv);
-    }
-    return result_cv;
-  }
-
-  template <bool supported, typename AccessorT>
-  inline TypedValue accumulateValueAccessor(const TypedValue &current,
-                                            AccessorT *accessor,
-                                            const attribute_id attr_id,
-                                            std::size_t *num_tuples_applied,
-                                            std::enable_if_t<supported>* = 0) const {
-    DCHECK(num_tuples_applied);
-
-    *num_tuples_applied = 0;
-    if (left_nullable && current.isNull()) {
-      return result_type.makeNullValue();
-    }
-
-    using LeftCppType = typename LeftType::cpptype;
-    using ResultCppType = typename ResultType::cpptype;
-    ResultCppType accumulated = current.getLiteral<LeftCppType>();
-
-    accessor->beginIteration();
-    while (accessor->next()) {
-      typename RightGen::NativeTypeConstPtr right_value =
-          RightGen::template GetValuePtr<
-              right_nullable, AccessorT>(accessor, attr_id);
-      if (right_nullable && RightGen::IsNull(right_value)) {
-        continue;
-      }
-
-      accumulated =
-          ResultGen::FunctorSpecializer::Invoke(
-              functor, accumulated, RightGen::Dereference(right_value));
-      ++(*num_tuples_applied);
-    }
-
-    return TypedValue(accumulated);
-  }
-
-  template <bool supported, typename AccessorT>
-  inline TypedValue accumulateValueAccessor(const TypedValue &current,
-                                            AccessorT *accessor,
-                                            const attribute_id attr_id,
-                                            std::size_t *num_tuples_applied,
-                                            std::enable_if_t<!supported>* = 0) const {
-    LOG(FATAL) << "Unimplemented method UncheckedBinaryOperatorWrapperCodegen"
-               << "::accumulateValueAccessor() because ResultType and LeftType "
-               << "are not same or not native types.";
-  }
-
-  const FunctorT &functor;
-  const Type &left_type;
-  const Type &right_type;
-  const Type &result_type;
-};
-
-template <typename FunctorT>
-class BinaryOperationWrapper : public BinaryOperation {
- public:
-  BinaryOperationWrapper()
-      : BinaryOperation(),
-        operation_name_(FunctorT::GetName()) {}
-
-  std::string getName() const override {
-    return operation_name_;
-  }
-
-  std::string getShortName() const override {
-    return getName();
-  }
-
-  std::vector<OperationSignaturePtr> getSignatures() const override {
-    return {
-        OperationSignature::Create(
-            getName(), {LeftType::kStaticTypeID, RightType::kStaticTypeID}, 0)
-    };
-  }
-
-  bool canApplyTo(const Type &left,
-                  const Type &right,
-                  const std::vector<TypedValue> &static_arguments,
-                  std::string *message) const override {
-    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
-    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return true;
-  }
-
-  const Type* getResultType(
-      const Type &left,
-      const Type &right,
-      const std::vector<TypedValue> &static_arguments) const override {
-    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
-    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return getResultTypeImpl<ResultType::kIsParPod>(
-        left, right, static_arguments);
-  }
-
-  UncheckedBinaryOperator* makeUncheckedBinaryOperator(
-      const Type &left,
-      const Type &right,
-      const std::vector<TypedValue> &static_arguments) const override {
-    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
-    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
-    DCHECK(static_arguments.empty());
-    return makeUncheckedBinaryOperatorImpl<
-        std::is_default_constructible<FunctorT>::value>(
-            left, right, static_arguments);
-  }
-
- private:
-  using LeftType = typename FunctorT::LeftArgumentType;
-  using RightType = typename FunctorT::RightArgumentType;
-  using ResultType = typename FunctorT::ResultType;
-
-  template <bool functor_use_default_constructor>
-  inline UncheckedBinaryOperator* makeUncheckedBinaryOperatorImpl(
-      const Type &left,
-      const Type &right,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<functor_use_default_constructor>* = 0) const {
-    return new UncheckedBinaryOperatorWrapperCodegen<FunctorT>(
-        left, right, *getResultType(left, right, static_arguments));
-  }
-
-  template <bool functor_use_default_constructor>
-  inline UncheckedBinaryOperator* makeUncheckedBinaryOperatorImpl(
-      const Type &left,
-      const Type &right,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<!functor_use_default_constructor>* = 0) const {
-    return new UncheckedBinaryOperatorWrapperCodegen<FunctorT>(
-        left, right, *getResultType(left, right, static_arguments),
-        static_cast<const LeftType&>(left),
-        static_cast<const RightType&>(right));
-  }
-
-  template <bool result_type_has_parameter>
-  inline const Type* getResultTypeImpl(
-      const Type &left,
-      const Type &right,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<!result_type_has_parameter>* = 0) const {
-    return &TypeFactory::GetType(
-        ResultType::kStaticTypeID,
-        left.isNullable() || right.isNullable());
-  }
-
-  template <bool result_type_has_parameter>
-  inline const Type* getResultTypeImpl(
-      const Type &left,
-      const Type &right,
-      const std::vector<TypedValue> &static_arguments,
-      std::enable_if_t<result_type_has_parameter>* = 0) const {
-    return FunctorT::GetResultType(left, right);
-  }
-
-  const std::string operation_name_;
-
-  DISALLOW_COPY_AND_ASSIGN(BinaryOperationWrapper);
-};
-
-template <typename LeftPack, typename RightPack,
-          template <typename LeftT,
-                    typename RightT,
-                    typename ResultT> class FunctorT,
-          template <typename LeftT,
-                    typename RightT> class ResultGenerator>
-struct BinaryFunctorCrossProductPack {
-  template <std::size_t l, std::size_t r>
-  inline static OperationPtr GenerateInner() {
-    using LeftType = std::tuple_element_t<l, LeftPack>;
-    using RightType = std::tuple_element_t<r, RightPack>;
-    using ResultType = typename ResultGenerator<LeftType, RightType>::type;
-
-    return std::make_shared<
-        const BinaryOperationWrapper<
-            FunctorT<LeftType, RightType, ResultType>>>();
-  }
-
-  template <std::size_t l, std::size_t ...Rs>
-  inline static std::list<OperationPtr> GenerateRightHelper() {
-    return { GenerateInner<l, Rs>()... };
-  }
-
-  template <std::size_t ...Ls, std::size_t ...Rs>
-  inline static std::vector<std::list<OperationPtr>> GenerateLeftHelper(
-      meta::IntegerSequence<Ls...> &&l_seq, meta::IntegerSequence<Rs...> &&r_seq) {
-    return { GenerateRightHelper<Ls, Rs...>()... };
-  }
-
-  template <typename Dispatcher>
-  inline static std::list<OperationPtr> GenerateOperations() {
-    std::vector<std::list<OperationPtr>> op_list_groups =
-        GenerateLeftHelper(typename meta::MakeSequence<std::tuple_size<LeftPack>::value>::type(),
-                           typename meta::MakeSequence<std::tuple_size<RightPack>::value>::type());
-
-    std::list<OperationPtr> operations;
-    for (std::list<OperationPtr> &op_list : op_list_groups) {
-      operations.splice(operations.end(), std::move(op_list));
-    }
-    return operations;
-  }
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/binary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMakeLists.txt b/types/operations/binary_operations/CMakeLists.txt
index c6fd4e2..dbd6b10 100644
--- a/types/operations/binary_operations/CMakeLists.txt
+++ b/types/operations/binary_operations/CMakeLists.txt
@@ -28,9 +28,9 @@ add_library(quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctor
 add_library(quickstep_types_operations_binaryoperations_BinaryOperation
             BinaryOperation.cpp
             BinaryOperation.hpp)
-add_library(quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+add_library(quickstep_types_operations_binaryoperations_BinaryOperationSynthesizer
             ../../../empty_src.cpp
-            BinaryOperationWrapper.hpp)
+            BinaryOperationSynthesizer.hpp)
 add_library(quickstep_types_operations_binaryoperations_CMathBinaryFunctors
             ../../../empty_src.cpp
             CMathBinaryFunctors.hpp)
@@ -53,17 +53,18 @@ target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBina
                       quickstep_types_TypedValue
                       quickstep_types_YearMonthIntervalType
                       quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
-                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_types_operations_binaryoperations_BinaryOperationSynthesizer
                       quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors
                       glog
                       quickstep_types_CharType
                       quickstep_types_IntType
+                      quickstep_types_TextType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_VarCharType
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_types_port_strnlen)
 target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperation
@@ -73,7 +74,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperatio
                       quickstep_types_operations_Operation
                       quickstep_types_operations_OperationSignature
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperationSynthesizer
                       glog
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_ValueAccessor
@@ -93,7 +94,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_CMathBinaryFun
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
-                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_types_operations_binaryoperations_BinaryOperationSynthesizer
                       quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_utility_meta_Common)
 
@@ -105,7 +106,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations
                       quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
                       quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_types_operations_binaryoperations_BinaryOperationSynthesizer
                       quickstep_types_operations_binaryoperations_CMathBinaryFunctors)
 
 # Tests:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/binary_operations/CMathBinaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMathBinaryFunctors.hpp b/types/operations/binary_operations/CMathBinaryFunctors.hpp
index c6fff3b..00c8979 100644
--- a/types/operations/binary_operations/CMathBinaryFunctors.hpp
+++ b/types/operations/binary_operations/CMathBinaryFunctors.hpp
@@ -27,7 +27,7 @@
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
-#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "types/operations/binary_operations/BinaryOperationSynthesizer.hpp"
 #include "types/operations/utility/OperationSynthesizeUtil.hpp"
 #include "utility/meta/Common.hpp"
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/comparisons/BasicComparison.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/BasicComparison.hpp b/types/operations/comparisons/BasicComparison.hpp
index 1d4bbdc..125942c 100644
--- a/types/operations/comparisons/BasicComparison.hpp
+++ b/types/operations/comparisons/BasicComparison.hpp
@@ -284,19 +284,18 @@ template <template <typename LeftCppType, bool left_type_nullable,
                     bool right_nullable, bool right_null_terminated, bool right_longer> class StringComparator>
 UncheckedComparator* BasicComparison::makeUncheckedComparatorForTypesHelper(const Type &left,
                                                                             const Type &right) const {
-//  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-//    return makeNumericComparatorOuterHelper<LiteralComparator>(left, right);
-//  } else if ((left.getTypeID() == kDate && right.getTypeID() == kDate)                         ||
-//             (left.getTypeID() == kDatetime && right.getTypeID() == kDatetime)                 ||
-//             (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval) ||
-//             (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval)) {
-//    return makeDateComparatorOuterHelper<LiteralComparator>(left, right);
-//  } else if (left.getSuperTypeID() == Type::kAsciiString && right.getSuperTypeID() == Type::kAsciiString) {
-//    return makeStringComparatorOuterHelper<StringComparator>(left, right);
-//  } else {
+  if (left.getSuperTypeID() == SuperTypeID::kNumeric && right.getSuperTypeID() == SuperTypeID::kNumeric) {
+    return makeNumericComparatorOuterHelper<LiteralComparator>(left, right);
+  } else if ((left.getTypeID() == kDate && right.getTypeID() == kDate)                         ||
+             (left.getTypeID() == kDatetime && right.getTypeID() == kDatetime)                 ||
+             (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval) ||
+             (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval)) {
+    return makeDateComparatorOuterHelper<LiteralComparator>(left, right);
+  } else if (left.getSuperTypeID() == SuperTypeID::kAsciiString && right.getSuperTypeID() == SuperTypeID::kAsciiString) {
+    return makeStringComparatorOuterHelper<StringComparator>(left, right);
+  } else {
     throw OperationInapplicableToType(getName(), 2, kTypeNames[left.getTypeID()], kTypeNames[right.getTypeID()]);
-//  }
-  // TODO(refactor-type): Switch back.
+  }
 }
 
 template <template <typename LeftCppType, bool left_type_nullable,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/comparisons/LiteralComparators-inl.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/LiteralComparators-inl.hpp b/types/operations/comparisons/LiteralComparators-inl.hpp
index ad54d4e..b8c4c07 100644
--- a/types/operations/comparisons/LiteralComparators-inl.hpp
+++ b/types/operations/comparisons/LiteralComparators-inl.hpp
@@ -62,8 +62,8 @@ TupleIdSequence* LiteralUncheckedComparator<ComparisonFunctor,
   static constexpr bool short_circuit = false;
 #endif
   // All literal types are usable with NativeColumnVector.
-  DCHECK(left.isNative());
-  DCHECK(right.isNative());
+  DCHECK(left.getImplementation() == ColumnVector::kNative);
+  DCHECK(right.getImplementation() == ColumnVector::kNative);
 
   const NativeColumnVector &left_native = static_cast<const NativeColumnVector&>(left);
   const NativeColumnVector &right_native = static_cast<const NativeColumnVector&>(right);
@@ -155,7 +155,7 @@ TupleIdSequence* LiteralUncheckedComparator<ComparisonFunctor,
   constexpr bool cv_nullable = column_vector_on_left ? left_nullable : right_nullable;
   constexpr bool static_value_nullable = column_vector_on_left ? right_nullable : left_nullable;
 
-  DCHECK(column_vector.isNative());
+  DCHECK(column_vector.getImplementation() == ColumnVector::kNative);
   const NativeColumnVector &native_column_vector
       = static_cast<const NativeColumnVector&>(column_vector);
 
@@ -402,7 +402,7 @@ TupleIdSequence* LiteralUncheckedComparator<ComparisonFunctor,
         const attribute_id value_accessor_attr_id,
         const TupleIdSequence *filter,
         const TupleIdSequence *existence_bitmap) const {
-  DCHECK(column_vector.isNative());
+  DCHECK(column_vector.getImplementation() == ColumnVector::kNative);
   const NativeColumnVector &native_column_vector
       = static_cast<const NativeColumnVector&>(column_vector);
 
@@ -642,7 +642,7 @@ TypedValue LiteralUncheckedComparator<ComparisonFunctor,
   const void *current_literal = current.isNull() ? nullptr : current.getDataPtr();
 
   // All literal types are usable with NativeColumnVector.
-  DCHECK(column_vector.isNative());
+  DCHECK(column_vector.getImplementation() == ColumnVector::kNative);
 
   const NativeColumnVector &native_vector = static_cast<const NativeColumnVector&>(column_vector);
   for (std::size_t pos = 0; pos < native_vector.size(); ++pos) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp b/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp
index ad45535..0eaddef 100644
--- a/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp
+++ b/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp
@@ -28,7 +28,7 @@
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
 #include "types/YearMonthIntervalType.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "types/operations/utility/OperationSynthesizeUtil.hpp"
 
 namespace quickstep {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/unary_operations/AsciiStringUnaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/AsciiStringUnaryFunctors.hpp b/types/operations/unary_operations/AsciiStringUnaryFunctors.hpp
index 34a78ab..a232dd8 100644
--- a/types/operations/unary_operations/AsciiStringUnaryFunctors.hpp
+++ b/types/operations/unary_operations/AsciiStringUnaryFunctors.hpp
@@ -30,7 +30,7 @@
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/VarCharType.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/unary_operations/UnaryOperationSynthesizer.hpp"
 #include "types/operations/utility/OperationSynthesizeUtil.hpp"
 #include "types/port/strnlen.hpp"
 #include "utility/meta/Common.hpp"


[16/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/preprocessed/SqlParser_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.cpp b/parser/preprocessed/SqlParser_gen.cpp
index 72c61dd..f3fedbc 100644
--- a/parser/preprocessed/SqlParser_gen.cpp
+++ b/parser/preprocessed/SqlParser_gen.cpp
@@ -138,22 +138,16 @@ typedef struct YYLTYPE {
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
-#include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "types/operations/comparisons/Comparison.hpp"
 #include "types/operations/comparisons/ComparisonFactory.hpp"
 #include "types/operations/comparisons/ComparisonID.hpp"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationFactory.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
 #include "utility/PtrList.hpp"
 #include "utility/PtrVector.hpp"
 
 // Needed for Bison 2.6 and higher, which do not automatically provide this typedef.
 typedef void* yyscan_t;
 
-#line 157 "SqlParser_gen.cpp" /* yacc.c:339  */
+#line 151 "SqlParser_gen.cpp" /* yacc.c:339  */
 
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -224,104 +218,105 @@ extern int quickstep_yydebug;
     TOKEN_CSB_TREE = 291,
     TOKEN_BY = 292,
     TOKEN_CASE = 293,
-    TOKEN_CHARACTER = 294,
-    TOKEN_CHECK = 295,
-    TOKEN_COLUMN = 296,
-    TOKEN_CONSTRAINT = 297,
-    TOKEN_COPY = 298,
-    TOKEN_CREATE = 299,
-    TOKEN_CURRENT = 300,
-    TOKEN_DATE = 301,
-    TOKEN_DATETIME = 302,
-    TOKEN_DAY = 303,
-    TOKEN_DECIMAL = 304,
-    TOKEN_DEFAULT = 305,
-    TOKEN_DELETE = 306,
-    TOKEN_DESC = 307,
-    TOKEN_DISTINCT = 308,
-    TOKEN_DOUBLE = 309,
-    TOKEN_DROP = 310,
-    TOKEN_ELSE = 311,
-    TOKEN_END = 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_STDERR = 368,
-    TOKEN_STDOUT = 369,
-    TOKEN_SUBSTRING = 370,
-    TOKEN_TABLE = 371,
-    TOKEN_THEN = 372,
-    TOKEN_TIME = 373,
-    TOKEN_TIMESTAMP = 374,
-    TOKEN_TO = 375,
-    TOKEN_TRUE = 376,
-    TOKEN_TUPLESAMPLE = 377,
-    TOKEN_UNBOUNDED = 378,
-    TOKEN_UNIQUE = 379,
-    TOKEN_UPDATE = 380,
-    TOKEN_USING = 381,
-    TOKEN_VALUES = 382,
-    TOKEN_VARCHAR = 383,
-    TOKEN_WHEN = 384,
-    TOKEN_WHERE = 385,
-    TOKEN_WINDOW = 386,
-    TOKEN_WITH = 387,
-    TOKEN_YEAR = 388,
-    TOKEN_YEARMONTH = 389,
-    TOKEN_EOF = 390,
-    TOKEN_LEX_ERROR = 391
+    TOKEN_CAST = 294,
+    TOKEN_CHARACTER = 295,
+    TOKEN_CHECK = 296,
+    TOKEN_COLUMN = 297,
+    TOKEN_CONSTRAINT = 298,
+    TOKEN_COPY = 299,
+    TOKEN_CREATE = 300,
+    TOKEN_CURRENT = 301,
+    TOKEN_DATE = 302,
+    TOKEN_DATETIME = 303,
+    TOKEN_DAY = 304,
+    TOKEN_DECIMAL = 305,
+    TOKEN_DEFAULT = 306,
+    TOKEN_DELETE = 307,
+    TOKEN_DESC = 308,
+    TOKEN_DISTINCT = 309,
+    TOKEN_DOUBLE = 310,
+    TOKEN_DROP = 311,
+    TOKEN_ELSE = 312,
+    TOKEN_END = 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_STDERR = 369,
+    TOKEN_STDOUT = 370,
+    TOKEN_SUBSTRING = 371,
+    TOKEN_TABLE = 372,
+    TOKEN_THEN = 373,
+    TOKEN_TIME = 374,
+    TOKEN_TIMESTAMP = 375,
+    TOKEN_TO = 376,
+    TOKEN_TRUE = 377,
+    TOKEN_TUPLESAMPLE = 378,
+    TOKEN_UNBOUNDED = 379,
+    TOKEN_UNIQUE = 380,
+    TOKEN_UPDATE = 381,
+    TOKEN_USING = 382,
+    TOKEN_VALUES = 383,
+    TOKEN_VARCHAR = 384,
+    TOKEN_WHEN = 385,
+    TOKEN_WHERE = 386,
+    TOKEN_WINDOW = 387,
+    TOKEN_WITH = 388,
+    TOKEN_YEAR = 389,
+    TOKEN_YEARMONTH = 390,
+    TOKEN_EOF = 391,
+    TOKEN_LEX_ERROR = 392
   };
 #endif
 
@@ -330,7 +325,7 @@ extern int quickstep_yydebug;
 
 union YYSTYPE
 {
-#line 121 "../SqlParser.ypp" /* yacc.c:355  */
+#line 115 "../SqlParser.ypp" /* yacc.c:355  */
 
   quickstep::ParseString *string_value_;
 
@@ -402,8 +397,8 @@ union YYSTYPE
   quickstep::ParseStatementQuit *quit_statement_;
 
   const quickstep::Comparison *comparison_;
-  const quickstep::UnaryOperation *unary_operation_;
-  const quickstep::BinaryOperation *binary_operation_;
+  quickstep::ParseString *unary_operation_;
+  quickstep::ParseString *binary_operation_;
 
   quickstep::ParseFunctionCall *function_call_;
   quickstep::PtrList<quickstep::ParseExpression> *expression_list_;
@@ -431,7 +426,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 435 "SqlParser_gen.cpp" /* yacc.c:355  */
+#line 430 "SqlParser_gen.cpp" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -460,13 +455,13 @@ int quickstep_yyparse (yyscan_t yyscanner, quickstep::ParseStatement **parsedSta
 #endif /* !YY_QUICKSTEP_YY_SQLPARSER_GEN_HPP_INCLUDED  */
 
 /* Copy the second part of user declarations.  */
-#line 222 "../SqlParser.ypp" /* yacc.c:358  */
+#line 216 "../SqlParser.ypp" /* yacc.c:358  */
 
 /* This header needs YYSTYPE, which is defined by the %union directive above */
 #include "SqlLexer_gen.hpp"
 void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature);
 
-#line 470 "SqlParser_gen.cpp" /* yacc.c:358  */
+#line 465 "SqlParser_gen.cpp" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -710,21 +705,21 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  50
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1391
+#define YYLAST   1389
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  148
+#define YYNTOKENS  149
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  110
+#define YYNNTS  111
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  298
+#define YYNRULES  301
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  550
+#define YYNSTATES  559
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   391
+#define YYMAXUTOK   392
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -734,11 +729,11 @@ union yyalloc
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     143,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     144,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,   147,     2,     2,
-     144,   145,    23,    21,   146,    22,    27,    24,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,   142,
+       2,     2,     2,     2,     2,     2,     2,   148,     2,     2,
+     145,   146,    23,    21,   147,    22,    27,    24,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,   143,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -772,43 +767,44 @@ static const yytype_uint8 yytranslate[] =
      110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
      120,   121,   122,   123,   124,   125,   126,   127,   128,   129,
      130,   131,   132,   133,   134,   135,   136,   137,   138,   139,
-     140,   141
+     140,   141,   142
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   640,   640,   644,   648,   652,   656,   659,   666,   669,
-     672,   675,   678,   681,   684,   687,   690,   693,   699,   705,
-     712,   718,   725,   734,   739,   748,   753,   758,   762,   768,
-     773,   776,   779,   784,   787,   790,   793,   796,   799,   802,
-     805,   808,   811,   823,   826,   829,   847,   867,   870,   873,
-     878,   883,   889,   895,   904,   908,   914,   917,   922,   927,
-     932,   939,   946,   950,   956,   959,   964,   967,   972,   975,
-     980,   983,  1002,  1005,  1010,  1014,  1020,  1023,  1026,  1029,
-    1034,  1037,  1040,  1047,  1052,  1063,  1068,  1073,  1077,  1081,
-    1087,  1090,  1096,  1104,  1107,  1110,  1116,  1121,  1126,  1130,
-    1136,  1140,  1143,  1148,  1151,  1156,  1161,  1166,  1170,  1176,
-    1185,  1188,  1193,  1196,  1215,  1220,  1224,  1230,  1236,  1245,
-    1250,  1258,  1264,  1270,  1273,  1276,  1281,  1284,  1289,  1293,
-    1299,  1302,  1305,  1310,  1315,  1320,  1323,  1326,  1331,  1334,
-    1337,  1340,  1343,  1346,  1349,  1352,  1357,  1360,  1365,  1369,
-    1373,  1376,  1380,  1383,  1388,  1391,  1396,  1399,  1404,  1408,
-    1414,  1417,  1422,  1425,  1430,  1433,  1438,  1441,  1460,  1463,
-    1468,  1472,  1478,  1484,  1489,  1492,  1497,  1500,  1505,  1508,
-    1513,  1516,  1521,  1522,  1525,  1530,  1531,  1534,  1539,  1543,
-    1549,  1556,  1559,  1562,  1567,  1570,  1573,  1579,  1582,  1587,
-    1592,  1601,  1606,  1615,  1620,  1623,  1628,  1631,  1636,  1642,
-    1648,  1651,  1654,  1657,  1660,  1663,  1669,  1678,  1681,  1686,
-    1689,  1694,  1697,  1702,  1705,  1708,  1711,  1715,  1719,  1722,
-    1725,  1728,  1731,  1736,  1740,  1744,  1747,  1752,  1757,  1761,
-    1767,  1770,  1775,  1779,  1785,  1790,  1794,  1800,  1805,  1808,
-    1813,  1817,  1823,  1826,  1829,  1832,  1844,  1848,  1867,  1880,
-    1895,  1898,  1901,  1904,  1907,  1910,  1915,  1919,  1925,  1928,
-    1933,  1937,  1944,  1947,  1950,  1953,  1956,  1959,  1962,  1965,
-    1968,  1971,  1976,  1987,  1990,  1995,  1998,  2001,  2007,  2011,
-    2017,  2020,  2028,  2031,  2034,  2037,  2043,  2048,  2053
+       0,   634,   634,   638,   642,   646,   650,   653,   660,   663,
+     666,   669,   672,   675,   678,   681,   684,   687,   693,   699,
+     706,   712,   719,   728,   733,   742,   747,   752,   756,   762,
+     767,   770,   773,   778,   781,   784,   787,   790,   793,   796,
+     799,   802,   805,   817,   820,   823,   841,   861,   864,   867,
+     872,   877,   883,   889,   898,   902,   908,   911,   916,   921,
+     926,   933,   940,   944,   950,   953,   958,   961,   966,   969,
+     974,   977,   996,   999,  1004,  1008,  1014,  1017,  1020,  1023,
+    1028,  1031,  1034,  1041,  1046,  1057,  1062,  1067,  1071,  1075,
+    1081,  1084,  1090,  1098,  1101,  1104,  1110,  1115,  1120,  1124,
+    1130,  1134,  1137,  1142,  1145,  1150,  1155,  1160,  1164,  1170,
+    1179,  1182,  1187,  1190,  1209,  1214,  1218,  1224,  1230,  1239,
+    1244,  1252,  1258,  1264,  1267,  1270,  1275,  1278,  1283,  1287,
+    1293,  1296,  1299,  1304,  1309,  1314,  1317,  1320,  1325,  1328,
+    1331,  1334,  1337,  1340,  1343,  1346,  1351,  1354,  1359,  1363,
+    1367,  1370,  1374,  1377,  1382,  1385,  1390,  1393,  1398,  1402,
+    1408,  1411,  1416,  1419,  1424,  1427,  1432,  1435,  1454,  1457,
+    1462,  1466,  1472,  1478,  1483,  1486,  1491,  1494,  1499,  1502,
+    1507,  1510,  1515,  1516,  1519,  1524,  1525,  1528,  1533,  1537,
+    1543,  1550,  1553,  1556,  1561,  1564,  1567,  1573,  1576,  1581,
+    1586,  1595,  1600,  1609,  1614,  1617,  1622,  1625,  1630,  1636,
+    1642,  1645,  1648,  1651,  1654,  1657,  1663,  1672,  1678,  1683,
+    1689,  1694,  1699,  1704,  1707,  1710,  1713,  1717,  1721,  1724,
+    1727,  1730,  1733,  1736,  1741,  1745,  1749,  1752,  1757,  1771,
+    1782,  1793,  1801,  1812,  1815,  1820,  1824,  1830,  1835,  1839,
+    1845,  1850,  1853,  1858,  1862,  1868,  1871,  1874,  1877,  1889,
+    1893,  1912,  1925,  1940,  1943,  1946,  1949,  1952,  1955,  1960,
+    1964,  1970,  1973,  1978,  1982,  1989,  1992,  1995,  1998,  2001,
+    2004,  2007,  2010,  2013,  2016,  2021,  2032,  2035,  2040,  2043,
+    2046,  2052,  2056,  2062,  2065,  2073,  2076,  2079,  2082,  2088,
+    2093,  2098
 };
 #endif
 
@@ -827,19 +823,20 @@ static const char *const yytname[] =
   "TOKEN_ALTER", "TOKEN_AS", "TOKEN_ASC", "TOKEN_BIGINT", "TOKEN_BIT",
   "TOKEN_BITWEAVING", "TOKEN_BLOCKPROPERTIES", "TOKEN_BLOCKSAMPLE",
   "TOKEN_BLOOM_FILTER", "TOKEN_CSB_TREE", "TOKEN_BY", "TOKEN_CASE",
-  "TOKEN_CHARACTER", "TOKEN_CHECK", "TOKEN_COLUMN", "TOKEN_CONSTRAINT",
-  "TOKEN_COPY", "TOKEN_CREATE", "TOKEN_CURRENT", "TOKEN_DATE",
-  "TOKEN_DATETIME", "TOKEN_DAY", "TOKEN_DECIMAL", "TOKEN_DEFAULT",
-  "TOKEN_DELETE", "TOKEN_DESC", "TOKEN_DISTINCT", "TOKEN_DOUBLE",
-  "TOKEN_DROP", "TOKEN_ELSE", "TOKEN_END", "TOKEN_EXISTS", "TOKEN_EXTRACT",
-  "TOKEN_FALSE", "TOKEN_FIRST", "TOKEN_FLOAT", "TOKEN_FOLLOWING",
-  "TOKEN_FOR", "TOKEN_FOREIGN", "TOKEN_FROM", "TOKEN_FULL", "TOKEN_GROUP",
-  "TOKEN_HASH", "TOKEN_HAVING", "TOKEN_HOUR", "TOKEN_IN", "TOKEN_INDEX",
-  "TOKEN_INNER", "TOKEN_INSERT", "TOKEN_INTEGER", "TOKEN_INTERVAL",
-  "TOKEN_INTO", "TOKEN_JOIN", "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT",
-  "TOKEN_LIMIT", "TOKEN_LONG", "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL",
-  "TOKEN_NULLS", "TOKEN_OFF", "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER",
-  "TOKEN_OVER", "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
+  "TOKEN_CAST", "TOKEN_CHARACTER", "TOKEN_CHECK", "TOKEN_COLUMN",
+  "TOKEN_CONSTRAINT", "TOKEN_COPY", "TOKEN_CREATE", "TOKEN_CURRENT",
+  "TOKEN_DATE", "TOKEN_DATETIME", "TOKEN_DAY", "TOKEN_DECIMAL",
+  "TOKEN_DEFAULT", "TOKEN_DELETE", "TOKEN_DESC", "TOKEN_DISTINCT",
+  "TOKEN_DOUBLE", "TOKEN_DROP", "TOKEN_ELSE", "TOKEN_END", "TOKEN_EXISTS",
+  "TOKEN_EXTRACT", "TOKEN_FALSE", "TOKEN_FIRST", "TOKEN_FLOAT",
+  "TOKEN_FOLLOWING", "TOKEN_FOR", "TOKEN_FOREIGN", "TOKEN_FROM",
+  "TOKEN_FULL", "TOKEN_GROUP", "TOKEN_HASH", "TOKEN_HAVING", "TOKEN_HOUR",
+  "TOKEN_IN", "TOKEN_INDEX", "TOKEN_INNER", "TOKEN_INSERT",
+  "TOKEN_INTEGER", "TOKEN_INTERVAL", "TOKEN_INTO", "TOKEN_JOIN",
+  "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT", "TOKEN_LIMIT", "TOKEN_LONG",
+  "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL", "TOKEN_NULLS", "TOKEN_OFF",
+  "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER", "TOKEN_OVER",
+  "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
   "TOKEN_PRECEDING", "TOKEN_PRIMARY", "TOKEN_PRIORITY", "TOKEN_QUIT",
   "TOKEN_RANGE", "TOKEN_REAL", "TOKEN_REFERENCES", "TOKEN_RIGHT",
   "TOKEN_ROW", "TOKEN_ROW_DELIMITER", "TOKEN_ROWS", "TOKEN_SECOND",
@@ -878,7 +875,7 @@ static const char *const yytname[] =
   "opt_order_direction", "opt_nulls_first", "opt_where_clause",
   "where_clause", "or_expression", "and_expression", "not_expression",
   "predicate_expression_base", "add_expression", "multiply_expression",
-  "unary_expression", "expression_base", "function_call",
+  "unary_expression", "expression_base", "function_call", "cast_function",
   "extract_function", "substr_function", "case_expression",
   "simple_when_clause_list", "simple_when_clause",
   "searched_when_clause_list", "searched_when_clause", "opt_else_clause",
@@ -909,14 +906,14 @@ static const yytype_uint16 yytoknum[] =
      360,   361,   362,   363,   364,   365,   366,   367,   368,   369,
      370,   371,   372,   373,   374,   375,   376,   377,   378,   379,
      380,   381,   382,   383,   384,   385,   386,   387,   388,   389,
-     390,   391,    59,    10,    40,    41,    44,    37
+     390,   391,   392,    59,    10,    40,    41,    44,    37
 };
 # endif
 
-#define YYPACT_NINF -395
+#define YYPACT_NINF -286
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-395)))
+  (!!((Yystate) == (-286)))
 
 #define YYTABLE_NINF -139
 
@@ -927,61 +924,62 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     174,  -395,  -395,   -64,    85,   -26,    14,   -31,   -16,  -395,
-      40,   196,   196,  -395,   109,   102,  -395,  -395,  -395,  -395,
-    -395,  -395,  -395,  -395,  -395,  -395,   148,    -3,    87,  -395,
-     -40,   121,   196,  -395,  -395,     1,    -5,   196,   196,   196,
-     196,   196,  -395,  -395,   716,    82,     2,  -395,   153,    63,
-    -395,  -395,  -395,    98,   152,    -3,    40,   141,  -395,    98,
-    -395,  -395,  -395,    12,    97,   116,   261,   116,   169,   126,
-     138,  -395,   176,  -395,  -395,   270,   274,  -395,  -395,  -395,
-     807,   139,  -395,   210,  -395,  -395,   154,  -395,  -395,   297,
-    -395,  -395,  -395,  -395,   172,  -395,  -395,   177,   231,   901,
-     313,   265,   192,  -395,  -395,   338,    23,  -395,  -395,   243,
-    -395,  -395,  -395,  -395,  -395,  1083,    -7,   196,   196,   214,
-     196,     1,   196,  -395,    98,   363,  -395,   205,   263,  -395,
-    -395,  -395,   255,  -395,   116,  -395,   196,   196,   625,  -395,
-    -395,   262,   196,  -395,  -395,  -395,   625,    33,   -29,  -395,
-     409,  -395,   165,   165,  1174,   411,  -395,   -14,    28,  -395,
-      13,   138,  1174,  -395,  -395,   196,  1174,  -395,  -395,  -395,
-    -395,  1174,    18,   274,  -395,   196,   398,    59,  -395,   417,
-    -395,    98,  -395,   202,  -395,   116,    98,    87,  -395,   196,
-      80,   196,   196,   196,  -395,   285,  -395,   211,  1241,   992,
-     214,   534,   422,   423,  -395,  -395,   312,   415,  1252,   219,
-      43,  1174,    61,  -395,  1174,  -395,   369,   292,  -395,  -395,
-    -395,  -395,  -395,  -395,   367,  -395,   216,   294,  -395,  -395,
-       7,   186,   267,  -395,   298,   186,     3,   372,  -395,  -395,
-      23,  -395,   347,  -395,  -395,   295,  1174,  -395,   351,   229,
-     196,  -395,  1174,  -395,   196,  -395,  -395,  -395,   303,   366,
-     368,   304,  -395,  -395,  -395,   232,  -395,  -395,  -395,  -395,
-    -395,    34,   196,   323,    80,   196,  -395,   188,  -395,  -395,
-       4,    65,   625,   625,   276,  -395,  -395,  -395,  -395,  -395,
-    -395,  -395,  -395,  1174,   311,  1174,    51,  -395,   234,   326,
-    1174,    71,  -395,   399,   351,  -395,  -395,  1174,   453,  -395,
-     160,   196,  -395,  -395,   370,  -395,   373,   374,   379,    13,
-    -395,   457,   462,   186,   430,   400,   431,   329,   380,  -395,
-     236,  -395,  1174,  -395,   351,  -395,   625,   333,   334,   196,
-    -395,   196,  -395,  -395,  -395,  -395,  -395,  -395,  -395,   196,
-    -395,  -395,  -395,   238,   454,   184,  -395,   336,   348,  -395,
-     391,   342,  1252,  -395,   403,   196,  -395,  -395,   188,  -395,
-    -395,   423,  -395,  -395,  -395,  1174,   345,   341,   901,  -395,
-     351,   401,  -395,  -395,  1252,   350,   351,  1174,  -395,    37,
-      35,  -395,  -395,  -395,  -395,  -395,    13,   267,   390,   395,
-    -395,  1174,   625,   396,  1174,  -395,   455,   108,  -395,   351,
-       8,   196,   196,   240,  -395,   242,  -395,   196,  -395,  -395,
-    -395,  -395,   354,    80,   461,   402,  -395,   625,  -395,  -395,
-     356,  -395,   346,   901,  -395,  1174,   245,  -395,  -395,  1252,
-     351,  -395,   495,  -395,   408,  -395,  -395,   358,   422,   464,
-     420,   358,  1174,  -395,  -395,  -395,   490,  -395,   249,   251,
-    -395,  -395,  -395,   196,  -395,  -395,   375,   468,  -395,    19,
-     196,  1174,   264,   351,  -395,   266,   371,   625,  1174,   504,
-     376,   377,  -395,   227,    46,   405,  -395,   269,   196,    -9,
-    -395,   381,   351,  -395,  -395,  -395,   422,   377,  -395,   196,
-    -395,   376,  -395,  1174,  -395,  -395,   421,   418,   407,   425,
-     515,   196,  -395,   277,  -395,  -395,   384,  -395,   496,  -395,
-    -395,    49,  -395,  -395,  -395,  -395,    56,   386,  -395,   196,
-     388,  -395,  -395,   466,   426,   467,  -395,   196,   279,   347,
-    -395,  -395,  -395,   281,   445,   404,  -395,   539,  -395,  -395
+     254,  -286,  -286,   -65,    71,   -18,   133,   -19,    28,  -286,
+      40,   190,   190,  -286,   209,    79,  -286,  -286,  -286,  -286,
+    -286,  -286,  -286,  -286,  -286,  -286,   168,    45,   183,  -286,
+     150,   238,   190,  -286,  -286,    13,    77,   190,   190,   190,
+     190,   190,  -286,  -286,   704,   118,   105,  -286,   225,   120,
+    -286,  -286,  -286,   148,   186,    45,    40,   179,  -286,   148,
+    -286,  -286,  -286,   164,    18,   159,   285,   159,   204,   162,
+     174,  -286,   -37,  -286,  -286,   307,   312,  -286,  -286,  -286,
+     771,   178,   194,  -286,   258,  -286,  -286,   198,  -286,  -286,
+     344,  -286,  -286,  -286,  -286,   207,  -286,  -286,   211,   282,
+     865,   353,   300,   227,  -286,  -286,   349,    24,  -286,  -286,
+     276,  -286,  -286,  -286,  -286,  -286,  -286,  1026,   -13,   190,
+     190,   236,   190,    13,   190,  -286,   148,   347,  -286,   248,
+     270,  -286,  -286,  -286,   239,  -286,   159,  -286,   190,   190,
+     610,  -286,  -286,   246,   190,  -286,  -286,  -286,   610,    50,
+     -16,  -286,  1093,   379,  -286,   146,   146,  1093,   387,  -286,
+       0,    29,  -286,    20,   174,  1093,  -286,  -286,   190,  1093,
+    -286,  -286,  -286,  -286,  1093,    21,   312,  -286,   190,   406,
+     -81,  -286,   389,  -286,   148,  -286,   175,  -286,   159,   148,
+     183,  -286,   190,    -7,   190,   190,   190,  -286,   274,  -286,
+     215,  1249,   932,   236,   543,   408,   416,  -286,  -286,   315,
+     420,  1237,   217,    10,  1093,     1,  -286,  1093,  -286,   380,
+     226,   298,  -286,  -286,  -286,  -286,  -286,  -286,   374,  -286,
+      85,   301,  -286,  -286,    11,   220,   228,  -286,   306,   220,
+      56,   381,  -286,  -286,    24,  -286,   348,  -286,  -286,   308,
+    1093,  -286,   346,   231,   190,  -286,  1093,  -286,   190,  -286,
+    -286,  -286,   311,   371,   376,   318,  -286,  -286,  -286,   233,
+    -286,  -286,  -286,  -286,  -286,    15,   190,   328,    -7,   190,
+    -286,   152,  -286,  -286,     2,    72,   610,   610,   210,  -286,
+    -286,  -286,  -286,  -286,  -286,  -286,  -286,  1093,   319,  1093,
+      60,  -286,   241,   334,  1093,    58,  -286,   407,   346,  -286,
+    1153,  -286,  1093,   462,  -286,   163,   190,  -286,  -286,   375,
+    -286,   378,   382,   393,    20,  -286,   465,   472,   220,   439,
+     409,   440,   337,   390,  -286,   243,  -286,  1093,  -286,   346,
+    -286,   610,   339,   341,   190,  -286,   190,  -286,  -286,  -286,
+    -286,  -286,  -286,  -286,   190,  -286,  -286,  -286,   250,   463,
+     170,  -286,   345,   356,  -286,   398,   350,  1237,  -286,   411,
+     190,  -286,  -286,   152,  -286,  -286,   416,  -286,  -286,  -286,
+    1093,   355,    92,   865,  -286,   346,   405,  -286,  -286,  1237,
+     357,   346,  1093,  -286,   359,   360,    31,    51,  -286,  -286,
+    -286,  -286,  -286,    20,   228,   399,   401,  -286,  1093,   610,
+     410,  1093,  -286,   466,   126,  -286,   346,    22,   190,   190,
+     255,  -286,   257,  -286,   190,  -286,  -286,  -286,  -286,   364,
+      -7,   473,   412,  -286,   610,  -286,  -286,   365,  -286,   259,
+     865,  -286,  1093,   262,  -286,  -286,  1237,   346,  -286,  -286,
+    -286,   506,  -286,   419,  -286,  -286,   370,   408,   476,   430,
+     370,  1093,  -286,  -286,  -286,   501,  -286,   271,   275,  -286,
+    -286,  -286,   190,  -286,  -286,   377,   479,  -286,    30,   190,
+    1093,   277,   346,  -286,   284,   383,   610,  1093,   516,   388,
+     385,  -286,   325,    25,   417,  -286,   286,   190,    17,  -286,
+     391,   346,  -286,  -286,  -286,   408,   385,  -286,   190,  -286,
+     388,  -286,  1093,  -286,  -286,   434,   432,   422,   433,   529,
+     190,  -286,   288,  -286,  -286,   394,  -286,   508,  -286,  -286,
+      38,  -286,  -286,  -286,  -286,    49,   400,  -286,   190,   413,
+    -286,  -286,   474,   443,   475,  -286,   190,   290,   348,  -286,
+    -286,  -286,   292,   454,   414,  -286,   549,  -286,  -286
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -989,93 +987,96 @@ static const yytype_int16 yypact[] =
      means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
-       0,     6,   298,     0,     0,     0,     0,     0,     0,    18,
+       0,     6,   301,     0,     0,     0,     0,     0,     0,    18,
      123,     0,     0,     7,     0,     0,    15,     8,    10,    11,
       13,    14,     9,    17,    12,    16,     0,   112,   119,   121,
-       0,   296,     0,   290,   291,     0,     0,     0,     0,     0,
+       0,   299,     0,   293,   294,     0,     0,     0,     0,     0,
        0,     0,   124,   125,     0,     0,   114,   115,     0,   156,
        1,     3,     2,     0,     0,   112,   123,     0,   110,     0,
-       5,     4,   297,     0,     0,   103,     0,   103,     0,     0,
-     197,    25,     0,   256,   253,     0,   282,   126,    40,    29,
-       0,     0,    30,    31,    34,    36,     0,    37,    39,     0,
-      41,   252,    35,    38,     0,    32,    33,     0,     0,     0,
-       0,     0,   127,   128,   232,   132,   218,   220,   222,   225,
-     228,   229,   230,   224,   223,     0,   268,     0,     0,     0,
-       0,     0,     0,   111,     0,     0,   120,     0,     0,   100,
-     102,   101,     0,    98,   103,    97,     0,     0,     0,   106,
-     198,     0,     0,    94,   254,   255,     0,     0,   248,   245,
-       0,    43,     0,   257,     0,     0,    44,     0,     0,   259,
-       0,   197,     0,   283,   284,     0,     0,   131,   286,   287,
-     285,     0,     0,     0,   221,     0,     0,   197,   108,     0,
-     116,     0,   117,     0,   288,   103,     0,   118,   113,     0,
-       0,     0,     0,     0,    96,    66,    27,     0,     0,     0,
-       0,     0,   199,   201,   203,   205,     0,   223,     0,     0,
-       0,     0,   248,   242,     0,   246,     0,     0,   262,   263,
-     264,   261,   265,   260,     0,   258,     0,     0,   134,   231,
-       0,     0,   158,   147,   133,   152,   135,   160,   129,   130,
-     217,   219,   174,   226,   269,     0,     0,   233,   250,     0,
-       0,   105,     0,   157,     0,    99,    95,    19,     0,     0,
-       0,     0,    20,    21,    22,     0,    74,    76,    77,    78,
-      79,     0,     0,     0,    64,     0,    42,    56,   204,   212,
-       0,     0,     0,     0,     0,   272,   274,   275,   276,   277,
-     273,   278,   280,     0,     0,     0,     0,   266,     0,     0,
-       0,     0,   243,     0,   249,   241,    45,     0,     0,    46,
-     138,     0,   148,   154,   144,   139,   140,   142,     0,     0,
-     151,     0,     0,   150,     0,   162,     0,     0,   176,   234,
-       0,   235,     0,   107,   109,   289,     0,     0,     0,     0,
-     104,     0,    81,    84,    82,   294,   295,   293,   292,     0,
-      80,    85,   270,     0,   268,     0,    63,    65,    68,    28,
-       0,     0,     0,    47,     0,     0,    49,    55,    57,    26,
-     211,   200,   202,   279,   281,     0,     0,     0,     0,   213,
-     210,     0,   209,    93,     0,     0,   247,     0,   240,     0,
-       0,   153,   155,   145,   141,   143,     0,   159,     0,     0,
-     149,     0,     0,   164,     0,   227,     0,   178,   236,   251,
-       0,     0,     0,     0,    75,     0,    67,     0,    86,    87,
-      88,    89,    90,     0,     0,    70,    48,     0,    51,    50,
-       0,    54,     0,     0,   215,     0,     0,   208,   267,     0,
-     244,   237,     0,   238,     0,   136,   137,   161,   163,     0,
-     166,   175,     0,   181,   180,   173,     0,    61,     0,     0,
-      58,    83,   271,     0,    24,    62,     0,     0,    23,     0,
-       0,     0,     0,   206,   214,     0,     0,     0,     0,     0,
-     168,   177,   188,   191,     0,     0,    59,     0,     0,     0,
-      52,     0,   207,   216,    92,   239,   146,   165,   167,     0,
-     122,   169,   170,     0,   192,   193,   194,     0,     0,     0,
-       0,     0,    91,     0,    72,    73,     0,    53,     0,   171,
-     189,     0,   190,   182,   184,   183,     0,     0,    69,     0,
-       0,   195,   196,     0,     0,     0,   179,     0,     0,   174,
-     185,   187,   186,     0,     0,     0,    60,     0,   172,    71
+       5,     4,   300,     0,     0,   103,     0,   103,     0,     0,
+     197,    25,     0,   259,   256,     0,   285,   126,    40,    29,
+       0,     0,     0,    30,    31,    34,    36,     0,    37,    39,
+       0,    41,   255,    35,    38,     0,    32,    33,     0,     0,
+       0,     0,     0,   127,   128,   233,   132,   218,   220,   222,
+     225,   228,   229,   230,   231,   224,   223,     0,   271,     0,
+       0,     0,     0,     0,     0,   111,     0,     0,   120,     0,
+       0,   100,   102,   101,     0,    98,   103,    97,     0,     0,
+       0,   106,   198,     0,     0,    94,   257,   258,     0,     0,
+     251,   248,     0,     0,    43,     0,   260,     0,     0,    44,
+       0,     0,   262,     0,   197,     0,   286,   287,     0,     0,
+     131,   289,   290,   288,     0,     0,     0,   221,     0,     0,
+     197,   108,     0,   116,     0,   117,     0,   291,   103,     0,
+     118,   113,     0,     0,     0,     0,     0,    96,    66,    27,
+       0,     0,     0,     0,     0,   199,   201,   203,   205,     0,
+     223,     0,     0,     0,     0,   251,   245,     0,   249,     0,
+       0,     0,   265,   266,   267,   264,   268,   263,     0,   261,
+       0,     0,   134,   232,     0,     0,   158,   147,   133,   152,
+     135,   160,   129,   130,   217,   219,   174,   226,   272,     0,
+       0,   234,   253,     0,     0,   105,     0,   157,     0,    99,
+      95,    19,     0,     0,     0,     0,    20,    21,    22,     0,
+      74,    76,    77,    78,    79,     0,     0,     0,    64,     0,
+      42,    56,   204,   212,     0,     0,     0,     0,     0,   275,
+     277,   278,   279,   280,   276,   281,   283,     0,     0,     0,
+       0,   269,     0,     0,     0,     0,   246,     0,   252,   244,
+       0,    45,     0,     0,    46,   138,     0,   148,   154,   144,
+     139,   140,   142,     0,     0,   151,     0,     0,   150,     0,
+     162,     0,     0,   176,   235,     0,   236,     0,   107,   109,
+     292,     0,     0,     0,     0,   104,     0,    81,    84,    82,
+     297,   298,   296,   295,     0,    80,    85,   273,     0,   271,
+       0,    63,    65,    68,    28,     0,     0,     0,    47,     0,
+       0,    49,    55,    57,    26,   211,   200,   202,   282,   284,
+       0,     0,     0,     0,   213,   210,     0,   209,    93,     0,
+       0,   250,     0,   243,     0,     0,     0,     0,   153,   155,
+     145,   141,   143,     0,   159,     0,     0,   149,     0,     0,
+     164,     0,   227,     0,   178,   237,   254,     0,     0,     0,
+       0,    75,     0,    67,     0,    86,    87,    88,    89,    90,
+       0,     0,    70,    48,     0,    51,    50,     0,    54,     0,
+       0,   215,     0,     0,   208,   270,     0,   247,   238,   239,
+     240,     0,   241,     0,   136,   137,   161,   163,     0,   166,
+     175,     0,   181,   180,   173,     0,    61,     0,     0,    58,
+      83,   274,     0,    24,    62,     0,     0,    23,     0,     0,
+       0,     0,   206,   214,     0,     0,     0,     0,     0,   168,
+     177,   188,   191,     0,     0,    59,     0,     0,     0,    52,
+       0,   207,   216,    92,   242,   146,   165,   167,     0,   122,
+     169,   170,     0,   192,   193,   194,     0,     0,     0,     0,
+       0,    91,     0,    72,    73,     0,    53,     0,   171,   189,
+       0,   190,   182,   184,   183,     0,     0,    69,     0,     0,
+     195,   196,     0,     0,     0,   179,     0,     0,   174,   185,
+     187,   186,     0,     0,     0,    60,     0,   172,    71
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -395,  -395,  -395,  -395,  -395,  -395,  -395,  -395,  -164,  -395,
-     349,   180,  -395,  -395,  -271,  -395,  -395,  -395,  -395,  -395,
-    -395,  -394,   209,  -395,  -395,  -395,  -395,  -395,  -395,  -395,
-    -395,    24,   -46,  -395,  -395,  -395,   301,  -395,   497,  -395,
-    -395,   435,   259,   433,   -28,   498,  -395,  -395,   397,  -395,
-     -90,  -395,  -395,  -207,   162,  -187,   -10,  -395,  -395,  -395,
-    -395,  -395,  -395,  -395,    60,    21,  -395,  -395,  -395,  -395,
-    -395,  -395,    84,    62,  -395,  -395,   -54,  -395,  -145,   282,
-     280,   382,   -35,   406,   412,   451,  -156,  -395,  -395,  -395,
-    -395,   355,  -395,   427,   359,  -232,  -203,   429,   129,  -128,
-    -395,  -395,  -395,  -395,  -395,  -136,    -4,  -395,  -395,  -395
+    -286,  -286,  -286,  -286,  -286,  -286,  -286,  -286,  -132,  -286,
+    -152,   184,  -286,  -286,  -275,  -286,  -286,  -286,  -286,  -286,
+    -286,  -285,   213,  -286,  -286,  -286,  -286,  -286,  -286,  -286,
+    -286,     4,    -8,  -286,  -286,  -286,   309,  -286,   507,  -286,
+    -286,   441,   240,   442,   -28,   510,  -286,  -286,   402,  -286,
+    -105,  -286,  -286,  -193,   166,  -185,   -11,  -286,  -286,  -286,
+    -286,  -286,  -286,  -286,    61,    26,  -286,  -286,  -286,  -286,
+    -286,  -286,    83,    63,  -286,  -286,    52,  -286,  -142,   287,
+     289,   392,   -35,   403,   415,   460,  -161,  -286,  -286,  -286,
+    -286,  -286,   366,  -286,   435,   367,  -238,  -200,   424,   137,
+    -135,  -286,  -286,  -286,  -286,  -286,  -140,    -4,  -286,  -286,
+    -286
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    14,    15,    16,    17,    18,    19,    20,   196,   197,
-     100,   367,   368,   369,   262,   357,   358,   273,   425,   468,
-     516,   265,   266,   267,   268,   269,   270,   422,   464,    21,
-      22,    65,   133,    23,    24,   177,   178,    25,    58,    26,
-      46,    47,   157,    28,    29,    44,   101,   102,   103,   161,
-     104,   323,   318,   232,   233,   312,   313,   234,   325,   403,
-     450,   480,   500,   501,   502,   327,   328,   407,   455,   456,
-     510,   536,   481,   482,   506,   522,   139,   140,   202,   203,
-     204,   205,   206,   106,   107,   108,   109,   110,   111,   112,
-     212,   213,   148,   149,   216,   249,   113,   224,   298,   114,
-     353,   295,   115,   166,   171,   183,   116,   351,    30,    31
+      -1,    14,    15,    16,    17,    18,    19,    20,   199,   200,
+     101,   372,   373,   374,   266,   362,   363,   277,   432,   477,
+     525,   269,   270,   271,   272,   273,   274,   429,   473,    21,
+      22,    65,   135,    23,    24,   180,   181,    25,    58,    26,
+      46,    47,   160,    28,    29,    44,   102,   103,   104,   164,
+     105,   328,   323,   236,   237,   317,   318,   238,   330,   410,
+     459,   489,   509,   510,   511,   332,   333,   414,   464,   465,
+     519,   545,   490,   491,   515,   531,   141,   142,   205,   206,
+     207,   208,   209,   107,   108,   109,   110,   111,   112,   113,
+     114,   215,   216,   150,   151,   219,   253,   115,   228,   302,
+     116,   358,   299,   117,   169,   174,   186,   118,   356,    30,
+      31
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -1083,386 +1084,386 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      36,   210,    48,   356,   235,   297,   209,    45,    49,   105,
-     207,    33,   282,    34,   330,    56,   282,    33,   207,    34,
-     175,   135,    33,   310,    34,   257,    56,   282,    63,   182,
-      56,   126,   214,    68,    69,    70,    71,    72,    33,   342,
-      34,   343,   321,   127,   143,   147,   168,   169,   320,   163,
-     164,   282,    37,   507,   163,   164,   280,    32,   163,   164,
-      67,   381,   344,   533,   158,   514,    66,    41,    42,   487,
-     231,   207,   128,   207,   235,   284,   285,   286,   287,   288,
-     289,   290,   291,   292,   293,    39,   163,   164,   194,    33,
-      40,    34,   163,   164,   513,    38,   508,   515,    43,   345,
-      60,   167,   129,    61,   442,   146,   534,   237,    48,    50,
-     279,   359,   397,   179,    49,   531,   184,    59,   186,   226,
-      64,    10,   214,   251,    62,   258,    64,   105,   346,   347,
-     322,   228,   195,   198,    57,   532,   400,   176,   184,   255,
-     231,   248,   294,   382,   352,   185,   436,   176,   118,   370,
-     259,   230,   465,   457,   207,   207,   236,   230,   256,   428,
-     348,   239,   242,   235,   490,   300,   281,   211,   243,   447,
-     170,   244,   451,   229,   509,     1,   301,     2,   349,   304,
-     443,   438,   441,   260,   535,   198,   119,   263,   264,   271,
-      33,   410,    34,   387,   138,   211,    53,   117,   360,    10,
-      33,   472,    34,   413,   379,   250,     3,   120,   207,   261,
-     229,   248,    10,   415,   453,   130,   131,   334,   218,   311,
-     454,   418,     4,     5,   419,   420,   236,    49,    54,   231,
-       6,    49,   314,   361,     7,   122,   297,   163,   164,   315,
-     235,   219,    51,   362,    52,   125,   179,   316,   163,   164,
-     335,   189,   190,   132,     8,   220,   221,   448,   377,    27,
-     380,   504,    10,    35,   136,   386,   134,   350,   354,   317,
-     137,   198,   389,   138,   207,   458,   459,   144,   222,     9,
-     363,   145,   469,   150,   505,    55,   434,   308,    10,   462,
-      10,   364,   151,   373,   374,   375,   365,   409,   152,   207,
-     421,   392,   153,   223,    11,   391,   231,    49,   141,   191,
-     192,    12,   121,   156,    13,   236,   154,   366,   159,    49,
-     142,   155,   284,   285,   286,   287,   288,   289,   290,   291,
-     292,   293,   496,   163,   164,   184,   160,   271,   162,   314,
-     432,   172,    33,   248,    34,   184,   315,   253,   254,   207,
-     435,  -138,   440,   376,   316,   471,   274,   275,   181,   163,
-     164,   430,   163,   164,   299,   254,   248,   163,   164,   248,
-     188,   165,   163,   164,   331,   332,   317,   340,   341,   383,
-     384,   408,   332,   416,   417,   460,   254,   461,   254,   294,
-     474,   332,   236,   538,   485,   254,   486,   254,   248,   193,
-     473,   543,    33,    73,    34,    74,   208,   184,   184,   493,
-     332,   494,   384,   354,   512,   341,   217,   483,   227,    75,
-      76,   245,   528,   341,   544,   254,   546,   254,   252,   272,
-     282,   305,   283,    78,    79,   296,   492,   306,   307,   309,
-     329,    80,    81,   483,   319,   324,   326,   336,   339,    82,
-      83,   337,    84,   338,   355,   378,   246,    85,   385,   271,
-     390,   388,    86,   396,   398,    87,   491,   393,   483,   399,
-     394,   395,   401,   404,   405,   402,   406,   411,   412,    88,
-      89,   175,   423,   426,   271,   424,   427,    90,   429,   433,
-      91,   445,   449,   437,   439,   518,   446,   452,   463,   466,
-     470,   467,   476,   477,   332,    92,   478,   527,   479,   484,
-     489,   498,   499,   511,   521,    93,   495,   524,    94,   488,
-     523,    95,    96,   503,   526,   184,   517,   525,   529,   530,
-     537,    97,   539,   184,   540,   542,   541,    98,    33,    73,
-      34,    74,    99,   247,   199,   547,   549,   277,   431,   548,
-     414,   333,   123,   180,   124,    75,    76,   187,   444,   238,
-     545,   519,   497,   372,   371,   520,   174,   302,   475,    78,
-      79,   303,   240,     0,     0,   215,     0,    80,    81,     0,
-       0,   278,   225,   241,     0,    82,    83,     0,    84,     0,
-       0,     0,     0,    85,     0,     0,     0,   200,    86,     0,
-       0,    87,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    88,    89,     0,     0,     0,
-       0,     0,     0,    90,     0,     0,    91,     0,     0,    33,
-      73,    34,    74,     0,     0,   199,     0,     0,     0,     0,
-       0,    92,     0,     0,     0,     0,    75,    76,    10,     0,
-       0,    93,     0,     0,    94,     0,     0,    95,    96,     0,
-      78,    79,     0,     0,     0,     0,     0,    97,    80,    81,
-       0,     0,     0,    98,     0,     0,    82,    83,   201,    84,
-       0,     0,     0,     0,    85,     0,     0,     0,   200,    86,
-       0,     0,    87,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    88,    89,     0,     0,
-       0,     0,     0,     0,    90,     0,     0,    91,     0,     0,
+      36,    48,   239,   361,   212,   210,   213,    45,    49,   106,
+     286,   301,   335,   210,   178,    33,   185,    34,   286,    33,
+     347,    34,   348,   131,    33,    33,    34,    34,    63,    56,
+     286,   128,   516,    68,    69,    70,    71,    72,   286,   262,
+      67,   315,    56,   349,   145,   149,   217,   171,   172,   281,
+     166,   167,   166,   167,   325,   140,   542,    32,   235,   137,
+     261,    37,   284,   217,   263,   161,   254,   210,    42,   210,
+     386,   166,   167,   239,    56,    33,   517,    34,    10,   166,
+     167,   350,   288,   289,   290,   291,   292,   293,   294,   295,
+     296,   297,   523,   166,   167,   326,   143,   264,   283,    43,
+     543,   442,   170,    40,    38,   540,   166,   167,   144,    48,
+     351,   352,    41,   166,   167,   182,    49,   220,   187,   148,
+     189,   451,   230,   265,   524,   541,    10,   188,   197,   235,
+     106,   404,   179,   304,   198,   201,   214,   132,   133,    64,
+     187,   357,   353,   407,   252,   443,   232,   364,   375,    66,
+     298,   210,   210,   387,   518,   474,   234,   313,   394,   240,
+     354,   260,   365,   239,   243,   234,   246,   435,   466,   285,
+     456,   247,   173,   460,   248,   233,   499,   450,   544,   305,
+     259,   392,   308,    57,   327,   214,    10,   496,   201,   445,
+     267,   268,   275,   384,    33,   129,    34,   452,   366,   417,
+     222,   179,   481,    64,   420,    39,   210,   425,   367,    50,
+     426,   427,   522,    59,   422,   252,   241,    53,   233,   235,
+      51,   339,    52,   223,    33,   130,    34,   378,   379,   380,
+     240,    49,   255,   462,   119,    49,   319,   224,   225,   463,
+      27,    62,   239,   320,    35,   368,   301,   166,   167,    54,
+     182,   321,   120,   316,   340,     1,   369,     2,   121,   310,
+     226,   370,   382,    10,   385,   122,    55,   457,   480,   391,
+     124,   355,   359,   322,   210,   201,   441,   396,   467,   468,
+     166,   167,   371,    10,   127,   227,     3,   428,   381,   471,
+     136,    60,   478,   123,    61,   192,   193,   134,   235,   210,
+     138,   319,   416,     4,     5,   399,   395,   139,   320,   398,
+     140,     6,    49,  -138,   146,     7,   321,   194,   195,   147,
+     240,   257,   258,   152,    49,   288,   289,   290,   291,   292,
+     293,   294,   295,   296,   297,     8,   166,   167,   322,   153,
+     187,   154,   275,   155,   505,   439,   166,   167,   252,   156,
+     187,   210,   157,    33,   191,    34,   158,   447,   162,   513,
+       9,   278,   279,   303,   258,   159,   437,   166,   167,    10,
+     166,   167,   163,   252,   165,   175,   252,   336,   337,   345,
+     346,   184,   168,   514,   196,    11,   221,   388,   389,   415,
+     337,   211,    12,   298,   231,    13,   423,   424,   547,   240,
+     256,   469,   258,   470,   258,   252,   552,   482,   483,   337,
+      33,    73,    34,    74,   187,   187,   286,   494,   258,   276,
+     359,   495,   258,   502,   337,   287,   492,    75,    76,   249,
+     503,   389,   521,   346,   537,   346,   553,   258,   555,   258,
+     300,    78,    79,   309,   311,   501,   312,   314,   331,    80,
+      81,    82,   492,   324,   334,   329,   341,   342,    83,    84,
+     360,    85,   343,   344,   383,   250,    86,   390,   275,   397,
+     393,    87,   405,   400,    88,   500,   401,   492,   403,   406,
+     402,   408,   411,   412,   418,   409,   419,   413,    89,    90,
+     178,   433,   430,   275,   431,   434,    91,   436,   444,    92,
+     440,   454,   446,   455,   527,   448,   449,   458,   461,   472,
+     479,   475,   476,   485,    93,   486,   536,   337,   487,   488,
+     493,   498,   497,   507,    94,   508,   520,    95,   530,   504,
+      96,    97,   512,   533,   187,   532,   534,   526,   535,   538,
+      98,   539,   187,   549,   551,   546,    99,    33,    73,    34,
+      74,   100,   251,   202,   550,   556,   558,   438,   548,   421,
+     557,   183,   125,   338,    75,    76,   126,   242,   190,   453,
+     506,   528,   244,   376,   554,   529,   377,   177,    78,    79,
+     229,   306,   307,   484,     0,   218,    80,    81,    82,   245,
+       0,     0,     0,     0,   282,    83,    84,     0,    85,     0,
+       0,     0,     0,    86,     0,     0,     0,   203,    87,     0,
+       0,    88,     0,     0,    33,    73,    34,    74,     0,     0,
+     202,     0,     0,     0,     0,    89,    90,     0,     0,     0,
+       0,    75,    76,    91,     0,     0,    92,     0,     0,     0,
+       0,     0,     0,     0,     0,    78,    79,     0,     0,     0,
+       0,    93,     0,    80,    81,    82,     0,     0,    10,     0,
+       0,    94,    83,    84,    95,    85,     0,    96,    97,     0,
+      86,     0,     0,     0,   203,    87,     0,    98,    88,     0,
+       0,     0,     0,    99,     0,     0,     0,     0,   204,     0,
+       0,     0,    89,    90,     0,     0,     0,     0,     0,     0,
+      91,     0,     0,    92,     0,     0,     0,     0,    33,    73,
+      34,    74,     0,     0,     0,     0,     0,     0,    93,     0,
+       0,     0,     0,     0,     0,    75,    76,    77,    94,     0,
+       0,    95,     0,     0,    96,    97,     0,     0,     0,    78,
+      79,     0,     0,     0,    98,     0,     0,    80,    81,    82,
+      99,     0,     0,     0,     0,   204,    83,    84,     0,    85,
+       0,     0,     0,     0,    86,     0,     0,     0,     0,    87,
+       0,     0,    88,     0,     0,    33,    73,    34,    74,     0,
+       0,     0,     0,     0,     0,     0,    89,    90,     0,     0,
+       0,     0,    75,    76,    91,     0,     0,    92,     0,     0,
+       0,     0,     0,     0,     0,     0,    78,    79,     0,     0,
+       0,     0,    93,     0,    80,    81,    82,     0,     0,     0,
+       0,     0,    94,    83,    84,    95,    85,     0,    96,    97,
+       0,    86,     0,     0,     0,     0,    87,     0,    98,    88,
+       0,     0,     0,     0,    99,     0,     0,     0,     0,   100,
+       0,     0,     0,    89,    90,     0,     0,     0,     0,     0,
+       0,    91,     0,     0,    92,     0,     0,     0,     0,    33,
+      73,    34,    74,     0,     0,     0,     0,     0,     0,    93,
+       0,     0,     0,     0,     0,     0,    75,    76,     0,    94,
+       0,     0,    95,     0,     0,    96,    97,     0,     0,     0,
+      78,    79,     0,     0,     0,    98,   148,     0,    80,    81,
+      82,    99,     0,     0,     0,     0,   100,    83,    84,     0,
+      85,     0,     0,     0,     0,    86,     0,     0,     0,     0,
+      87,     0,     0,    88,     0,     0,    33,    73,    34,    74,
+       0,     0,     0,     0,     0,     0,     0,    89,    90,     0,
+       0,     0,     0,    75,    76,    91,     0,     0,    92,     0,
+       0,     0,     0,     0,     0,     0,     0,    78,    79,     0,
+       0,     0,     0,    93,     0,    80,    81,    82,     0,     0,
+      10,     0,     0,    94,    83,    84,    95,    85,     0,    96,
+      97,     0,    86,     0,     0,     0,   203,    87,     0,    98,
+      88,     0,     0,     0,     0,    99,     0,     0,     0,     0,
+     100,     0,     0,     0,    89,    90,     0,     0,     0,     0,
+       0,     0,    91,     0,     0,    92,     0,     0,     0,     0,
       33,    73,    34,    74,     0,     0,     0,     0,     0,     0,
-       0,     0,    92,     0,     0,     0,     0,    75,    76,    77,
-       0,     0,    93,     0,     0,    94,     0,     0,    95,    96,
-       0,    78,    79,     0,     0,     0,     0,     0,    97,    80,
-      81,     0,     0,     0,    98,     0,     0,    82,    83,   201,
-      84,     0,     0,     0,     0,    85,     0,     0,     0,     0,
-      86,     0,     0,    87,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    88,    89,     0,
-       0,     0,     0,     0,     0,    90,     0,     0,    91,     0,
-       0,    33,    73,    34,    74,     0,     0,     0,     0,     0,
-       0,     0,     0,    92,     0,     0,     0,     0,    75,    76,
-       0,     0,     0,    93,     0,     0,    94,     0,     0,    95,
-      96,     0,    78,    79,     0,     0,     0,     0,     0,    97,
-      80,    81,     0,     0,     0,    98,     0,     0,    82,    83,
-      99,    84,     0,     0,     0,     0,    85,     0,     0,     0,
-       0,    86,     0,     0,    87,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    88,    89,
-       0,     0,     0,     0,     0,     0,    90,     0,     0,    91,
-       0,     0,     0,     0,     0,    33,    73,    34,    74,     0,
-       0,     0,     0,     0,    92,     0,     0,     0,     0,     0,
-       0,     0,    75,    76,    93,     0,     0,    94,     0,     0,
-      95,    96,     0,     0,     0,     0,    78,    79,     0,     0,
-      97,   146,     0,     0,    80,    81,    98,     0,     0,     0,
-       0,    99,    82,    83,     0,    84,     0,     0,     0,     0,
-      85,     0,     0,     0,     0,    86,     0,     0,    87,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    88,    89,     0,     0,     0,     0,     0,     0,
-      90,     0,     0,    91,     0,     0,    33,    73,    34,    74,
-       0,     0,     0,     0,     0,     0,     0,     0,    92,     0,
-       0,     0,     0,    75,    76,    10,     0,     0,    93,     0,
-       0,    94,     0,     0,    95,    96,     0,    78,    79,     0,
-       0,     0,     0,     0,    97,    80,    81,     0,     0,     0,
-      98,     0,     0,    82,    83,    99,    84,     0,     0,     0,
-       0,    85,     0,     0,     0,   200,    86,     0,     0,    87,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    88,    89,     0,     0,     0,     0,     0,
-       0,    90,     0,     0,    91,     0,     0,    33,    73,    34,
-      74,     0,     0,     0,     0,     0,     0,     0,     0,    92,
-       0,     0,     0,     0,    75,   173,     0,     0,     0,    93,
-       0,     0,    94,     0,     0,    95,    96,     0,    78,    79,
-       0,     0,     0,     0,     0,    97,    80,    81,     0,     0,
-       0,    98,     0,     0,    82,    83,   201,    84,     0,     0,
-       0,     0,    85,     0,     0,     0,     0,    86,     0,     0,
-      87,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    88,    89,     0,     0,     0,     0,
-       0,     0,    90,     0,     0,    91,     0,     0,    33,    73,
-      34,    74,     0,     0,     0,     0,     0,     0,     0,     0,
-      92,     0,     0,     0,     0,    75,    76,     0,     0,     0,
-      93,     0,     0,    94,     0,     0,    95,    96,     0,    78,
-      79,     0,     0,     0,     0,     0,    97,    80,    81,     0,
-       0,     0,    98,     0,     0,    82,    83,    99,    84,     0,
-       0,     0,     0,    85,     0,     0,     0,     0,    86,     0,
-       0,    87,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    88,    89,    73,     0,    74,
-       0,     0,     0,    90,     0,     0,    91,     0,     0,     0,
-       0,     0,     0,    75,   173,     0,    78,    79,     0,     0,
-       0,    92,     0,     0,     0,    81,     0,    78,    79,     0,
-       0,    93,    82,    83,    94,    84,    81,    95,    96,     0,
-      85,     0,     0,    82,    83,     0,    84,    97,    87,     0,
-       0,    85,     0,    98,     0,     0,     0,     0,    99,    87,
-       0,     0,    88,   276,     0,     0,     0,     0,     0,     0,
-      90,     0,     0,    88,    89,     0,     0,     0,     0,     0,
-       0,    90,     0,     0,    91,     0,     0,     0,    92,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    93,    92,
-       0,     0,     0,     0,    95,    96,     0,     0,     0,    93,
-       0,     0,     0,     0,    97,    95,    96,     0,     0,     0,
-      98,     0,     0,     0,     0,    97,     0,     0,     0,     0,
-       0,    98
+      93,     0,     0,     0,     0,     0,     0,    75,   176,     0,
+      94,     0,     0,    95,     0,     0,    96,    97,     0,     0,
+       0,    78,    79,     0,     0,     0,    98,     0,     0,    80,
+      81,    82,    99,     0,     0,     0,     0,   204,    83,    84,
+       0,    85,     0,     0,     0,     0,    86,     0,     0,     0,
+       0,    87,     0,     0,    88,     0,     0,    33,    73,    34,
+      74,     0,     0,     0,     0,     0,     0,     0,    89,    90,
+       0,     0,     0,     0,    75,    76,    91,     0,     0,    92,
+       0,     0,     0,     0,     0,     0,     0,     0,    78,    79,
+       0,     0,     0,     0,    93,     0,    80,    81,    82,     0,
+       0,     0,     0,     0,    94,    83,    84,    95,    85,     0,
+      96,    97,     0,    86,     0,     0,     0,    33,    87,    34,
+      98,    88,     0,     0,     0,     0,    99,     0,     0,     0,
+       0,   100,     0,     0,     0,    89,    90,     0,     0,     0,
+       0,     0,     0,    91,     0,     0,    92,     0,    78,    79,
+       0,     0,     0,     0,     0,     0,     0,     0,    82,     0,
+       0,    93,     0,     0,     0,    83,    84,     0,    85,     0,
+       0,    94,     0,    86,    95,     0,     0,    96,    97,     0,
+       0,    88,     0,     0,     0,     0,     0,    98,     0,     0,
+       0,     0,     0,    99,     0,    89,   280,     0,   100,     0,
+       0,     0,    73,    91,    74,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    75,   176,
+       0,    93,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    94,    78,    79,     0,     0,     0,    96,    97,     0,
+       0,     0,    82,     0,    78,    79,     0,    98,     0,    83,
+      84,     0,    85,    99,    82,     0,     0,    86,     0,     0,
+       0,    83,    84,     0,    85,    88,     0,     0,     0,    86,
+       0,     0,     0,     0,     0,     0,     0,    88,     0,    89,
+      90,     0,     0,     0,     0,     0,     0,    91,     0,     0,
+      92,    89,   280,     0,     0,     0,     0,     0,     0,    91,
+       0,     0,     0,     0,     0,    93,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    94,     0,    93,     0,     0,
+       0,    96,    97,     0,     0,     0,     0,    94,     0,     0,
+       0,    98,     0,    96,    97,     0,     0,    99,     0,     0,
+       0,     0,     0,    98,     0,     0,     0,     0,     0,    99
 };
 
 static const yytype_int16 yycheck[] =
 {
-       4,   146,    12,   274,   160,   208,   142,    11,    12,    44,
-     138,     4,     8,     6,   246,    29,     8,     4,   146,     6,
-      27,    67,     4,   230,     6,   189,    29,     8,    32,   119,
-      29,    59,    61,    37,    38,    39,    40,    41,     4,     5,
-       6,     7,    39,    31,    72,    80,    23,    24,   235,    21,
-      22,     8,    78,     7,    21,    22,   201,   121,    21,    22,
-      36,    10,    28,     7,    99,    74,    71,    83,    28,   463,
-     160,   199,    60,   201,   230,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    71,    21,    22,   134,     4,
-     121,     6,    21,    22,   488,   121,    50,   106,    58,    65,
-     140,   105,     5,   143,    69,   134,    50,   161,   118,     0,
-     200,   275,   319,   117,   118,    66,   120,    30,   122,   154,
-     125,   114,    61,   177,     3,    45,   125,   162,    94,    95,
-     127,   145,   136,   137,   137,    86,   323,   144,   142,   185,
-     230,   176,    77,    92,   272,   121,   378,   144,   146,   145,
-      70,   144,   423,   145,   282,   283,   160,   144,   186,   362,
-     126,   165,   144,   319,   145,   122,   201,   134,   172,   401,
-     147,   175,   404,   145,   128,     1,   211,     3,   144,   214,
-     145,   384,   145,   103,   128,   189,    33,   191,   192,   193,
-       4,   336,     6,   122,   135,   134,    48,   115,    10,   114,
-       4,   433,     6,   339,   294,   146,    32,   144,   336,   129,
-     145,   246,   114,   349,   106,   118,   119,   252,    53,    33,
-     112,    37,    48,    49,    40,    41,   230,   231,    80,   319,
-      56,   235,    72,    45,    60,    83,   439,    21,    22,    79,
-     396,    76,   140,    55,   142,   104,   250,    87,    21,    22,
-     254,    46,    47,   137,    80,    90,    91,   402,   293,     0,
-     295,    34,   114,     4,    95,   300,     5,   271,   272,   109,
-     144,   275,   307,   135,   402,   411,   412,     7,   113,   105,
-      92,     7,   427,   144,    57,    26,   376,    71,   114,   417,
-     114,   103,    82,    17,    18,    19,   108,   332,   144,   427,
-     116,   311,     5,   138,   130,   145,   396,   311,   132,    46,
-      47,   137,    53,    82,   140,   319,   144,   129,     5,   323,
-     144,   144,    10,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,   477,    21,    22,   339,    71,   341,   146,    72,
-     375,    98,     4,   378,     6,   349,    79,   145,   146,   477,
-       9,    84,   387,    77,    87,     9,   145,   146,   144,    21,
-      22,   365,    21,    22,   145,   146,   401,    21,    22,   404,
-       7,    33,    21,    22,   145,   146,   109,   145,   146,   145,
-     146,   145,   146,   145,   146,   145,   146,   145,   146,    77,
-     145,   146,   396,   529,   145,   146,   145,   146,   433,   144,
-     435,   537,     4,     5,     6,     7,   144,   411,   412,   145,
-     146,   145,   146,   417,   145,   146,     7,   452,     7,    21,
-      22,    23,   145,   146,   145,   146,   145,   146,    11,   144,
-       8,    62,     9,    35,    36,    20,   471,   145,    71,   145,
-     145,    43,    44,   478,   146,    73,    99,   144,   144,    51,
-      52,    85,    54,    85,   131,   144,    58,    59,   132,   463,
-       7,    62,    64,    84,     7,    67,   470,    97,   503,     7,
-      97,    97,    42,    42,   145,    75,    96,   144,   144,    81,
-      82,    27,   146,    92,   488,   137,   144,    89,    85,   144,
-      92,   101,    96,    92,   144,   499,   101,    42,   144,    38,
-     144,    99,     7,    95,   146,   107,    42,   511,    88,    19,
-      42,     7,   136,   108,    93,   117,   145,   110,   120,   144,
-     102,   123,   124,   146,     9,   529,   145,   102,   144,    33,
-     144,   133,   144,   537,    68,    68,   110,   139,     4,     5,
-       6,     7,   144,   145,    10,   100,     7,   198,   368,   145,
-     341,   250,    55,   118,    56,    21,    22,   124,   396,   162,
-     539,   501,   478,   283,   282,   503,   115,   212,   439,    35,
-      36,   212,   166,    -1,    -1,   148,    -1,    43,    44,    -1,
-      -1,   199,   153,   171,    -1,    51,    52,    -1,    54,    -1,
-      -1,    -1,    -1,    59,    -1,    -1,    -1,    63,    64,    -1,
-      -1,    67,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    81,    82,    -1,    -1,    -1,
-      -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,     4,
-       5,     6,     7,    -1,    -1,    10,    -1,    -1,    -1,    -1,
-      -1,   107,    -1,    -1,    -1,    -1,    21,    22,   114,    -1,
-      -1,   117,    -1,    -1,   120,    -1,    -1,   123,   124,    -1,
-      35,    36,    -1,    -1,    -1,    -1,    -1,   133,    43,    44,
-      -1,    -1,    -1,   139,    -1,    -1,    51,    52,   144,    54,
-      -1,    -1,    -1,    -1,    59,    -1,    -1,    -1,    63,    64,
-      -1,    -1,    67,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    81,    82,    -1,    -1,
-      -1,    -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,
+       4,    12,   163,   278,   144,   140,   148,    11,    12,    44,
+       8,   211,   250,   148,    27,     4,   121,     6,     8,     4,
+       5,     6,     7,     5,     4,     4,     6,     6,    32,    29,
+       8,    59,     7,    37,    38,    39,    40,    41,     8,    46,
+      36,   234,    29,    28,    72,    80,    62,    23,    24,   201,
+      21,    22,    21,    22,   239,   136,     7,   122,   163,    67,
+     192,    79,   204,    62,    71,   100,   147,   202,    28,   204,
+      10,    21,    22,   234,    29,     4,    51,     6,   115,    21,
+      22,    66,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    75,    21,    22,    39,   133,   104,   203,    59,
+      51,     9,   106,   122,   122,    67,    21,    22,   145,   120,
+      95,    96,    84,    21,    22,   119,   120,   152,   122,   135,
+     124,    70,   157,   130,   107,    87,   115,   123,   136,   234,
+     165,   324,   145,   123,   138,   139,   135,   119,   120,   126,
+     144,   276,   127,   328,   179,   383,   146,   279,   146,    72,
+      78,   286,   287,    93,   129,   430,   145,    72,   310,   163,
+     145,   189,    10,   324,   168,   145,   145,   367,   146,   204,
+     408,   175,   148,   411,   178,   146,   146,   146,   129,   214,
+     188,   123,   217,   138,   128,   135,   115,   472,   192,   389,
+     194,   195,   196,   298,     4,    31,     6,   146,    46,   341,
+      54,   145,   440,   126,   344,    72,   341,    37,    56,     0,
+      40,    41,   497,    30,   354,   250,   164,    49,   146,   324,
+     141,   256,   143,    77,     4,    61,     6,    17,    18,    19,
+     234,   235,   180,   107,   116,   239,    73,    91,    92,   113,
+       0,     3,   403,    80,     4,    93,   446,    21,    22,    81,
+     254,    88,   147,    33,   258,     1,   104,     3,    33,    33,
+     114,   109,   297,   115,   299,   145,    26,   409,     9,   304,
+      84,   275,   276,   110,   409,   279,   381,   312,   418,   419,
+      21,    22,   130,   115,   105,   139,    32,   117,    78,   424,
+       5,   141,   434,    53,   144,    47,    48,   138,   403,   434,
+      96,    73,   337,    49,    50,   316,   310,   145,    80,   146,
+     136,    57,   316,    85,     7,    61,    88,    47,    48,     7,
+     324,   146,   147,   145,   328,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    81,    21,    22,   110,   145,
+     344,    83,   346,   145,   486,   380,    21,    22,   383,     5,
+     354,   486,   145,     4,     7,     6,   145,   392,     5,    34,
+     106,   146,   147,   146,   147,    83,   370,    21,    22,   115,
+      21,    22,    72,   408,   147,    99,   411,   146,   147,   146,
+     147,   145,    33,    58,   145,   131,     7,   146,   147,   146,
+     147,   145,   138,    78,     7,   141,   146,   147,   538,   403,
+      11,   146,   147,   146,   147,   440,   546,   442,   146,   147,
+       4,     5,     6,     7,   418,   419,     8,   146,   147,   145,
+     424,   146,   147,   146,   147,     9,   461,    21,    22,    23,
+     146,   147,   146,   147,   146,   147,   146,   147,   146,   147,
+      20,    35,    36,    63,   146,   480,    72,   146,   100,    43,
+      44,    45,   487,   147,   146,    74,   145,    86,    52,    53,
+     132,    55,    86,   145,   145,    59,    60,   133,   472,     7,
+      63,    65,     7,    98,    68,   479,    98,   512,    85,     7,
+      98,    42,    42,   146,   145,    76,   145,    97,    82,    83,
+      27,    93,   147,   497,   138,   145,    90,    86,    93,    93,
+     145,   102,   145,   102,   508,   146,   146,    97,    42,   145,
+     145,    38,   100,     7,   108,    96,   520,   147,    42,    89,
+      19,    42,   145,     7,   118,   137,   109,   121,    94,   146,
+     124,   125,   147,   111,   538,   103,   103,   146,     9,   145,
+     134,    33,   546,    69,    69,   145,   140,     4,     5,     6,
+       7,   145,   146,    10,   111,   101,     7,   373,   145,   346,
+     146,   120,    55,   254,    21,    22,    56,   165,   126,   403,
+     487,   510,   169,   286,   548,   512,   287,   117,    35,    36,
+     156,   215,   215,   446,    -1,   150,    43,    44,    45,   174,
+      -1,    -1,    -1,    -1,   202,    52,    53,    -1,    55,    -1,
+      -1,    -1,    -1,    60,    -1,    -1,    -1,    64,    65,    -1,
+      -1,    68,    -1,    -1,     4,     5,     6,     7,    -1,    -1,
+      10,    -1,    -1,    -1,    -1,    82,    83,    -1,    -1,    -1,
+      -1,    21,    22,    90,    -1,    -1,    93,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    35,    36,    -1,    -1,    -1,
+      -1,   108,    -1,    43,    44,    45,    -1,    -1,   115,    -1,
+      -1,   118,    52,    53,   121,    55,    -1,   124,   125,    -1,
+      60,    -1,    -1,    -1,    64,    65,    -1,   134,    68,    -1,
+      -1,    -1,    -1,   140,    -1,    -1,    -1,    -1,   145,    -1,
+      -1,    -1,    82,    83,    -1,    -1,    -1,    -1,    -1,    -1,
+      90,    -1,    -1,    93,    -1,    -1,    -1,    -1,     4,     5,
+       6,     7,    -1,    -1,    -1,    -1,    -1,    -1,   108,    -1,
+      -1,    -1,    -1,    -1,    -1,    21,    22,    23,   118,    -1,
+      -1,   121,    -1,    -1,   124,   125,    -1,    -1,    -1,    35,
+      36,    -1,    -1,    -1,   134,    -1,    -1,    43,    44,    45,
+     140,    -1,    -1,    -1,    -1,   145,    52,    53,    -1,    55,
+      -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,    65,
+      -1,    -1,    68,    -1,    -1,     4,     5,     6,     7,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    82,    83,    -1,    -1,
+      -1,    -1,    21,    22,    90,    -1,    -1,    93,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    35,    36,    -1,    -1,
+      -1,    -1,   108,    -1,    43,    44,    45,    -1,    -1,    -1,
+      -1,    -1,   118,    52,    53,   121,    55,    -1,   124,   125,
+      -1,    60,    -1,    -1,    -1,    -1,    65,    -1,   134,    68,
+      -1,    -1,    -1,    -1,   140,    -1,    -1,    -1,    -1,   145,
+      -1,    -1,    -1,    82,    83,    -1,    -1,    -1,    -1,    -1,
+      -1,    90,    -1,    -1,    93,    -1,    -1,    -1,    -1,     4,
+       5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,   108,
+      -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    -1,   118,
+      -1,    -1,   121,    -1,    -1,   124,   125,    -1,    -1,    -1,
+      35,    36,    -1,    -1,    -1,   134,   135,    -1,    43,    44,
+      45,   140,    -1,    -1,    -1,    -1,   145,    52,    53,    -1,
+      55,    -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,
+      65,    -1,    -1,    68,    -1,    -1,     4,     5,     6,     7,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    82,    83,    -1,
+      -1,    -1,    -1,    21,    22,    90,    -1,    -1,    93,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    35,    36,    -1,
+      -1,    -1,    -1,   108,    -1,    43,    44,    45,    -1,    -1,
+     115,    -1,    -1,   118,    52,    53,   121,    55,    -1,   124,
+     125,    -1,    60,    -1,    -1,    -1,    64,    65,    -1,   134,
+      68,    -1,    -1,    -1,    -1,   140,    -1,    -1,    -1,    -1,
+     145,    -1,    -1,    -1,    82,    83,    -1,    -1,    -1,    -1,
+      -1,    -1,    90,    -1,    -1,    93,    -1,    -1,    -1,    -1,
        4,     5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,   107,    -1,    -1,    -1,    -1,    21,    22,    23,
-      -1,    -1,   117,    -1,    -1,   120,    -1,    -1,   123,   124,
-      -1,    35,    36,    -1,    -1,    -1,    -1,    -1,   133,    43,
-      44,    -1,    -1,    -1,   139,    -1,    -1,    51,    52,   144,
-      54,    -1,    -1,    -1,    -1,    59,    -1,    -1,    -1,    -1,
-      64,    -1,    -1,    67,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    81,    82,    -1,
-      -1,    -1,    -1,    -1,    -1,    89,    -1,    -1,    92,    -1,
-      -1,     4,     5,     6,     7,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   107,    -1,    -1,    -1,    -1,    21,    22,
-      -1,    -1,    -1,   117,    -1,    -1,   120,    -1,    -1,   123,
-     124,    -1,    35,    36,    -1,    -1,    -1,    -1,    -1,   133,
-      43,    44,    -1,    -1,    -1,   139,    -1,    -1,    51,    52,
-     144,    54,    -1,    -1,    -1,    -1,    59,    -1,    -1,    -1,
-      -1,    64,    -1,    -1,    67,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    81,    82,
-      -1,    -1,    -1,    -1,    -1,    -1,    89,    -1,    -1,    92,
-      -1,    -1,    -1,    -1,    -1,     4,     5,     6,     7,    -1,
-      -1,    -1,    -1,    -1,   107,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    21,    22,   117,    -1,    -1,   120,    -1,    -1,
-     123,   124,    -1,    -1,    -1,    -1,    35,    36,    -1,    -1,
-     133,   134,    -1,    -1,    43,    44,   139,    -1,    -1,    -1,
-      -1,   144,    51,    52,    -1,    54,    -1,    -1,    -1,    -1,
-      59,    -1,    -1,    -1,    -1,    64,    -1,    -1,    67,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    81,    82,    -1,    -1,    -1,    -1,    -1,    -1,
-      89,    -1,    -1,    92,    -1,    -1,     4,     5,     6,     7,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   107,    -1,
-      -1,    -1,    -1,    21,    22,   114,    -1,    -1,   117,    -1,
-      -1,   120,    -1,    -1,   123,   124,    -1,    35,    36,    -1,
-      -1,    -1,    -1,    -1,   133,    43,    44,    -1,    -1,    -1,
-     139,    -1,    -1,    51,    52,   144,    54,    -1,    -1,    -1,
-      -1,    59,    -1,    -1,    -1,    63,    64,    -1,    -1,    67,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    81,    82,    -1,    -1,    -1,    -1,    -1,
-      -1,    89,    -1,    -1,    92,    -1,    -1,     4,     5,     6,
-       7,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   107,
-      -1,    -1,    -1,    -1,    21,    22,    -1,    -1,    -1,   117,
-      -1,    -1,   120,    -1,    -1,   123,   124,    -1,    35,    36,
-      -1,    -1,    -1,    -1,    -1,   133,    43,    44,    -1,    -1,
-      -1,   139,    -1,    -1,    51,    52,   144,    54,    -1,    -1,
-      -1,    -1,    59,    -1,    -1,    -1,    -1,    64,    -1,    -1,
-      67,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    81,    82,    -1,    -1,    -1,    -1,
-      -1,    -1,    89,    -1,    -1,    92,    -1,    -1,     4,     5,
-       6,     7,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     107,    -1,    -1,    -1,    -1,    21,    22,    -1,    -1,    -1,
-     117,    -1,    -1,   120,    -1,    -1,   123,   124,    -1,    35,
-      36,    -1,    -1,    -1,    -1,    -1,   133,    43,    44,    -1,
-      -1,    -1,   139,    -1,    -1,    51,    52,   144,    54,    -1,
-      -1,    -1,    -1,    59,    -1,    -1,    -1,    -1,    64,    -1,
-      -1,    67,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    81,    82,     5,    -1,     7,
-      -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,    -1,
-      -1,    -1,    -1,    21,    22,    -1,    35,    36,    -1,    -1,
-      -1,   107,    -1,    -1,    -1,    44,    -1,    35,    36,    -1,
-      -1,   117,    51,    52,   120,    54,    44,   123,   124,    -1,
-      59,    -1,    -1,    51,    52,    -1,    54,   133,    67,    -1,
-      -1,    59,    -1,   139,    -1,    -1,    -1,    -1,   144,    67,
-      -1,    -1,    81,    82,    -1,    -1,    -1,    -1,    -1,    -1,
-      89,    -1,    -1,    81,    82,    -1,    -1,    -1,    -1,    -1,
-      -1,    89,    -1,    -1,    92,    -1,    -1,    -1,   107,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   117,   107,
-      -1,    -1,    -1,    -1,   123,   124,    -1,    -1,    -1,   117,
-      -1,    -1,    -1,    -1,   133,   123,   124,    -1,    -1,    -1,
-     139,    -1,    -1,    -1,    -1,   133,    -1,    -1,    -1,    -1,
-      -1,   139
+     108,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    -1,
+     118,    -1,    -1,   121,    -1,    -1,   124,   125,    -1,    -1,
+      -1,    35,    36,    -1,    -1,    -1,   134,    -1,    -1,    43,
+      44,    45,   140,    -1,    -1,    -1,    -1,   145,    52,    53,
+      -1,    55,    -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,
+      -1,    65,    -1,    -1,    68,    -1,    -1,     4,     5,     6,
+       7,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    82,    83,
+      -1,    -1,    -1,    -1,    21,    22,    90,    -1,    -1,    93,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    35,    36,
+      -1,    -1,    -1,    -1,   108,    -1,    43,    44,    45,    -1,
+      -1,    -1,    -1,    -1,   118,    52,    53,   121,    55,    -1,
+     124,   125,    -1,    60,    -1,    -1,    -1,     4,    65,     6,
+     134,    68,    -1,    -1,    -1,    -1,   140,    -1,    -1,    -1,
+      -1,   145,    -1,    -1,    -1,    82,    83,    -1,    -1,    -1,
+      -1,    -1,    -1,    90,    -1,    -1,    93,    -1,    35,    36,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    45,    -1,
+      -1,   108,    -1,    -1,    -1,    52,    53,    -1,    55,    -1,
+      -1,   118,    -1,    60,   121,    -1,    -1,   124,   125,    -1,
+      -1,    68,    -1,    -1,    -1,    -1,    -1,   134,    -1,    -1,
+      -1,    -1,    -1,   140,    -1,    82,    83,    -1,   145,    -1,
+      -1,    -1,     5,    90,     7,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,
+      -1,   108,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   118,    35,    36,    -1,    -1,    -1,   124,   125,    -1,
+      -1,    -1,    45,    -1,    35,    36,    -1,   134,    -1,    52,
+      53,    -1,    55,   140,    45,    -1,    -1,    60,    -1,    -1,
+      -1,    52,    53,    -1,    55,    68,    -1,    -1,    -1,    60,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    68,    -1,    82,
+      83,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,
+      93,    82,    83,    -1,    -1,    -1,    -1,    -1,    -1,    90,
+      -1,    -1,    -1,    -1,    -1,   108,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,   118,    -1,   108,    -1,    -1,
+      -1,   124,   125,    -1,    -1,    -1,    -1,   118,    -1,    -1,
+      -1,   134,    -1,   124,   125,    -1,    -1,   140,    -1,    -1,
+      -1,    -1,    -1,   134,    -1,    -1,    -1,    -1,    -1,   140
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint16 yystos[] =
 {
-       0,     1,     3,    32,    48,    49,    56,    60,    80,   105,
-     114,   130,   137,   140,   149,   150,   151,   152,   153,   154,
-     155,   177,   178,   181,   182,   185,   187,   190,   191,   192,
-     256,   257,   121,     4,     6,   190,   254,    78,   121,    71,
-     121,    83,    28,    58,   193,   254,   188,   189,   204,   254,
-       0,   140,   142,    48,    80,   190,    29,   137,   186,    30,
-     140,   143,     3,   254,   125,   179,    71,   179,   254,   254,
-     254,   254,   254,     5,     7,    21,    22,    23,    35,    36,
-      43,    44,    51,    52,    54,    59,    64,    67,    81,    82,
-      89,    92,   107,   117,   120,   123,   124,   133,   139,   144,
-     158,   194,   195,   196,   198,   230,   231,   232,   233,   234,
-     235,   236,   237,   244,   247,   250,   254,   115,   146,    33,
-     144,   190,    83,   186,   193,   104,   192,    31,    60,     5,
-     118,   119,   137,   180,     5,   180,    95,   144,   135,   224,
-     225,   132,   144,   192,     7,     7,   134,   230,   240,   241,
-     144,    82,   144,     5,   144,   144,    82,   190,   230,     5,
-      71,   197,   146,    21,    22,    33,   251,   254,    23,    24,
-     147,   252,    98,    22,   233,    27,   144,   183,   184,   254,
-     189,   144,   198,   253,   254,   179,   254,   191,     7,    46,
-      47,    46,    47,   144,   180,   254,   156,   157,   254,    10,
-      63,   144,   226,   227,   228,   229,   230,   247,   144,   253,
-     226,   134,   238,   239,    61,   241,   242,     7,    53,    76,
-      90,    91,   113,   138,   245,   245,   230,     7,   145,   145,
-     144,   198,   201,   202,   205,   234,   254,   224,   196,   254,
-     231,   232,   144,   254,   254,    23,    58,   145,   230,   243,
-     146,   224,    11,   145,   146,   180,   192,   156,    45,    70,
-     103,   129,   162,   254,   254,   169,   170,   171,   172,   173,
-     174,   254,   144,   165,   145,   146,    82,   158,   229,   198,
-     226,   230,     8,     9,    10,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    77,   249,    20,   244,   246,   145,
-     122,   230,   239,   242,   230,    62,   145,    71,    71,   145,
-     201,    33,   203,   204,    72,    79,    87,   109,   200,   146,
-     203,    39,   127,   199,    73,   206,    99,   213,   214,   145,
-     243,   145,   146,   184,   230,   254,   144,    85,    85,   144,
-     145,   146,     5,     7,    28,    65,    94,    95,   126,   144,
-     254,   255,   247,   248,   254,   131,   162,   163,   164,   156,
-      10,    45,    55,    92,   103,   108,   129,   159,   160,   161,
-     145,   227,   228,    17,    18,    19,    77,   230,   144,   198,
-     230,    10,    92,   145,   146,   132,   230,   122,    62,   230,
-       7,   145,   204,    97,    97,    97,    84,   201,     7,     7,
-     203,    42,    75,   207,    42,   145,    96,   215,   145,   230,
-     226,   144,   144,   253,   170,   253,   145,   146,    37,    40,
-      41,   116,   175,   146,   137,   166,    92,   144,   244,    85,
-     254,   159,   230,   144,   198,     9,   243,    92,   244,   144,
-     230,   145,    69,   145,   202,   101,   101,   243,   226,    96,
-     208,   243,    42,   106,   112,   216,   217,   145,   253,   253,
-     145,   145,   247,   144,   176,   162,    38,    99,   167,   226,
-     144,     9,   243,   230,   145,   246,     7,    95,    42,    88,
-     209,   220,   221,   230,    19,   145,   145,   169,   144,    42,
-     145,   254,   230,   145,   145,   145,   226,   220,     7,   136,
-     210,   211,   212,   146,    34,    57,   222,     7,    50,   128,
-     218,   108,   145,   169,    74,   106,   168,   145,   254,   212,
-     221,    93,   223,   102,   110,   102,     9,   254,   145,   144,
-      33,    66,    86,     7,    50,   128,   219,   144,   253,   144,
-      68,   110,    68,   253,   145,   213,   145,   100,   145,     7
+       0,     1,     3,    32,    49,    50,    57,    61,    81,   106,
+     115,   131,   138,   141,   150,   151,   152,   153,   154,   155,
+     156,   178,   179,   182,   183,   186,   188,   191,   192,   193,
+     258,   259,   122,     4,     6,   191,   256,    79,   122,    72,
+     122,    84,    28,    59,   194,   256,   189,   190,   205,   256,
+       0,   141,   143,    49,    81,   191,    29,   138,   187,    30,
+     141,   144,     3,   256,   126,   180,    72,   180,   256,   256,
+     256,   256,   256,     5,     7,    21,    22,    23,    35,    36,
+      43,    44,    45,    52,    53,    55,    60,    65,    68,    82,
+      83,    90,    93,   108,   118,   121,   124,   125,   134,   140,
+     145,   159,   195,   196,   197,   199,   231,   232,   233,   234,
+     235,   236,   237,   238,   239,   246,   249,   252,   256,   116,
+     147,    33,   145,   191,    84,   187,   194,   105,   193,    31,
+      61,     5,   119,   120,   138,   181,     5,   181,    96,   145,
+     136,   225,   226,   133,   145,   193,     7,     7,   135,   231,
+     242,   243,   145,   145,    83,   145,     5,   145,   145,    83,
+     191,   231,     5,    72,   198,   147,    21,    22,    33,   253,
+     256,    23,    24,   148,   254,    99,    22,   234,    27,   145,
+     184,   185,   256,   190,   145,   199,   255,   256,   180,   256,
+     192,     7,    47,    48,    47,    48,   145,   181,   256,   157,
+     158,   256,    10,    64,   145,   227,   228,   229,   230,   231,
+     249,   145,   255,   227,   135,   240,   241,    62,   243,   244,
+     231,     7,    54,    77,    91,    92,   114,   139,   247,   247,
+     231,     7,   146,   146,   145,   199,   202,   203,   206,   235,
+     256,   225,   197,   256,   232,   233,   145,   256,   256,    23,
+      59,   146,   231,   245,   147,   225,    11,   146,   147,   181,
+     193,   157,    46,    71,   104,   130,   163,   256,   256,   170,
+     171,   172,   173,   174,   175,   256,   145,   166,   146,   147,
+      83,   159,   230,   199,   227,   231,     8,     9,    10,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    78,   251,
+      20,   246,   248,   146,   123,   231,   241,   244,   231,    63,
+      33,   146,    72,    72,   146,   202,    33,   204,   205,    73,
+      80,    88,   110,   201,   147,   204,    39,   128,   200,    74,
+     207,   100,   214,   215,   146,   245,   146,   147,   185,   231,
+     256,   145,    86,    86,   145,   146,   147,     5,     7,    28,
+      66,    95,    96,   127,   145,   256,   257,   249,   250,   256,
+     132,   163,   164,   165,   157,    10,    46,    56,    93,   104,
+     109,   130,   160,   161,   162,   146,   228,   229,    17,    18,
+      19,    78,   231,   145,   199,   231,    10,    93,   146,   147,
+     133,   231,   123,    63,   159,   256,   231,     7,   146,   205,
+      98,    98,    98,    85,   202,     7,     7,   204,    42,    76,
+     208,    42,   146,    97,   216,   146,   231,   227,   145,   145,
+     255,   171,   255,   146,   147,    37,    40,    41,   117,   176,
+     147,   138,   167,    93,   145,   246,    86,   256,   160,   231,
+     145,   199,     9,   245,    93,   246,   145,   231,   146,   146,
+     146,    70,   146,   203,   102,   102,   245,   227,    97,   209,
+     245,    42,   107,   113,   217,   218,   146,   255,   255,   146,
+     146,   249,   145,   177,   163,    38,   100,   168,   227,   145,
+       9,   245,   231,   146,   248,     7,    96,    42,    89,   210,
+     221,   222,   231,    19,   146,   146,   170,   145,    42,   146,
+     256,   231,   146,   146,   146,   227,   221,     7,   137,   211,
+     212,   213,   147,    34,    58,   223,     7,    51,   129,   219,
+     109,   146,   170,    75,   107,   169,   146,   256,   213,   222,
+      94,   224,   103,   111,   103,     9,   256,   146,   145,    33,
+      67,    87,     7,    51,   129,   220,   145,   255,   145,    69,
+     111,    69,   255,   146,   214,   146,   101,   146,     7
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint16 yyr1[] =
 {
-       0,   148,   149,   149,   149,   149,   149,   149,   150,   150,
-     150,   150,   150,   150,   150,   150,   150,   150,   151,   152,
-     152,   152,   152,   153,   154,   155,   156,   157,   157,   158,
-     158,   158,   158,   158,   158,   158,   158,   158,   158,   158,
-     158,   158,   158,   158,   158,   158,   158,   159,   159,   159,
-     159,   159,   159,   159,   160,   160,   161,   161,   162,   162,
-     162,   162,   163,   163,   164,   164,   165,   165,   166,   166,
-     167,   167,   168,   168,   169,   169,   170,   170,   170,   170,
-     171,   171,   171,   172,   173,   174,   175,   175,   175,   175,
-     176,   176,   177,   177,   177,   177,   178,   178,   178,   178,
-     179,   179,   179,   180,   180,   181,   182,   183,   183,   184,
-     185,   185,   186,   186,   187,   188,   188,   189,   190,   190,
-     191,   191,   192,   193,   193,   193,   194,   194,   195,   195,
-     196,   196,   196,   197,   198,   199,   199,   199,   200,   200,
-     200,   200,   200,   200,   200,   200,   201,   201,   202,   202,
-     202,   202,   202,   202,   203,   203,   204,   204,   205,   205,
-     206,   206,   207,   207,   208,   208,   209,   209,   210,   210,
-     211,   211,   212,   213,   214,   214,   215,   215,   216,   216,
-     217,   217,   218,   218,   218,   219,   

<TRUNCATED>


[17/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/SqlParser.ypp
----------------------------------------------------------------------
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index 8fbcdd7..af79fe3 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -102,15 +102,9 @@ typedef struct YYLTYPE {
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
-#include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "types/operations/comparisons/Comparison.hpp"
 #include "types/operations/comparisons/ComparisonFactory.hpp"
 #include "types/operations/comparisons/ComparisonID.hpp"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationFactory.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
 #include "utility/PtrList.hpp"
 #include "utility/PtrVector.hpp"
 
@@ -189,8 +183,8 @@ typedef void* yyscan_t;
   quickstep::ParseStatementQuit *quit_statement_;
 
   const quickstep::Comparison *comparison_;
-  const quickstep::UnaryOperation *unary_operation_;
-  const quickstep::BinaryOperation *binary_operation_;
+  quickstep::ParseString *unary_operation_;
+  quickstep::ParseString *binary_operation_;
 
   quickstep::ParseFunctionCall *function_call_;
   quickstep::PtrList<quickstep::ParseExpression> *expression_list_;
@@ -261,6 +255,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_CSB_TREE;
 %token TOKEN_BY;
 %token TOKEN_CASE;
+%token TOKEN_CAST;
 %token TOKEN_CHARACTER;
 %token TOKEN_CHECK;
 %token TOKEN_COLUMN;
@@ -394,6 +389,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
   add_expression
   case_expression
   opt_else_clause
+  cast_function
   extract_function
   substr_function
 
@@ -624,8 +620,6 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 
 %destructor { } <boolean_value_>
 %destructor { } <comparison_>
-%destructor { } <unary_operation_>
-%destructor { } <binary_operation_>
 %destructor { } <join_type_>
 
 %destructor {
@@ -1676,7 +1670,10 @@ predicate_expression_base:
 /* Scalars */
 add_expression:
   add_expression add_operation multiply_expression {
-    $$ = new quickstep::ParseBinaryExpression(@2.first_line, @2.first_column, *$2, $1, $3);
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($1);
+    arguments->push_back($3);
+    $$ = new quickstep::ParseFunctionCall(@1.first_line, @1.first_column, false, $2, arguments);
   }
   | multiply_expression {
     $$ = $1;
@@ -1684,7 +1681,10 @@ add_expression:
 
 multiply_expression:
   multiply_expression multiply_operation unary_expression {
-    $$ = new quickstep::ParseBinaryExpression(@2.first_line, @2.first_column, *$2, $1, $3);
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($1);
+    arguments->push_back($3);
+    $$ = new quickstep::ParseFunctionCall(@1.first_line, @1.first_column, false, $2, arguments);
   }
   | unary_expression {
     $$ = $1;
@@ -1692,7 +1692,9 @@ multiply_expression:
 
 unary_expression:
   unary_operation expression_base {
-    $$ = new quickstep::ParseUnaryExpression(@1.first_line, @1.first_column, *$1, $2);
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($2);
+    $$ = new quickstep::ParseFunctionCall(@1.first_line, @1.first_column, false, $1, arguments);
   }
   | expression_base {
     $$ = $1;
@@ -1716,6 +1718,9 @@ expression_base:
     $1->setWindow($4);
     $$ = $1;
   }
+  | cast_function {
+    $$ = $1;
+  }
   | extract_function {
     $$ = $1;
   }
@@ -1748,19 +1753,59 @@ function_call:
     $$ = new quickstep::ParseFunctionCall(@1.first_line, @1.first_column, true, $1, $4);
   };
 
+cast_function:
+  TOKEN_CAST '(' add_expression TOKEN_AS data_type ')' {
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($3);
+    arguments->push_back(new quickstep::ParseScalarLiteral(
+        new quickstep::StringParseLiteralValue(
+            new quickstep::ParseString(@5.first_line,
+                                       @5.first_column,
+                                       $5->getType().getName()),
+            nullptr)));
+    delete $5;
+    auto *name = new quickstep::ParseString(@1.first_line, @1.first_column, "cast");
+    $$ = new quickstep::ParseFunctionCall(
+        @1.first_line, @1.first_column, false, name, arguments);
+  }
+  | TOKEN_CAST '(' add_expression TOKEN_AS any_name ')' {
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($3);
+    arguments->push_back(new quickstep::ParseScalarLiteral(
+        new quickstep::StringParseLiteralValue($5, nullptr)));
+    auto *name = new quickstep::ParseString(@1.first_line, @1.first_column, "cast");
+    $$ = new quickstep::ParseFunctionCall(
+        @1.first_line, @1.first_column, false, name, arguments);
+  };
+
 extract_function:
   TOKEN_EXTRACT '(' datetime_unit TOKEN_FROM add_expression ')' {
-    $$ = new quickstep::ParseExtractFunction(@1.first_line, @1.first_column, $3, $5);
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($5);
+    arguments->push_back(new quickstep::ParseScalarLiteral(
+        new quickstep::StringParseLiteralValue($3, nullptr)));
+    auto *name = new quickstep::ParseString(@1.first_line, @1.first_column, "extract");
+    $$ = new quickstep::ParseFunctionCall(
+        @1.first_line, @1.first_column, false, name, arguments);
   };
 
 substr_function:
   TOKEN_SUBSTRING '(' add_expression TOKEN_FROM TOKEN_UNSIGNED_NUMVAL ')' {
-    $$ = new quickstep::ParseSubstringFunction(
-        @1.first_line, @1.first_column, $3, $5->long_value());
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($3);
+    arguments->push_back(new quickstep::ParseScalarLiteral($5));
+    auto *name = new quickstep::ParseString(@1.first_line, @1.first_column, "substring");
+    $$ = new quickstep::ParseFunctionCall(
+        @1.first_line, @1.first_column, false, name, arguments);
   }
   | TOKEN_SUBSTRING '(' add_expression TOKEN_FROM TOKEN_UNSIGNED_NUMVAL TOKEN_FOR TOKEN_UNSIGNED_NUMVAL ')' {
-    $$ = new quickstep::ParseSubstringFunction(
-        @1.first_line, @1.first_column, $3, $5->long_value(), $7->long_value());
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($3);
+    arguments->push_back(new quickstep::ParseScalarLiteral($5));
+    arguments->push_back(new quickstep::ParseScalarLiteral($7));
+    auto *name = new quickstep::ParseString(@1.first_line, @1.first_column, "substring");
+    $$ = new quickstep::ParseFunctionCall(
+        @1.first_line, @1.first_column, false, name, arguments);
   };
 
 case_expression:
@@ -1980,26 +2025,26 @@ unary_operation:
      * to shift rather than reduce, the case in 'literal_value' has precedence
      * over this one.
      **/
-    $$ = &quickstep::UnaryOperationFactory::GetUnaryOperation(quickstep::UnaryOperationID::kNegate);
+    $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("-"));
   };
 
 add_operation:
   '+' {
-    $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kAdd);
+    $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("+"));
   }
   | '-' {
-    $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kSubtract);
+    $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("-"));
   };
 
 multiply_operation:
   '%' {
-    $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kModulo);
+    $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("%"));
   }
   | '*' {
-    $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kMultiply);
+    $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("*"));
   }
   | '/' {
-    $$ = &quickstep::BinaryOperationFactory::GetBinaryOperation(quickstep::BinaryOperationID::kDivide);
+    $$ = new quickstep::ParseString(@1.first_line, @1.first_column, std::string("/"));
   };
 
 /* General Utility Stuff */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/preprocessed/SqlLexer_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.cpp b/parser/preprocessed/SqlLexer_gen.cpp
index 4800cde..b1ea67f 100644
--- a/parser/preprocessed/SqlLexer_gen.cpp
+++ b/parser/preprocessed/SqlLexer_gen.cpp
@@ -592,8 +592,8 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 164
-#define YY_END_OF_BUFFER 165
+#define YY_NUM_RULES 165
+#define YY_END_OF_BUFFER 166
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -601,72 +601,72 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_accept[589] =
+static const flex_int16_t yy_accept[590] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  165,    2,    2,  163,  163,  162,  161,  163,
-      140,  136,  139,  136,  136,  159,  132,  129,  133,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  137,    4,    5,    5,    3,  155,
-      155,  152,  156,  156,  150,  157,  157,  154,    1,  162,
-      130,  160,  159,  159,  159,    0,  134,  131,  135,  158,
-      158,  158,  158,   10,  158,  158,  158,   22,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  138,
-
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,   58,   67,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,   81,   82,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  113,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,    4,    5,    3,  155,  151,  156,
-      149,  149,  141,  143,  144,  145,  146,  147,  148,  149,
-      157,  153,  160,  159,    0,  159,    6,    7,  158,    9,
-       11,  158,  158,   15,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,   33,  158,  158,  158,  158,
-
-      158,  158,  158,  158,   43,  158,  158,  158,  158,  158,
-      158,   50,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,   62,  158,   69,  158,  158,  158,  158,  158,  158,
-      158,   77,  158,   80,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,   98,  158,  158,
-      103,  104,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  141,
-      143,  142,  158,  158,  158,  158,  158,  158,  158,   20,
-       23,  158,  158,  158,   28,  158,  158,  158,   31,  158,
-      158,  158,   37,  158,  158,   41,   42,  158,  158,  158,
-
-      158,  158,  158,  158,   52,   53,  158,   55,  158,   57,
-      158,  158,  158,  158,   66,   68,   70,   71,   72,  158,
-       74,  158,  158,   78,  158,  158,   85,  158,  158,  158,
-      158,  158,   92,  158,   94,  158,  158,  158,  100,  158,
-      158,  158,  158,  158,  158,  158,  158,  110,  111,  114,
-      158,  158,  158,  158,  158,  158,  158,  158,  123,  158,
-      158,  126,  127,  141,  142,    8,  158,  158,  158,  158,
-      158,  158,  158,   25,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,   46,   47,
-       48,  158,  158,   54,  158,   59,   60,  158,  158,  158,
-
-       73,  158,   76,   79,   83,   84,  158,  158,  158,  158,
-      158,   93,  158,  158,   97,  158,  158,  158,  158,  158,
-      158,  158,  109,  158,  158,  158,  117,  158,  158,  120,
-      158,  158,  124,  158,  158,  158,  158,   14,  158,  158,
-      158,  158,  158,   26,  158,   29,  158,  158,  158,  158,
-      158,   36,  158,  158,   40,   44,  158,  158,  158,   56,
-       61,  158,  158,  158,   75,  158,  158,  158,  158,  158,
-      158,   96,  158,  101,  102,  158,  106,  107,  158,  158,
-      158,  158,  118,  119,  121,  158,  125,  158,  158,   13,
-      158,  158,  158,  158,  158,  158,   21,   30,  158,   34,
-
-       35,  158,  158,   45,  158,   51,   63,  158,  158,  158,
-       88,  158,   90,  158,  158,  158,  158,  158,  158,  158,
-      158,  122,  158,  158,  158,  158,  158,  158,  158,  158,
-       32,  158,   39,  158,  158,   65,  158,  158,   91,  158,
-      158,  105,  158,  158,  158,  158,  158,   12,  158,  158,
-      158,  158,   24,  158,  158,   49,   64,   86,   89,  158,
-      158,  108,  112,  158,  116,  128,   16,  158,  158,  158,
-       27,   38,   87,   95,  158,  158,  158,   18,   19,  158,
-      115,  158,  158,  158,   99,  158,   17,    0
+        0,    0,  166,    2,    2,  164,  164,  163,  162,  164,
+      141,  137,  140,  137,  137,  160,  133,  130,  134,  159,
+      159,  159,  159,  159,  159,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,  159,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,  138,    4,    5,    5,    3,  156,
+      156,  153,  157,  157,  151,  158,  158,  155,    1,  163,
+      131,  161,  160,  160,  160,    0,  135,  132,  136,  159,
+      159,  159,  159,   10,  159,  159,  159,   23,  159,  159,
+      159,  159,  159,  159,  159,  159,  159,  159,  159,  139,
+
+      159,  159,  159,  159,  159,  159,  159,  159,  159,  159,
+      159,  159,   59,   68,  159,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,  159,   82,   83,  159,  159,  159,
+      159,  159,  159,  159,  159,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,  114,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,    4,    5,    3,  156,  152,  157,
+      150,  150,  142,  144,  145,  146,  147,  148,  149,  150,
+      158,  154,  161,  160,    0,  160,    6,    7,  159,    9,
+       11,  159,  159,   15,  159,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,  159,   34,  159,  159,  159,  159,
+
+      159,  159,  159,  159,   44,  159,  159,  159,  159,  159,
+      159,   51,  159,  159,  159,  159,  159,  159,  159,  159,
+      159,   63,  159,   70,  159,  159,  159,  159,  159,  159,
+      159,   78,  159,   81,  159,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,  159,  159,  159,   99,  159,  159,
+      104,  105,  159,  159,  159,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,  159,  159,  159,  159,  159,  142,
+      144,  143,  159,  159,  159,  159,  159,  159,  159,   20,
+       21,   24,  159,  159,  159,   29,  159,  159,  159,   32,
+      159,  159,  159,   38,  159,  159,   42,   43,  159,  159,
+
+      159,  159,  159,  159,  159,   53,   54,  159,   56,  159,
+       58,  159,  159,  159,  159,   67,   69,   71,   72,   73,
+      159,   75,  159,  159,   79,  159,  159,   86,  159,  159,
+      159,  159,  159,   93,  159,   95,  159,  159,  159,  101,
+      159,  159,  159,  159,  159,  159,  159,  159,  111,  112,
+      115,  159,  159,  159,  159,  159,  159,  159,  159,  124,
+      159,  159,  127,  128,  142,  143,    8,  159,  159,  159,
+      159,  159,  159,  159,   26,  159,  159,  159,  159,  159,
+      159,  159,  159,  159,  159,  159,  159,  159,  159,   47,
+       48,   49,  159,  159,   55,  159,   60,   61,  159,  159,
+
+      159,   74,  159,   77,   80,   84,   85,  159,  159,  159,
+      159,  159,   94,  159,  159,   98,  159,  159,  159,  159,
+      159,  159,  159,  110,  159,  159,  159,  118,  159,  159,
+      121,  159,  159,  125,  159,  159,  159,  159,   14,  159,
+      159,  159,  159,  159,   27,  159,   30,  159,  159,  159,
+      159,  159,   37,  159,  159,   41,   45,  159,  159,  159,
+       57,   62,  159,  159,  159,   76,  159,  159,  159,  159,
+      159,  159,   97,  159,  102,  103,  159,  107,  108,  159,
+      159,  159,  159,  119,  120,  122,  159,  126,  159,  159,
+       13,  159,  159,  159,  159,  159,  159,   22,   31,  159,
+
+       35,   36,  159,  159,   46,  159,   52,   64,  159,  159,
+      159,   89,  159,   91,  159,  159,  159,  159,  159,  159,
+      159,  159,  123,  159,  159,  159,  159,  159,  159,  159,
+      159,   33,  159,   40,  159,  159,   66,  159,  159,   92,
+      159,  159,  106,  159,  159,  159,  159,  159,   12,  159,
+      159,  159,  159,   25,  159,  159,   50,   65,   87,   90,
+      159,  159,  109,  113,  159,  117,  129,   16,  159,  159,
+      159,   28,   39,   88,   96,  159,  159,  159,   18,   19,
+      159,  116,  159,  159,  159,  100,  159,   17,    0
     } ;
 
 static const YY_CHAR yy_ec[256] =
@@ -713,155 +713,155 @@ static const YY_CHAR yy_meta[72] =
         8
     } ;
 
-static const flex_int16_t yy_base[604] =
+static const flex_int16_t yy_base[605] =
     {   0,
         0,    1,   46,    0,  117,  162,    2,    3,  127,  128,
-        6,   10,  147, 1316, 1316,    0, 1316,   13, 1316,  130,
-     1316, 1316, 1316,  129,    6,  129,    4, 1316,   28,  124,
+        6,   10,  147, 1317, 1317,    0, 1317,   13, 1317,  130,
+     1317, 1317, 1317,  129,    6,  129,    4, 1317,   28,  124,
       159,  213,  165,  167,  263,   92,  158,  163,   96,  107,
       214,  160,  186,  219,  221,  155,  281,  274,  325,  257,
-      186,  209,    0,  219, 1316,   27,    4,   19,    0,    0,
+      186,  209,    0,  219, 1317,   27,    4,   19,    0,    0,
         0,   17,    0,    0,  389,    0,    0,    8,    0,   22,
-     1316,    0,  293,  325,  343,   18, 1316, 1316, 1316,    0,
+     1317,    0,  293,  325,  343,   18, 1317, 1317, 1317,    0,
       223,  265,  234,  242,  260,  292,  288,    0,  299,  330,
-      337,  324,  334,  324,  325,  380,  325,  331,  346, 1316,
+      337,  324,  334,  324,  325,  380,  325,  331,  346, 1317,
 
       348,  364,  378,  376,  371,  378,  382,  386,  390,  389,
       386,  385,  435,    0,  402,  389,  400,  435,  433,  431,
       433,  436,  431,  440,  447,    0,  452,  437,  453,  441,
       442,  456,  453,  449,  465,  457,  444,  494,  468,  495,
       500,  501,  499,  492,    0,  486,  492,  507,  506,  502,
-      500,  508,  501,  516,    0,   29,    0,    0, 1316,    0,
-     1316, 1316,   22,   24, 1316, 1316, 1316, 1316, 1316,    0,
-        0, 1316,    0,  524,   26,   28,    0,    0,  517,    0,
-      518,  501,  516,  504,  545,  525,  531,  552,  536,  542,
-      537,  562,  544,  547,  561,    0,  558,  567,  564,  567,
-
-      551,  570,  557,  569,    0,  556,  558,  560,  561,  580,
-      570,  578,  572,  575,  567,  598,  598,  595,  610,  613,
-      614,  615,  607,    0,  602,  603,  619,  616,  619,  606,
-      608,    0,  617,    0,  626,  627,  615,  614,  634,  635,
-      626,  620,  636,  633,  641,  659,  657,  652,  658,  671,
-        0,  665,  673,  660,  668,  668,  678,  679,  673,  671,
-      672,  689,  677,  671,  692,  683,  692,  690,  681,   30,
-      125,    0,  685,  690,  705,  708,  718,  718,  718,    0,
-      733,  724,  723,  717,    0,  718,  722,  736,  722,  730,
-      723,  725,  741,  738,  736,    0,    0,  729,  749,  748,
-
-      734,  735,  741,  748,    0,    0,  743,    0,  747,    0,
-      738,  750,  762,  774,    0,    0,    0,    0,    0,  767,
-        0,  769,  785,  775,  777,  778,    0,  789,  794,  795,
-      800,  784,    0,  798,    0,  786,  781,  786,    0,  803,
-      794,  808,  800,  795,  793,  795,  812,    0,  800,    0,
-      815,  805,  824,  818,  825,  840,  845,  843,    0,  847,
-      838,    0,  841,  131, 1316,    0,  852,  852,  838,  858,
-      844,  855,  859,    0,  850,  847,  861,  864,  856,  862,
-      871,  861,  870,  863,  864,  879,  877,  894,    0,    0,
-        0,  880,  898,    0,  901,    0,    0,  889,  905,  892,
-
-        0,  907,    0,    0,    0,    0,  895,  902,  913,  900,
-      910,    0,  915,  905,    0,  917,  919,  904,  918,  910,
-      909,  912,    0,  911,  914,  921,    0,  931,  937,    0,
-      935,  954,    0,  938,  948,  957,  953,    0,  946,  951,
-      969,  963,  953,    0,  973,    0,  970,  956,  964,  966,
-      959,    0,  976,  978,    0,    0,  962,  976,  972,    0,
-        0,  969,  983,  988,    0,  982,  973,  985,  975,  992,
-      999,    0, 1007,    0,    0, 1007,    0,    0, 1015, 1024,
-     1025, 1023,    0,    0,    0, 1010,    0, 1016, 1017,    0,
-     1023, 1018, 1021, 1023, 1031, 1028,    0,    0, 1033,    0,
-
-        0, 1030, 1020,    0, 1029,    0,    0, 1041, 1033, 1031,
-        0, 1033,    0, 1024, 1048, 1043, 1038, 1056, 1058, 1064,
-     1074,    0, 1062, 1076, 1070, 1069, 1070, 1068, 1071, 1076,
-        0, 1077,    0, 1085, 1073,    0, 1080, 1088,    0, 1091,
-     1084,    0, 1091, 1085, 1086, 1099, 1096,    0, 1098, 1102,
-     1097, 1105,    0, 1096, 1121,    0,    0, 1110,    0, 1116,
-     1128,    0,    0, 1128,    0,    0,    0, 1123, 1137, 1125,
-        0,    0,    0,    0, 1124, 1141, 1127,    0,    0, 1143,
-        0, 1140, 1132, 1146,    0, 1133,    0, 1316, 1198, 1208,
-     1218, 1228, 1238, 1242, 1245, 1251, 1261, 1271, 1281, 1291,
-
-     1301, 1306, 1308
+      500,  508,  501,  516,    0,   29,    0,    0, 1317,    0,
+     1317, 1317,   22,   24, 1317, 1317, 1317, 1317, 1317,    0,
+        0, 1317,    0,  524,   26,   28,    0,    0,  517,    0,
+      518,  501,  516,  504,  545,  544,  512,  552,  536,  542,
+      537,  562,  545,  548,  562,    0,  559,  568,  565,  568,
+
+      552,  571,  558,  570,    0,  557,  561,  561,  562,  581,
+      571,  580,  574,  576,  585,  599,  604,  597,  613,  614,
+      615,  616,  608,    0,  603,  604,  620,  617,  620,  607,
+      609,    0,  618,    0,  627,  628,  616,  617,  635,  636,
+      628,  620,  638,  634,  659,  660,  663,  654,  661,  672,
+        0,  666,  674,  661,  669,  668,  679,  680,  674,  672,
+      673,  690,  678,  674,  693,  683,  694,  691,  685,   30,
+      125,    0,  686,  698,  717,  709,  724,  720,  721,    0,
+        0,  734,  725,  724,  718,    0,  719,  722,  737,  723,
+      731,  724,  726,  742,  739,  737,    0,    0,  730,  752,
+
+      749,  735,  736,  742,  750,    0,    0,  745,    0,  748,
+        0,  746,  762,  763,  780,    0,    0,    0,    0,    0,
+      769,    0,  772,  785,  775,  777,  778,    0,  788,  795,
+      796,  801,  785,    0,  799,    0,  787,  782,  787,    0,
+      804,  797,  809,  801,  796,  794,  797,  814,    0,  801,
+        0,  823,  817,  825,  824,  827,  843,  846,  844,    0,
+      848,  839,    0,  842,  131, 1317,    0,  852,  853,  839,
+      859,  845,  856,  860,    0,  851,  848,  864,  865,  857,
+      863,  872,  863,  872,  864,  872,  891,  878,  900,    0,
+        0,    0,  882,  901,    0,  902,    0,    0,  890,  906,
+
+      894,    0,  907,    0,    0,    0,    0,  894,  903,  914,
+      901,  911,    0,  916,  906,    0,  918,  920,  907,  919,
+      911,  910,  913,    0,  913,  916,  922,    0,  939,  949,
+        0,  936,  960,    0,  940,  951,  958,  954,    0,  947,
+      952,  970,  963,  954,    0,  974,    0,  971,  957,  965,
+      967,  960,    0,  977,  979,    0,    0,  965,  977,  973,
+        0,    0,  970,  984,  990,    0,  984,  974,  993,  987,
+      993, 1005,    0, 1009,    0,    0, 1010,    0,    0, 1016,
+     1025, 1026, 1024,    0,    0,    0, 1011,    0, 1016, 1018,
+        0, 1024, 1019, 1022, 1024, 1032, 1029,    0,    0, 1034,
+
+        0,    0, 1031, 1023,    0, 1030,    0,    0, 1042, 1034,
+     1032,    0, 1035,    0, 1026, 1049, 1051, 1050, 1057, 1064,
+     1066, 1077,    0, 1063, 1077, 1071, 1070, 1071, 1068, 1072,
+     1077,    0, 1078,    0, 1086, 1074,    0, 1081, 1089,    0,
+     1092, 1085,    0, 1094, 1086, 1087, 1100, 1097,    0, 1100,
+     1104, 1098, 1113,    0, 1108, 1122,    0,    0, 1116,    0,
+     1118, 1131,    0,    0, 1129,    0,    0,    0, 1124, 1138,
+     1126,    0,    0,    0,    0, 1125, 1141, 1128,    0,    0,
+     1144,    0, 1141, 1133, 1147,    0, 1134,    0, 1317, 1199,
+     1209, 1219, 1229, 1239, 1243, 1246, 1252, 1262, 1272, 1282,
+
+     1292, 1302, 1307, 1309
     } ;
 
-static const flex_int16_t yy_def[604] =
+static const flex_int16_t yy_def[605] =
     {   0,
-      589,  589,  588,    3,  590,  590,  591,  591,  592,  592,
-      593,  593,  588,  588,  588,  594,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  588,  588,  588,  588,  596,  597,
-      597,  588,  598,  598,  599,  600,  600,  588,  594,  588,
-      588,  601,  588,  588,  588,  588,  588,  588,  588,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  588,
-
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  588,  588,  596,  597,  588,  598,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  602,
-      600,  588,  601,  588,  588,  588,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  588,
-      588,  603,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  588,  588,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  595,
-      595,  595,  595,  595,  595,  595,  595,    0,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-
-      588,  588,  588
+      590,  590,  589,    3,  591,  591,  592,  592,  593,  593,
+      594,  594,  589,  589,  589,  595,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  589,  589,  589,  589,  597,  598,
+      598,  589,  599,  599,  600,  601,  601,  589,  595,  589,
+      589,  602,  589,  589,  589,  589,  589,  589,  589,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  589,
+
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  589,  589,  597,  598,  589,  599,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  603,
+      601,  589,  602,  589,  589,  589,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  589,
+      589,  604,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  589,  589,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,    0,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+
+      589,  589,  589,  589
     } ;
 
-static const flex_int16_t yy_nxt[1388] =
+static const flex_int16_t yy_nxt[1389] =
     {   0,
-      588,  155,   15,   15,   61,   61,  156,  156,   67,   62,
+      589,  155,   15,   15,   61,   61,  156,  156,   67,   62,
        62,   68,   67,  172,   70,   68,   70,   73,   73,   77,
        78,  156,  156,   70,  159,   70,  175,  175,  155,  176,
       176,  156,  156,  270,  271,  271,  271,  176,  176,  176,
-      176,  364,  271,   79,   16,   16,   17,   18,   19,   18,
+      176,  365,  271,   79,   16,   16,   17,   18,   19,   18,
        20,   21,   22,   23,   22,   24,   25,   26,   26,   17,
        27,   28,   29,   30,   31,   32,   33,   34,   35,   36,
        37,   38,   39,   40,   41,   42,   43,   44,   45,   46,
@@ -872,146 +872,146 @@ static const flex_int16_t yy_nxt[1388] =
        48,   49,   50,   51,   52,   53,   54,   17,   56,   57,
        58,   17,   17,   17,   17,   17,  110,  115,  116,   64,
        64,   17,   17,   17,   62,   62,  271,  271,   72,   74,
-       75,   75,  271,  271,   81,   71,  588,  588,  588,  588,
-       76,  588,   82,  588,   83,  110,  115,  116,  588,   84,
+       75,   75,  271,  271,   81,   71,  589,  589,  589,  589,
+       76,  589,   82,  589,   83,  110,  115,  116,  589,   84,
        17,   17,   17,   56,   57,   58,   17,   17,   17,   17,
        17,   65,   65,   81,  100,  111,   17,   17,   17,   76,
        85,   82,   95,   83,   86,  121,   96,   87,   84,  112,
-       97,  122,  133,  113,  588,  101,   98,  102,  114,   99,
+       97,  122,  133,  113,  589,  101,   98,  102,  114,   99,
 
-       88,  588,  588,  151,  111,   17,   17,  103,  588,   85,
-      588,   95,  588,   86,  121,   96,   87,  123,  112,   97,
+       88,  589,  589,  151,  111,   17,   17,  103,  589,   85,
+      589,   95,  589,   86,  121,   96,   87,  123,  112,   97,
       122,  133,  113,  124,  101,   98,  102,  114,   99,   88,
        89,  117,  151,  152,  153,  118,  103,   90,  130,  119,
       154,  125,  131,  177,   91,  120,  123,   92,   93,  126,
-       94,  588,  124,  127,  180,  132,  128,  129,  588,   89,
-      117,  181,  152,  153,  118,  588,   90,  130,  119,  154,
-      125,  131,  177,   91,  120,  588,   92,   93,  126,   94,
-      104,  588,  127,  180,  132,  128,  129,  148,  105,  149,
-      181,  106,  150,  178,  107,  138,  182,  108,  134,  588,
-
-      109,  179,  135,  139,   73,   73,  136,  588,  588,  104,
-      140,  141,  137,  588,   76,  183,  148,  105,  149,  185,
+       94,  589,  124,  127,  180,  132,  128,  129,  589,   89,
+      117,  181,  152,  153,  118,  589,   90,  130,  119,  154,
+      125,  131,  177,   91,  120,  589,   92,   93,  126,   94,
+      104,  589,  127,  180,  132,  128,  129,  148,  105,  149,
+      181,  106,  150,  178,  107,  138,  182,  108,  134,  589,
+
+      109,  179,  135,  139,   73,   73,  136,  589,  589,  104,
+      140,  141,  137,  589,   76,  183,  148,  105,  149,  185,
       106,  150,  178,  107,  138,  182,  108,  134,  184,  109,
-      179,  135,  139,  588,  186,  136,  174,  174,  588,  140,
+      179,  135,  139,  589,  186,  136,  174,  174,  589,  140,
       141,  137,  142,   76,  183,  192,   76,  187,  185,  143,
       144,  188,  193,   74,   75,   75,  145,  184,  194,  146,
       201,  195,  147,  186,   76,  189,  196,  190,  202,  191,
-      588,  142,  588,  588,  192,   76,  187,  203,  143,  144,
-      188,  193,  588,  204,  205,  145,  588,  194,  146,  201,
+      589,  142,  589,  589,  192,   76,  187,  203,  143,  144,
+      188,  193,  589,  204,  205,  145,  589,  194,  146,  201,
       195,  147,  162,   76,  189,  196,  190,  202,  191,  197,
 
       163,  164,  198,  206,  208,  209,  203,  165,  199,  210,
       211,  166,  204,  205,  207,  200,  212,  213,  214,  167,
-      215,  216,  218,  168,  217,  169,  588,  223,  197,  170,
+      215,  216,  218,  168,  217,  169,  589,  223,  197,  170,
       224,  198,  206,  208,  209,  225,  165,  199,  210,  211,
-      166,  588,  588,  207,  200,  212,  213,  214,  167,  215,
+      166,  589,  589,  207,  200,  212,  213,  214,  167,  215,
       216,  218,  168,  217,  169,  219,  223,  226,  170,  224,
       227,  229,  228,  230,  225,  220,  231,  232,  233,  234,
       221,  222,  235,  236,  237,  238,  239,  240,  242,  243,
       247,  241,  244,  248,  219,  252,  226,  245,  246,  227,
-      229,  228,  230,  588,  220,  231,  232,  233,  234,  221,
+      229,  228,  230,  589,  220,  231,  232,  233,  234,  221,
 
       222,  235,  236,  237,  238,  239,  240,  242,  243,  247,
       241,  244,  248,  249,  252,  253,  245,  246,  254,  255,
       256,  257,  250,  258,  259,  260,  262,  263,  264,  266,
       251,  267,  261,  269,  265,  174,  174,  268,  273,  274,
-      275,  276,  249,  277,  253,   76,  280,  254,  255,  256,
+      275,  276,  249,  277,  253,   76,  282,  254,  255,  256,
       257,  250,  258,  259,  260,  262,  263,  264,  266,  251,
-      267,  261,  269,  265,  278,  281,  268,  273,  274,  275,
-      276,  282,  277,  283,   76,  280,  279,  284,  285,  286,
-      287,  288,  289,  290,  291,  292,  293,  294,  295,  296,
-      297,  298,  299,  278,  281,  300,  301,  302,  303,  304,
+      267,  261,  269,  265,  278,  280,  268,  273,  274,  275,
+      276,  283,  277,  284,   76,  282,  279,  285,  286,  287,
+      281,  288,  289,  290,  291,  292,  293,  294,  295,  296,
+      297,  298,  299,  278,  280,  300,  301,  302,  303,  304,
 
-      282,  305,  283,  306,  307,  279,  284,  285,  286,  287,
+      283,  305,  284,  306,  307,  279,  285,  286,  287,  281,
       288,  289,  290,  291,  292,  293,  294,  295,  296,  297,
       298,  299,  308,  309,  300,  301,  302,  303,  304,  310,
-      305,  311,  306,  307,  312,  313,  314,  316,  317,  318,
-      319,  320,  321,  322,  323,  324,  315,  325,  326,  327,
-      328,  308,  309,  329,  330,  331,  333,  332,  310,  334,
-      311,  335,  336,  312,  313,  314,  316,  317,  318,  319,
-      320,  321,  322,  323,  324,  315,  325,  326,  327,  328,
-      337,  338,  329,  330,  331,  333,  332,  339,  334,  341,
-      335,  336,  342,  343,  344,  346,  347,  340,  348,  349,
-
-      350,  351,  352,  353,  345,  354,  355,  356,  357,  337,
-      338,  358,  361,  359,  362,  363,  339,  360,  341,  366,
-      367,  342,  343,  344,  346,  347,  368,  348,  349,  350,
-      351,  352,  353,  345,  354,  355,  356,  357,  369,  370,
-      358,  361,  359,  362,  363,  371,  360,  372,  366,  367,
-      373,  374,  375,  376,  377,  368,  378,  379,  380,  381,
+      305,  311,  306,  307,  312,  313,  314,  315,  317,  318,
+      319,  320,  321,  322,  323,  324,  325,  316,  326,  327,
+      328,  308,  309,  329,  330,  331,  334,  332,  310,  333,
+      311,  335,  336,  312,  313,  314,  315,  317,  318,  319,
+      320,  321,  322,  323,  324,  325,  316,  326,  327,  328,
+      337,  338,  329,  330,  331,  334,  332,  339,  333,  340,
+      335,  336,  342,  343,  344,  345,  347,  348,  349,  341,
+
+      350,  351,  352,  353,  354,  346,  355,  356,  357,  337,
+      338,  358,  359,  360,  362,  363,  339,  361,  340,  364,
+      367,  342,  343,  344,  345,  347,  348,  349,  368,  350,
+      351,  352,  353,  354,  346,  355,  356,  357,  369,  370,
+      358,  359,  360,  362,  363,  371,  361,  372,  364,  367,
+      373,  374,  375,  376,  377,  378,  379,  368,  380,  381,
       382,  383,  384,  385,  386,  387,  388,  369,  370,  389,
       390,  391,  392,  393,  371,  394,  372,  395,  396,  373,
-      374,  375,  376,  377,  397,  378,  379,  380,  381,  382,
+      374,  375,  376,  377,  378,  379,  397,  380,  381,  382,
       383,  384,  385,  386,  387,  388,  398,  399,  389,  390,
 
-      391,  392,  393,  401,  394,  402,  395,  396,  400,  403,
-      404,  405,  406,  397,  407,  408,  409,  410,  411,  412,
+      391,  392,  393,  400,  394,  402,  395,  396,  403,  404,
+      405,  406,  407,  408,  401,  397,  409,  410,  411,  412,
       413,  414,  415,  416,  417,  398,  399,  418,  419,  420,
-      421,  422,  401,  423,  402,  424,  425,  400,  403,  404,
-      405,  406,  426,  407,  408,  409,  410,  411,  412,  413,
+      421,  422,  400,  423,  402,  424,  425,  403,  404,  405,
+      406,  407,  408,  401,  426,  409,  410,  411,  412,  413,
       414,  415,  416,  417,  427,  428,  418,  419,  420,  421,
       422,  429,  423,  430,  424,  425,  431,  432,  433,  434,
-      435,  426,  436,  437,  438,  439,  440,  442,  443,  441,
-      444,  445,  446,  427,  428,  447,  448,  449,  450,  451,
+      435,  436,  437,  426,  438,  439,  440,  441,  443,  444,
+      442,  445,  446,  427,  428,  447,  448,  449,  450,  451,
       429,  452,  430,  453,  454,  431,  432,  433,  434,  435,
 
-      455,  436,  437,  438,  439,  440,  442,  443,  441,  444,
+      436,  437,  455,  438,  439,  440,  441,  443,  444,  442,
       445,  446,  456,  457,  447,  448,  449,  450,  451,  458,
-      452,  459,  453,  454,  460,  461,  462,  463,  465,  455,
-      464,  466,  467,  468,  469,  470,  471,  472,  473,  474,
+      452,  459,  453,  454,  460,  461,  462,  463,  466,  464,
+      467,  455,  465,  468,  469,  470,  471,  472,  473,  474,
       475,  456,  457,  476,  477,  478,  479,  480,  458,  481,
-      459,  482,  483,  460,  461,  462,  463,  465,  484,  464,
-      466,  467,  468,  469,  470,  471,  472,  473,  474,  475,
+      459,  482,  483,  460,  461,  462,  463,  466,  464,  467,
+      484,  465,  468,  469,  470,  471,  472,  473,  474,  475,
       485,  486,  476,  477,  478,  479,  480,  487,  481,  488,
-      482,  483,  489,  490,  491,  492,  493,  484,  494,  495,
+      482,  483,  489,  490,  491,  492,  493,  494,  495,  484,
       496,  497,  498,  499,  500,  501,  502,  503,  504,  485,
 
       486,  505,  506,  507,  508,  509,  487,  510,  488,  511,
-      512,  489,  490,  491,  492,  493,  513,  494,  495,  496,
+      512,  489,  490,  491,  492,  493,  494,  495,  513,  496,
       497,  498,  499,  500,  501,  502,  503,  504,  514,  515,
       505,  506,  507,  508,  509,  516,  510,  517,  511,  512,
-      518,  519,  520,  521,  522,  513,  523,  524,  525,  526,
+      518,  519,  520,  521,  522,  523,  524,  513,  525,  526,
       527,  528,  529,  530,  531,  532,  533,  514,  515,  534,
       535,  536,  537,  538,  516,  539,  517,  540,  541,  518,
-      519,  520,  521,  522,  542,  523,  524,  525,  526,  527,
+      519,  520,  521,  522,  523,  524,  542,  525,  526,  527,
       528,  529,  530,  531,  532,  533,  543,  544,  534,  535,
       536,  537,  538,  545,  539,  546,  540,  541,  547,  548,
 
-      549,  550,  551,  542,  552,  553,  554,  555,  556,  557,
+      549,  550,  551,  552,  553,  542,  554,  555,  556,  557,
       558,  559,  560,  561,  562,  543,  544,  563,  564,  565,
       566,  567,  545,  568,  546,  569,  570,  547,  548,  549,
-      550,  551,  571,  552,  553,  554,  555,  556,  557,  558,
+      550,  551,  552,  553,  571,  554,  555,  556,  557,  558,
       559,  560,  561,  562,  572,  573,  563,  564,  565,  566,
       567,  574,  568,  575,  569,  570,  576,  577,  578,  579,
-      580,  571,  581,  582,  583,  584,  585,  586,  587,  588,
-      588,  588,  588,  572,  573,  588,  588,  588,  588,  588,
-      574,  588,  575,  588,  588,  576,  577,  578,  579,  580,
-      588,  581,  582,  583,  584,  585,  586,  587,   14,   14,
-
-       14,   14,   14,   14,   14,   14,   14,   14,   59,   59,
-       59,   59,   59,   59,   59,   59,   59,   59,   60,   60,
-       60,   60,   60,   60,   60,   60,   60,   60,   63,   63,
-       63,   63,   63,   63,   63,   63,   63,   63,   66,   66,
-       66,   66,   66,   66,   66,   66,   66,   66,   69,   69,
-       80,   80,   80,  588,   80,  157,  157,  157,  157,  588,
-      157,  158,  158,  158,  588,  158,  158,  158,  158,  158,
-      158,  160,  160,  160,  588,  160,  160,  160,  160,  588,
-      160,  161,  161,  161,  161,  161,  161,  161,  161,  161,
-      161,  171,  171,  588,  171,  171,  171,  171,  171,  171,
-
-      171,  173,  588,  173,  173,  173,  173,  173,  173,  173,
-      173,  272,  272,  365,  365,   13,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588
+      580,  581,  582,  571,  583,  584,  585,  586,  587,  588,
+      589,  589,  589,  572,  573,  589,  589,  589,  589,  589,
+      574,  589,  575,  589,  589,  576,  577,  578,  579,  580,
+      581,  582,  589,  583,  584,  585,  586,  587,  588,   14,
+
+       14,   14,   14,   14,   14,   14,   14,   14,   14,   59,
+       59,   59,   59,   59,   59,   59,   59,   59,   59,   60,
+       60,   60,   60,   60,   60,   60,   60,   60,   60,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   66,
+       66,   66,   66,   66,   66,   66,   66,   66,   66,   69,
+       69,   80,   80,   80,  589,   80,  157,  157,  157,  157,
+      589,  157,  158,  158,  158,  589,  158,  158,  158,  158,
+      158,  158,  160,  160,  160,  589,  160,  160,  160,  160,
+      589,  160,  161,  161,  161,  161,  161,  161,  161,  161,
+      161,  161,  171,  171,  589,  171,  171,  171,  171,  171,
+
+      171,  171,  173,  589,  173,  173,  173,  173,  173,  173,
+      173,  173,  272,  272,  366,  366,   13,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589
     } ;
 
-static const flex_int16_t yy_chk[1388] =
+static const flex_int16_t yy_chk[1389] =
     {   0,
         0,  155,    1,    2,    7,    8,   57,   57,   11,    7,
         8,   11,   12,   68,   18,   12,   18,   25,   25,   27,
@@ -1028,7 +1028,7 @@ static const flex_int16_t yy_chk[1388] =
         3,    3,    3,    3,    3,    3,    3,    5,    5,    5,
         5,    5,    5,    5,    5,    5,   36,   39,   40,    9,
        10,    5,    5,    5,    9,   10,  271,  271,   24,   26,
-       26,   26,  364,  364,   30,   20,   13,    0,    0,    0,
+       26,   26,  365,  365,   30,   20,   13,    0,    0,    0,
        26,    0,   30,    0,   30,   36,   39,   40,    0,   30,
         5,    5,    6,    6,    6,    6,    6,    6,    6,    6,
         6,    9,   10,   30,   34,   37,    6,    6,    6,   26,
@@ -1072,103 +1072,103 @@ static const flex_int16_t yy_chk[1388] =
       132,  135,  137,  138,  139,  140,  135,  135,  141,  142,
       143,  144,  138,  146,  147,  148,  149,  150,  151,  152,
       138,  153,  148,  154,  151,  174,  174,  153,  179,  181,
-      182,  183,  138,  184,  140,  174,  186,  141,  142,  143,
+      182,  183,  138,  184,  140,  174,  187,  141,  142,  143,
       144,  138,  146,  147,  148,  149,  150,  151,  152,  138,
-      153,  148,  154,  151,  185,  187,  153,  179,  181,  182,
-      183,  188,  184,  189,  174,  186,  185,  190,  191,  192,
-      193,  194,  195,  197,  198,  199,  200,  201,  202,  203,
-      204,  206,  207,  185,  187,  208,  209,  210,  211,  212,
+      153,  148,  154,  151,  185,  186,  153,  179,  181,  182,
+      183,  188,  184,  189,  174,  187,  185,  190,  191,  192,
+      186,  193,  194,  195,  197,  198,  199,  200,  201,  202,
+      203,  204,  206,  185,  186,  207,  208,  209,  210,  211,
 
-      188,  213,  189,  214,  215,  185,  190,  191,  192,  193,
-      194,  195,  197,  198,  199,  200,  201,  202,  203,  204,
-      206,  207,  216,  217,  208,  209,  210,  211,  212,  218,
-      213,  219,  214,  215,  220,  221,  222,  223,  225,  226,
+      188,  212,  189,  213,  214,  185,  190,  191,  192,  186,
+      193,  194,  195,  197,  198,  199,  200,  201,  202,  203,
+      204,  206,  215,  216,  207,  208,  209,  210,  211,  217,
+      212,  218,  213,  214,  219,  220,  221,  222,  223,  225,
+      226,  227,  228,  229,  230,  231,  233,  222,  235,  236,
+      237,  215,  216,  238,  239,  240,  242,  241,  217,  241,
+      218,  243,  244,  219,  220,  221,  222,  223,  225,  226,
       227,  228,  229,  230,  231,  233,  222,  235,  236,  237,
-      238,  216,  217,  239,  240,  241,  242,  241,  218,  243,
-      219,  244,  245,  220,  221,  222,  223,  225,  226,  227,
-      228,  229,  230,  231,  233,  222,  235,  236,  237,  238,
-      246,  247,  239,  240,  241,  242,  241,  248,  243,  249,
-      244,  245,  250,  252,  253,  254,  255,  248,  256,  257,
-
-      258,  259,  260,  261,  253,  261,  262,  263,  264,  246,
-      247,  265,  267,  266,  268,  269,  248,  266,  249,  273,
-      274,  250,  252,  253,  254,  255,  275,  256,  257,  258,
-      259,  260,  261,  253,  261,  262,  263,  264,  276,  277,
-      265,  267,  266,  268,  269,  278,  266,  279,  273,  274,
-      281,  282,  283,  284,  286,  275,  287,  288,  289,  290,
-      291,  292,  293,  294,  295,  298,  299,  276,  277,  300,
-      301,  302,  303,  304,  278,  307,  279,  309,  311,  281,
-      282,  283,  284,  286,  312,  287,  288,  289,  290,  291,
-      292,  293,  294,  295,  298,  299,  313,  314,  300,  301,
-
-      302,  303,  304,  320,  307,  322,  309,  311,  314,  323,
-      324,  325,  326,  312,  328,  329,  330,  331,  332,  334,
-      336,  337,  338,  340,  341,  313,  314,  342,  343,  344,
-      345,  346,  320,  347,  322,  349,  351,  314,  323,  324,
-      325,  326,  352,  328,  329,  330,  331,  332,  334,  336,
-      337,  338,  340,  341,  353,  354,  342,  343,  344,  345,
-      346,  355,  347,  356,  349,  351,  357,  358,  360,  361,
-      363,  352,  367,  368,  369,  370,  371,  372,  373,  371,
-      375,  376,  377,  353,  354,  378,  379,  380,  381,  382,
-      355,  383,  356,  384,  385,  357,  358,  360,  361,  363,
-
-      386,  367,  368,  369,  370,  371,  372,  373,  371,  375,
-      376,  377,  387,  388,  378,  379,  380,  381,  382,  392,
-      383,  393,  384,  385,  395,  398,  399,  400,  402,  386,
-      400,  407,  408,  409,  410,  411,  413,  414,  416,  417,
-      418,  387,  388,  419,  420,  421,  422,  424,  392,  425,
-      393,  426,  428,  395,  398,  399,  400,  402,  429,  400,
-      407,  408,  409,  410,  411,  413,  414,  416,  417,  418,
-      431,  432,  419,  420,  421,  422,  424,  434,  425,  435,
-      426,  428,  436,  437,  439,  440,  441,  429,  442,  443,
-      445,  447,  448,  449,  450,  451,  453,  454,  457,  431,
-
-      432,  458,  459,  462,  463,  464,  434,  466,  435,  467,
-      468,  436,  437,  439,  440,  441,  469,  442,  443,  445,
-      447,  448,  449,  450,  451,  453,  454,  457,  470,  471,
-      458,  459,  462,  463,  464,  473,  466,  476,  467,  468,
-      479,  480,  481,  482,  486,  469,  488,  489,  491,  492,
-      493,  494,  495,  496,  499,  502,  503,  470,  471,  505,
-      508,  509,  510,  512,  473,  514,  476,  515,  516,  479,
-      480,  481,  482,  486,  517,  488,  489,  491,  492,  493,
-      494,  495,  496,  499,  502,  503,  518,  519,  505,  508,
-      509,  510,  512,  520,  514,  521,  515,  516,  523,  524,
-
-      525,  526,  527,  517,  528,  529,  530,  532,  534,  535,
-      537,  538,  540,  541,  543,  518,  519,  544,  545,  546,
-      547,  549,  520,  550,  521,  551,  552,  523,  524,  525,
-      526,  527,  554,  528,  529,  530,  532,  534,  535,  537,
-      538,  540,  541,  543,  555,  558,  544,  545,  546,  547,
-      549,  560,  550,  561,  551,  552,  564,  568,  569,  570,
-      575,  554,  576,  577,  580,  582,  583,  584,  586,    0,
-        0,    0,    0,  555,  558,    0,    0,    0,    0,    0,
-      560,    0,  561,    0,    0,  564,  568,  569,  570,  575,
-        0,  576,  577,  580,  582,  583,  584,  586,  589,  589,
-
-      589,  589,  589,  589,  589,  589,  589,  589,  590,  590,
-      590,  590,  590,  590,  590,  590,  590,  590,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  592,  592,
-      592,  592,  592,  592,  592,  592,  592,  592,  593,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  594,  594,
-      595,  595,  595,    0,  595,  596,  596,  596,  596,    0,
-      596,  597,  597,  597,    0,  597,  597,  597,  597,  597,
-      597,  598,  598,  598,    0,  598,  598,  598,  598,    0,
-      598,  599,  599,  599,  599,  599,  599,  599,  599,  599,
-      599,  600,  600,    0,  600,  600,  600,  600,  600,  600,
-
-      600,  601,    0,  601,  601,  601,  601,  601,  601,  601,
-      601,  602,  602,  603,  603,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588,  588,  588,  588,
-      588,  588,  588,  588,  588,  588,  588
+      245,  246,  238,  239,  240,  242,  241,  247,  241,  248,
+      243,  244,  249,  250,  252,  253,  254,  255,  256,  248,
+
+      257,  258,  259,  260,  261,  253,  261,  262,  263,  245,
+      246,  264,  265,  266,  267,  268,  247,  266,  248,  269,
+      273,  249,  250,  252,  253,  254,  255,  256,  274,  257,
+      258,  259,  260,  261,  253,  261,  262,  263,  275,  276,
+      264,  265,  266,  267,  268,  277,  266,  278,  269,  273,
+      279,  282,  283,  284,  285,  287,  288,  274,  289,  290,
+      291,  292,  293,  294,  295,  296,  299,  275,  276,  300,
+      301,  302,  303,  304,  277,  305,  278,  308,  310,  279,
+      282,  283,  284,  285,  287,  288,  312,  289,  290,  291,
+      292,  293,  294,  295,  296,  299,  313,  314,  300,  301,
+
+      302,  303,  304,  315,  305,  321,  308,  310,  323,  324,
+      325,  326,  327,  329,  315,  312,  330,  331,  332,  333,
+      335,  337,  338,  339,  341,  313,  314,  342,  343,  344,
+      345,  346,  315,  347,  321,  348,  350,  323,  324,  325,
+      326,  327,  329,  315,  352,  330,  331,  332,  333,  335,
+      337,  338,  339,  341,  353,  354,  342,  343,  344,  345,
+      346,  355,  347,  356,  348,  350,  357,  358,  359,  361,
+      362,  364,  368,  352,  369,  370,  371,  372,  373,  374,
+      372,  376,  377,  353,  354,  378,  379,  380,  381,  382,
+      355,  383,  356,  384,  385,  357,  358,  359,  361,  362,
+
+      364,  368,  386,  369,  370,  371,  372,  373,  374,  372,
+      376,  377,  387,  388,  378,  379,  380,  381,  382,  389,
+      383,  393,  384,  385,  394,  396,  399,  400,  403,  401,
+      408,  386,  401,  409,  410,  411,  412,  414,  415,  417,
+      418,  387,  388,  419,  420,  421,  422,  423,  389,  425,
+      393,  426,  427,  394,  396,  399,  400,  403,  401,  408,
+      429,  401,  409,  410,  411,  412,  414,  415,  417,  418,
+      430,  432,  419,  420,  421,  422,  423,  433,  425,  435,
+      426,  427,  436,  437,  438,  440,  441,  442,  443,  429,
+      444,  446,  448,  449,  450,  451,  452,  454,  455,  430,
+
+      432,  458,  459,  460,  463,  464,  433,  465,  435,  467,
+      468,  436,  437,  438,  440,  441,  442,  443,  469,  444,
+      446,  448,  449,  450,  451,  452,  454,  455,  470,  471,
+      458,  459,  460,  463,  464,  472,  465,  474,  467,  468,
+      477,  480,  481,  482,  483,  487,  489,  469,  490,  492,
+      493,  494,  495,  496,  497,  500,  503,  470,  471,  504,
+      506,  509,  510,  511,  472,  513,  474,  515,  516,  477,
+      480,  481,  482,  483,  487,  489,  517,  490,  492,  493,
+      494,  495,  496,  497,  500,  503,  518,  519,  504,  506,
+      509,  510,  511,  520,  513,  521,  515,  516,  522,  524,
+
+      525,  526,  527,  528,  529,  517,  530,  531,  533,  535,
+      536,  538,  539,  541,  542,  518,  519,  544,  545,  546,
+      547,  548,  520,  550,  521,  551,  552,  522,  524,  525,
+      526,  527,  528,  529,  553,  530,  531,  533,  535,  536,
+      538,  539,  541,  542,  555,  556,  544,  545,  546,  547,
+      548,  559,  550,  561,  551,  552,  562,  565,  569,  570,
+      571,  576,  577,  553,  578,  581,  583,  584,  585,  587,
+        0,    0,    0,  555,  556,    0,    0,    0,    0,    0,
+      559,    0,  561,    0,    0,  562,  565,  569,  570,  571,
+      576,  577,    0,  578,  581,  583,  584,  585,  587,  590,
+
+      590,  590,  590,  590,  590,  590,  590,  590,  590,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  592,
+      592,  592,  592,  592,  592,  592,  592,  592,  592,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  594,
+      594,  594,  594,  594,  594,  594,  594,  594,  594,  595,
+      595,  596,  596,  596,    0,  596,  597,  597,  597,  597,
+        0,  597,  598,  598,  598,    0,  598,  598,  598,  598,
+      598,  598,  599,  599,  599,    0,  599,  599,  599,  599,
+        0,  599,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  601,  601,    0,  601,  601,  601,  601,  601,
+
+      601,  601,  602,    0,  602,  602,  602,  602,  602,  602,
+      602,  602,  603,  603,  604,  604,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
+      589,  589,  589,  589,  589,  589,  589,  589
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static const flex_int32_t yy_rule_can_match_eol[165] =
+static const flex_int32_t yy_rule_can_match_eol[166] =
     {   0,
 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1177,8 +1177,8 @@ static const flex_int32_t yy_rule_can_match_eol[165] =
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 
-    0, 1, 0, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 
+    0, 0, 1, 0, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -1613,13 +1613,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 589 )
+				if ( yy_current_state >= 590 )
 					yy_c = yy_meta[yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 588 );
+		while ( yy_current_state != 589 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1783,17 +1783,17 @@ return TOKEN_CASE;
 case 21:
 YY_RULE_SETUP
 #line 187 "../SqlLexer.lpp"
-return TOKEN_CSB_TREE;
+return TOKEN_CAST;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
 #line 188 "../SqlLexer.lpp"
-return TOKEN_BY;
+return TOKEN_CSB_TREE;
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
 #line 189 "../SqlLexer.lpp"
-return TOKEN_CHARACTER;
+return TOKEN_BY;
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
@@ -1803,67 +1803,67 @@ return TOKEN_CHARACTER;
 case 25:
 YY_RULE_SETUP
 #line 191 "../SqlLexer.lpp"
-return TOKEN_CHECK;
+return TOKEN_CHARACTER;
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
 #line 192 "../SqlLexer.lpp"
-return TOKEN_COLUMN;
+return TOKEN_CHECK;
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
 #line 193 "../SqlLexer.lpp"
-return TOKEN_CONSTRAINT;
+return TOKEN_COLUMN;
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
 #line 194 "../SqlLexer.lpp"
-return TOKEN_COPY;
+return TOKEN_CONSTRAINT;
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
 #line 195 "../SqlLexer.lpp"
-return TOKEN_CREATE;
+return TOKEN_COPY;
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
 #line 196 "../SqlLexer.lpp"
-return TOKEN_CURRENT;
+return TOKEN_CREATE;
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
 #line 197 "../SqlLexer.lpp"
-return TOKEN_DATE;
+return TOKEN_CURRENT;
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
 #line 198 "../SqlLexer.lpp"
-return TOKEN_DATETIME;
+return TOKEN_DATE;
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
 #line 199 "../SqlLexer.lpp"
-return TOKEN_DAY;
+return TOKEN_DATETIME;
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
 #line 200 "../SqlLexer.lpp"
-return TOKEN_DECIMAL;
+return TOKEN_DAY;
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
 #line 201 "../SqlLexer.lpp"
-return TOKEN_DEFAULT;
+return TOKEN_DECIMAL;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
 #line 202 "../SqlLexer.lpp"
-return TOKEN_DELETE;
+return TOKEN_DEFAULT;
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
 #line 203 "../SqlLexer.lpp"
-return TOKEN_DESC;
+return TOKEN_DELETE;
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
@@ -1873,122 +1873,122 @@ return TOKEN_DESC;
 case 39:
 YY_RULE_SETUP
 #line 205 "../SqlLexer.lpp"
-return TOKEN_DISTINCT;
+return TOKEN_DESC;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
 #line 206 "../SqlLexer.lpp"
-return TOKEN_DOUBLE;
+return TOKEN_DISTINCT;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
 #line 207 "../SqlLexer.lpp"
-return TOKEN_DROP;
+return TOKEN_DOUBLE;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
 #line 208 "../SqlLexer.lpp"
-return TOKEN_ELSE;
+return TOKEN_DROP;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
 #line 209 "../SqlLexer.lpp"
-return TOKEN_END;
+return TOKEN_ELSE;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
 #line 210 "../SqlLexer.lpp"
-return TOKEN_EXISTS;
+return TOKEN_END;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 211 "../SqlLexer.lpp"
-return TOKEN_EXTRACT;
+return TOKEN_EXISTS;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 212 "../SqlLexer.lpp"
-return TOKEN_FALSE;
+return TOKEN_EXTRACT;
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 213 "../SqlLexer.lpp"
-return TOKEN_FIRST;
+return TOKEN_FALSE;
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 214 "../SqlLexer.lpp"
-return TOKEN_FLOAT;
+return TOKEN_FIRST;
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 215 "../SqlLexer.lpp"
-return TOKEN_FOLLOWING;
+return TOKEN_FLOAT;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 216 "../SqlLexer.lpp"
-return TOKEN_FOR;
+return TOKEN_FOLLOWING;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 217 "../SqlLexer.lpp"
-return TOKEN_FOREIGN;
+return TOKEN_FOR;
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 218 "../SqlLexer.lpp"
-return TOKEN_FROM;
+return TOKEN_FOREIGN;
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
 #line 219 "../SqlLexer.lpp"
-return TOKEN_FULL;
+return TOKEN_FROM;
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
 #line 220 "../SqlLexer.lpp"
-return TOKEN_GROUP;
+return TOKEN_FULL;
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
 #line 221 "../SqlLexer.lpp"
-return TOKEN_HASH;
+return TOKEN_GROUP;
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
 #line 222 "../SqlLexer.lpp"
-return TOKEN_HAVING;
+return TOKEN_HASH;
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
 #line 223 "../SqlLexer.lpp"
-return TOKEN_HOUR;
+return TOKEN_HAVING;
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
 #line 224 "../SqlLexer.lpp"
-return TOKEN_IN;
+return TOKEN_HOUR;
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
 #line 225 "../SqlLexer.lpp"
-return TOKEN_INDEX;
+return TOKEN_IN;
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
 #line 226 "../SqlLexer.lpp"
-return TOKEN_INNER;
+return TOKEN_INDEX;
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
 #line 227 "../SqlLexer.lpp"
-return TOKEN_INSERT;
+return TOKEN_INNER;
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
 #line 228 "../SqlLexer.lpp"
-return TOKEN_INTEGER;
+return TOKEN_INSERT;
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
@@ -1998,337 +1998,337 @@ return TOKEN_INTEGER;
 case 64:
 YY_RULE_SETUP
 #line 230 "../SqlLexer.lpp"
-return TOKEN_INTERSECT;
+return TOKEN_INTEGER;
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
 #line 231 "../SqlLexer.lpp"
-return TOKEN_INTERVAL;
+return TOKEN_INTERSECT;
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
 #line 232 "../SqlLexer.lpp"
-return TOKEN_INTO;
+return TOKEN_INTERVAL;
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
 #line 233 "../SqlLexer.lpp"
-return TOKEN_IS;
+return TOKEN_INTO;
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
 #line 234 "../SqlLexer.lpp"
-return TOKEN_JOIN;
+return TOKEN_IS;
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
 #line 235 "../SqlLexer.lpp"
-return TOKEN_KEY;
+return TOKEN_JOIN;
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
 #line 236 "../SqlLexer.lpp"
-return TOKEN_LAST;
+return TOKEN_KEY;
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
 #line 237 "../SqlLexer.lpp"
-return TOKEN_LEFT;
+return TOKEN_LAST;
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
 #line 238 "../SqlLexer.lpp"
-return TOKEN_LIKE;
+return TOKEN_LEFT;
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
 #line 239 "../SqlLexer.lpp"
-return TOKEN_LIMIT;
+return TOKEN_LIKE;
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
 #line 240 "../SqlLexer.lpp"
-return TOKEN_LONG;
+return TOKEN_LIMIT;
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
 #line 241 "../SqlLexer.lpp"
-return TOKEN_MINUTE;
+return TOKEN_LONG;
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
 #line 242 "../SqlLexer.lpp"
-return TOKEN_MONTH;
+return TOKEN_MINUTE;
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
 #line 243 "../SqlLexer.lpp"
-return TOKEN_NOT;
+return TOKEN_MONTH;
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
 #line 244 "../SqlLexer.lpp"
-return TOKEN_NULL;
+return TOKEN_NOT;
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
 #line 245 "../SqlLexer.lpp"
-return TOKEN_NULLS;
+return TOKEN_NULL;
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
 #line 246 "../SqlLexer.lpp"
-return TOKEN_OFF;
+return TOKEN_NULLS;
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
 #line 247 "../SqlLexer.lpp"
-return TOKEN_ON;
+return TOKEN_OFF;
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
 #line 248 "../SqlLexer.lpp"
-return TOKEN_OR;
+return TOKEN_ON;
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
 #line 249 "../SqlLexer.lpp"
-return TOKEN_ORDER;
+return TOKEN_OR;
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
 #line 250 "../SqlLexer.lpp"
-return TOKEN_OUTER;
+return TOKEN_ORDER;
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
 #line 251 "../SqlLexer.lpp"
-return TOKEN_OVER;
+return TOKEN_OUTER;
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
 #line 252 "../SqlLexer.lpp"
-return TOKEN_PARTITION;
+return TOKEN_OVER;
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
 #line 253 "../SqlLexer.lpp"
-return TOKEN_PARTITIONS;
+return TOKEN_PARTITION;
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
 #line 254 "../SqlLexer.lpp"
-return TOKEN_PERCENT;
+return TOKEN_PARTITIONS;
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
 #line 255 "../SqlLexer.lpp"
-return TOKEN_PRECEDING;
+return TOKEN_PERCENT;
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
 #line 256 "../SqlLexer.lpp"
-return TOKEN_PRIMARY;
+return TOKEN_PRECEDING;
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
 #line 257 "../SqlLexer.lpp"
-return TOKEN_PRIORITY;
+return TOKEN_PRIMARY;
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
 #line 258 "../SqlLexer.lpp"
-return TOKEN_QUIT;
+return TOKEN_PRIORITY;
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
 #line 259 "../SqlLexer.lpp"
-return TOKEN_RANGE;
+return TOKEN_QUIT;
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
 #line 260 "../SqlLexer.lpp"
-return TOKEN_REAL;
+return TOKEN_RANGE;
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
 #line 261 "../SqlLexer.lpp"
-return TOKEN_REFERENCES;
+return TOKEN_REAL;
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
 #line 262 "../SqlLexer.lpp"
-return TOKEN_REGEXP;
+return TOKEN_REFERENCES;
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
 #line 263 "../SqlLexer.lpp"
-return TOKEN_RIGHT;
+return TOKEN_REGEXP;
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
 #line 264 "../SqlLexer.lpp"
-return TOKEN_ROW;
+return TOKEN_RIGHT;
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
 #line 265 "../SqlLexer.lpp"
-return TOKEN_ROW_DELIMITER;
+return TOKEN_ROW;
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
 #line 266 "../SqlLexer.lpp"
-return TOKEN_ROWS;
+return TOKEN_ROW_DELIMITER;
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
 #line 267 "../SqlLexer.lpp"
-return TOKEN_SECOND;
+return TOKEN_ROWS;
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
 #line 268 "../SqlLexer.lpp"
-return TOKEN_SELECT;
+return TOKEN_SECOND;
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
 #line 269 "../SqlLexer.lpp"
-return TOKEN_SET;
+return TOKEN_SELECT;
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
 #line 270 "../SqlLexer.lpp"
-return TOKEN_SMA;
+return TOKEN_SET;
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
 #line 271 "../SqlLexer.lpp"
-return TOKEN_SMALLINT;
+return TOKEN_SMA;
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
 #line 272 "../SqlLexer.lpp"
-return TOKEN_STDERR;
+return TOKEN_SMALLINT;
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
 #line 273 "../SqlLexer.lpp"
-return TOKEN_STDOUT;
+return TOKEN_STDERR;
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
 #line 274 "../SqlLexer.lpp"
-return TOKEN_SUBSTRING;
+return TOKEN_STDOUT;
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
 #line 275 "../SqlLexer.lpp"
-return TOKEN_TABLE;
+return TOKEN_SUBSTRING;
 	YY_BREAK
 case 110:
 YY_RULE_SETUP
 #line 276 "../SqlLexer.lpp"
-return TOKEN_THEN;
+return TOKEN_TABLE;
 	YY_BREAK
 case 111:
 YY_RULE_SETUP
 #line 277 "../SqlLexer.lpp"
-return TOKEN_TIME;
+return TOKEN_THEN;
 	YY_BREAK
 case 112:
 YY_RULE_SETUP
 #line 278 "../SqlLexer.lpp"
-return TOKEN_TIMESTAMP;
+return TOKEN_TIME;
 	YY_BREAK
 case 113:
 YY_RULE_SETUP
 #line 279 "../SqlLexer.lpp"
-return TOKEN_TO;
+return TOKEN_TIMESTAMP;
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
 #line 280 "../SqlLexer.lpp"
-return TOKEN_TRUE;
+return TOKEN_TO;
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
 #line 281 "../SqlLexer.lpp"
-return TOKEN_TUPLESAMPLE;
+return TOKEN_TRUE;
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
 #line 282 "../SqlLexer.lpp"
-return TOKEN_UNBOUNDED;
+return TOKEN_TUPLESAMPLE;
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
 #line 283 "../SqlLexer.lpp"
-return TOKEN_UNION;
+return TOKEN_UNBOUNDED;
 	YY_BREAK
 case 118:
 YY_RULE_SETUP
 #line 284 "../SqlLexer.lpp"
-return TOKEN_UNIQUE;
+return TOKEN_UNION;
 	YY_BREAK
 case 119:
 YY_RULE_SETUP
 #line 285 "../SqlLexer.lpp"
-return TOKEN_UPDATE;
+return TOKEN_UNIQUE;
 	YY_BREAK
 case 120:
 YY_RULE_SETUP
 #line 286 "../SqlLexer.lpp"
-return TOKEN_USING;
+return TOKEN_UPDATE;
 	YY_BREAK
 case 121:
 YY_RULE_SETUP
 #line 287 "../SqlLexer.lpp"
-return TOKEN_VALUES;
+return TOKEN_USING;
 	YY_BREAK
 case 122:
 YY_RULE_SETUP
 #line 288 "../SqlLexer.lpp"
-return TOKEN_VARCHAR;
+return TOKEN_VALUES;
 	YY_BREAK
 case 123:
 YY_RULE_SETUP
 #line 289 "../SqlLexer.lpp"
-return TOKEN_WHEN;
+return TOKEN_VARCHAR;
 	YY_BREAK
 case 124:
 YY_RULE_SETUP
 #line 290 "../SqlLexer.lpp"
-return TOKEN_WHERE;
+return TOKEN_WHEN;
 	YY_BREAK
 case 125:
 YY_RULE_SETUP
 #line 291 "../SqlLexer.lpp"
-return TOKEN_WINDOW;
+return TOKEN_WHERE;
 	YY_BREAK
 case 126:
 YY_RULE_SETUP
 #line 292 "../SqlLexer.lpp"
-return TOKEN_WITH;
+return TOKEN_WINDOW;
 	YY_BREAK
 case 127:
 YY_RULE_SETUP
 #line 293 "../SqlLexer.lpp"
-return TOKEN_YEAR;
+return TOKEN_WITH;
 	YY_BREAK
 case 128:
 YY_RULE_SETUP
 #line 294 "../SqlLexer.lpp"
-return TOKEN_YEARMONTH;
+return TOKEN_YEAR;
 	YY_BREAK
 case 129:
 YY_RULE_SETUP
-#line 296 "../SqlLexer.lpp"
-return TOKEN_EQ;
+#line 295 "../SqlLexer.lpp"
+return TOKEN_YEARMONTH;
 	YY_BREAK
 case 130:
 YY_RULE_SETUP
 #line 297 "../SqlLexer.lpp"
-return TOKEN_NEQ;
+return TOKEN_EQ;
 	YY_BREAK
 case 131:
 YY_RULE_SETUP
@@ -2338,56 +2338,61 @@ return TOKEN_NEQ;
 case 132:
 YY_RULE_SETUP
 #line 299 "../SqlLexer.lpp"
-return TOKEN_LT;
+return TOKEN_NEQ;
 	YY_BREAK
 case 133:
 YY_RULE_SETUP
 #line 300 "../SqlLexer.lpp"
-return TOKEN_GT;
+return TOKEN_LT;
 	YY_BREAK
 case 134:
 YY_RULE_SETUP
 #line 301 "../SqlLexer.lpp"
-return TOKEN_LEQ;
+return TOKEN_GT;
 	YY_BREAK
 case 135:
 YY_RULE_SETUP
 #line 302 "../SqlLexer.lpp"
-return TOKEN_GEQ;
+return TOKEN_LEQ;
 	YY_BREAK
 case 136:
 YY_RULE_SETUP
-#line 304 "../SqlLexer.lpp"
-return yytext[0];
+#line 303 "../SqlLexer.lpp"
+return TOKEN_GEQ;
 	YY_BREAK
 case 137:
 YY_RULE_SETUP
 #line 305 "../SqlLexer.lpp"
 return yytext[0];
 	YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 306 "../SqlLexer.lpp"
+return yytext[0];
+	YY_BREAK
 /**
     * Quoted strings. Prefacing a string with an 'e' or 'E' causes escape
     * sequences to be processed (as in PostgreSQL).
     **/
-case 138:
+case 139:
 YY_RULE_SETUP
-#line 311 "../SqlLexer.lpp"
+#line 312 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED_ESCAPED);
   }
 	YY_BREAK
-case 139:
+case 140:
 YY_RULE_SETUP
-#line 316 "../SqlLexer.lpp"
+#line 317 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED);
   }
 	YY_BREAK
-case 140:
+case 141:
 YY_RULE_SETUP
-#line 321 "../SqlLexer.lpp"
+#line 322 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_DOUBLE_QUOTED);
@@ -2399,7 +2404,7 @@ YY_RULE_SETUP
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED):
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED_ESCAPED):
 case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
-#line 330 "../SqlLexer.lpp"
+#line 331 "../SqlLexer.lpp"
 {
     delete yylval->string_value_;
     BEGIN(INITIAL);
@@ -2410,9 +2415,9 @@ case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
 
 /* Process escape sequences. */
 
-case 141:
+case 142:
 YY_RULE_SETUP
-#line 340 "../SqlLexer.lpp"
+#line 341 "../SqlLexer.lpp"
 {
     /* Octal code */
     unsigned int code;
@@ -2426,9 +2431,9 @@ YY_RULE_SETUP
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 142:
+case 143:
 YY_RULE_SETUP
-#line 352 "../SqlLexer.lpp"
+#line 353 "../SqlLexer.lpp"
 {
     /* Hexadecimal code */
     unsigned int code;
@@ -2436,9 +2441,9 @@ YY_RULE_SETUP
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 143:
+case 144:
 YY_RULE_SETUP
-#line 358 "../SqlLexer.lpp"
+#line 359 "../SqlLexer.lpp"
 {
     /* A numeric escape sequence that isn't correctly specified. */
     delete yylval->string_value_;
@@ -2447,58 +2452,58 @@ YY_RULE_SETUP
     return TOKEN_LEX_ERROR;
   }
 	YY_BREAK
-case 144:
+case 145:
 YY_RULE_SETUP
-#line 365 "../SqlLexer.lpp"
+#line 366 "../SqlLexer.lpp"
 {
     /* Backspace */
     yylval->string_value_->push_back('\b');
   }
 	YY_BREAK
-case 145:
+case 146:
 YY_RULE_SETUP
-#line 369 "../SqlLexer.lpp"
+#line 370 "../SqlLexer.lpp"
 {
     /* Form-feed */
     yylval->string_value_->push_back('\f');
   }
 	YY_BREAK
-case 146:
+case 147:
 YY_RULE_SETUP
-#line 373 "../SqlLexer.lpp"
+#line 374 "../SqlLexer.lpp"
 {
     /* Newline */
     yylval->string_value_->push_back('\n');
   }
 	YY_BREAK
-case 147:
+case 148:
 YY_RULE_SETUP
-#line 377 "../SqlLexer.lpp"
+#line 378 "../SqlLexer.lpp"
 {
     /* Carriage-return */
     yylval->string_value_->push_back('\r');
   }
 	YY_BREAK
-case 148:
+case 149:
 YY_RULE_SETUP
-#line 381 "../SqlLexer.lpp"
+#line 382 "../SqlLexer.lpp"
 {
     /* Horizontal Tab */
     yylval->string_value_->push_back('\t');
   }
 	YY_BREAK
-case 149:
-/* rule 149 can match eol */
+case 150:
+/* rule 150 can match eol */
 YY_RULE_SETUP
-#line 385 "../SqlLexer.lpp"
+#line 386 "../SqlLexer.lpp"
 {
     /* Any other character (including actual newline or carriage return) */
     yylval->string_value_->push_back(yytext[1]);
   }
 	YY_BREAK
-case 150:
+case 151:
 YY_RULE_SETUP
-#line 389 "../SqlLexer.lpp"
+#line 390 "../SqlLexer.lpp"
 {
     /* This should only be encountered right before an EOF. */
     delete yylval->string_value_;
@@ -2509,17 +2514,17 @@ YY_RULE_SETUP
 	YY_BREAK
 
 
-case 151:
+case 152:
 YY_RULE_SETUP
-#line 399 "../SqlLexer.lpp"
+#line 400 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('\'');
   }
 	YY_BREAK
-case 152:
+case 153:
 YY_RULE_SETUP
-#line 403 "../SqlLexer.lpp"
+#line 404 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2528,17 +2533,17 @@ YY_RULE_SETUP
 	YY_BREAK
 
 
-case 153:
+case 154:
 YY_RULE_SETUP
-#line 411 "../SqlLexer.lpp"
+#line 412 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('"');
   }
 	YY_BREAK
-case 154:
+case 155:
 YY_RULE_SETUP
-#line 415 "../SqlLexer.lpp"
+#line 416 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2546,94 +2551,94 @@ YY_RULE_SETUP
   }
 	YY_BREAK
 
-case 155:
-/* rule 155 can match eol */
+case 156:
+/* rule 156 can match eol */
 YY_RULE_SETUP
-#line 422 "../SqlLexer.lpp"
+#line 423 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 156:
-/* rule 156 can match eol */
+case 157:
+/* rule 157 can match eol */
 YY_RULE_SETUP
-#line 427 "../SqlLexer.lpp"
+#line 428 "../SqlLexer.lpp"
 {
   /* Scan up to a quote or escape sequence. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 157:
-/* rule 157 can match eol */
+case 158:
+/* rule 158 can match eol */
 YY_RULE_SETUP
-#line 432 "../SqlLexer.lpp"
+#line 433 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
 
-case 158:
+case 159:
 YY_RULE_SETUP
-#line 438 "../SqlLexer.lpp"
+#line 439 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(
         yylloc->first_line, yylloc->first_column, std::string(yytext, yyleng));
     return TOKEN_NAME;
   }
 	YY_BREAK
-case 159:
+case 160:
 YY_RULE_SETUP
-#line 444 "../SqlLexer.lpp"
+#line 445 "../SqlLexer.lpp"
 {
     yylval->numeric_literal_value_ = new quickstep::NumericParseLiteralValue(
         yylloc->first_line, yylloc->first_column, yytext);
     return TOKEN_UNSIGNED_NUMVAL;
   }
 	YY_BREAK
-case 160:
+case 161:
 YY_RULE_SETUP
-#line 450 "../SqlLexer.lpp"
+#line 451 "../SqlLexer.lpp"
 /* comment */
 	YY_BREAK
-case 161:
-/* rule 161 can match eol */
+case 162:
+/* rule 162 can match eol */
 YY_RULE_SETUP
-#line 452 "../SqlLexer.lpp"
+#line 453 "../SqlLexer.lpp"
 { yycolumn = 0; }
 	YY_BREAK
-case 162:
+case 163:
 YY_RULE_SETUP
-#line 454 "../SqlLexer.lpp"
+#line 455 "../SqlLexer.lpp"
 ; /* ignore white space */
 	YY_BREAK
 /* CONDITION_SQL */
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(CONDITION_COMMAND):
 case YY_STATE_EOF(CONDITION_SQL):
-#line 458 "../SqlLexer.lpp"
+#line 459 "../SqlLexer.lpp"
 {
   /* All conditions except for mutli-state string extracting conditions. */
   BEGIN(INITIAL);
   return TOKEN_EOF;
 }
 	YY_BREAK
-case 163:
+case 164:
 YY_RULE_SETUP
-#line 464 "../SqlLexer.lpp"
+#line 465 "../SqlLexer.lpp"
 {
   BEGIN(INITIAL);
   quickstep_yyerror(NULL, yyscanner, NULL, "illegal character");
   return TOKEN_LEX_ERROR;
 }
 	YY_BREAK
-case 164:
+case 165:
 YY_RULE_SETUP
-#line 470 "../SqlLexer.lpp"
+#line 471 "../SqlLexer.lpp"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 2636 "SqlLexer_gen.cpp"
+#line 2641 "SqlLexer_gen.cpp"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2931,7 +2936,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 589 )
+			if ( yy_current_state >= 590 )
 				yy_c = yy_meta[yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -2960,11 +2965,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 589 )
+		if ( yy_current_state >= 590 )
 			yy_c = yy_meta[yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-	yy_is_jam = (yy_current_state == 588);
+	yy_is_jam = (yy_current_state == 589);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -3794,6 +3799,6 @@ void yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 470 "../SqlLexer.lpp"
+#line 471 "../SqlLexer.lpp"
 
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/preprocessed/SqlLexer_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.hpp b/parser/preprocessed/SqlLexer_gen.hpp
index 5fafae5..479b72d 100644
--- a/parser/preprocessed/SqlLexer_gen.hpp
+++ b/parser/preprocessed/SqlLexer_gen.hpp
@@ -733,7 +733,7 @@ extern int yylex \
 #undef yyTABLES_NAME
 #endif
 
-#line 470 "../SqlLexer.lpp"
+#line 471 "../SqlLexer.lpp"
 
 
 #line 739 "SqlLexer_gen.hpp"


[04/38] incubator-quickstep git commit: More updates to types

Posted by ji...@apache.org.
More updates to types


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/82697640
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/82697640
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/82697640

Branch: refs/heads/refactor-type
Commit: 826976406be8cba5cda245916c096361910de108
Parents: 843a172
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Wed Oct 4 03:21:44 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 parser/ParseDataType.cpp              |   6 +-
 parser/ParseDataType.hpp              |  12 ++--
 query_optimizer/resolver/Resolver.cpp | 108 ++++++++++++++++++++++++-----
 query_optimizer/resolver/Resolver.hpp |   3 +
 types/ArrayType.cpp                   |   7 ++
 types/ArrayType.hpp                   |  10 ++-
 types/GenericValue.hpp                |  35 +++++++---
 types/TypeFactory-decl.hpp            |  12 ++++
 types/TypeFactory.cpp                 |  45 ++++++++++--
 types/TypeSynthesizer.hpp             |   6 ++
 10 files changed, 197 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/parser/ParseDataType.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseDataType.cpp b/parser/ParseDataType.cpp
index b960961..7892122 100644
--- a/parser/ParseDataType.cpp
+++ b/parser/ParseDataType.cpp
@@ -33,11 +33,11 @@ void ParseDataType::getFieldStringItems(
     std::vector<const ParseTreeNode*> *non_container_child_fields,
     std::vector<std::string> *container_child_field_names,
     std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
-  inline_field_names->emplace_back("name");
-  inline_field_values->emplace_back(name_->value());
+  inline_field_names->emplace_back("type_name");
+  inline_field_values->emplace_back(type_name_->value());
 
   inline_field_names->emplace_back("nullable");
-
+  inline_field_values->emplace_back(nullable_ ? "true" : "false");
 
   container_child_field_names->emplace_back("parameters");
   container_child_fields->emplace_back();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/parser/ParseDataType.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseDataType.hpp b/parser/ParseDataType.hpp
index 96b7b96..b554011 100644
--- a/parser/ParseDataType.hpp
+++ b/parser/ParseDataType.hpp
@@ -41,7 +41,7 @@ class Type;
 
 class ParseDataTypeParameter : public ParseTreeNode {
  public:
-  enum class ParameterType {
+  enum ParameterType {
     kDataType,
     kLiteralValue
   };
@@ -64,15 +64,19 @@ class ParseDataType : public ParseTreeNode {
  public:
   ParseDataType(const int line_number,
                 const int column_number,
-                ParseString *name)
+                ParseString *type_name)
       : ParseTreeNode(line_number, column_number),
-        name_(name),
+        type_name_(type_name),
         nullable_(false) {}
 
   std::string getName() const override {
     return "DataType";
   }
 
+  const ParseString& type_name() const {
+    return *type_name_;
+  }
+
   const std::vector<std::unique_ptr<ParseDataTypeParameter>>& parameters() const {
     return parameters_;
   }
@@ -99,7 +103,7 @@ class ParseDataType : public ParseTreeNode {
       std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
 
  private:
-  const std::unique_ptr<ParseString> name_;
+  const std::unique_ptr<ParseString> type_name_;
   std::vector<std::unique_ptr<ParseDataTypeParameter>> parameters_;
   bool nullable_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 37a93fb..cf3ca6e 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -43,6 +43,7 @@
 #include "parser/ParseBasicExpressions.hpp"
 #include "parser/ParseBlockProperties.hpp"
 #include "parser/ParseCaseExpressions.hpp"
+#include "parser/ParseDataType.hpp"
 #include "parser/ParseExpression.hpp"
 #include "parser/ParseGeneratorTableReference.hpp"
 #include "parser/ParseGroupBy.hpp"
@@ -118,6 +119,7 @@
 #include "types/ArrayType.hpp"
 #include "types/GenericValue.hpp"
 #include "types/IntType.hpp"
+#include "types/LongType.hpp"
 #include "types/MetaType.hpp"
 #include "types/NullType.hpp"
 #include "types/Type.hpp"
@@ -639,14 +641,13 @@ L::LogicalPtr Resolver::resolveCreateTable(
           << "Column " << attribute_definition.name()->value()
           << " is specified more than once";
     }
-    LOG(FATAL) << "TODO(refactor-type): To implement";
-//    attributes.emplace_back(
-//        E::AttributeReference::Create(context_->nextExprId(),
-//                                      attribute_definition.name()->value(),
-//                                      attribute_definition.name()->value(),
-//                                      relation_name,
-//                                      attribute_definition.data_type().getType(),
-//                                      E::AttributeReferenceScope::kLocal));
+    attributes.emplace_back(
+        E::AttributeReference::Create(context_->nextExprId(),
+                                      attribute_definition.name()->value(),
+                                      attribute_definition.name()->value(),
+                                      relation_name,
+                                      resolveDataType(attribute_definition.data_type()),
+                                      E::AttributeReferenceScope::kLocal));
     attribute_name_set.insert(lower_attribute_name);
   }
 
@@ -1117,7 +1118,7 @@ L::LogicalPtr Resolver::resolveInsertTuple(
     }
     // Create a NULL value.
     resolved_column_values.push_back(E::ScalarLiteral::Create(
-        GenericValue(relation_attributes[aid]->getValueType())));
+        GenericValue::CreateNullValue(relation_attributes[aid]->getValueType())));
     ++aid;
   }
 
@@ -1193,6 +1194,72 @@ L::LogicalPtr Resolver::resolveUpdate(
                                 resolved_where_predicate);
 }
 
+const Type& Resolver::resolveDataType(const ParseDataType &parse_data_type) {
+  const std::string &type_name = ToLower(parse_data_type.type_name().value());
+  if (!TypeFactory::TypeNameIsValid(type_name)) {
+    THROW_SQL_ERROR_AT(&parse_data_type.type_name())
+        << "Unrecognized type name: " << type_name;
+  }
+
+  const TypeID type_id = TypeFactory::GetTypeIDForName(type_name);
+  const MemoryLayout memory_layout = TypeUtil::GetMemoryLayout(type_id);
+
+  const auto &parse_parameters = parse_data_type.parameters();
+  if (memory_layout == kCxxInlinePod) {
+    if (!parse_parameters.empty()) {
+      THROW_SQL_ERROR_AT(parse_parameters.front())
+          << "Invalid parameter to type " << type_name;
+    }
+    return TypeFactory::GetType(type_id, parse_data_type.nullable());
+  }
+
+  std::vector<GenericValue> values;
+  for (const auto &param : parse_parameters) {
+    if (param->getParameterType() == ParseDataTypeParameter::kLiteralValue) {
+      const ParseLiteralValue &literal_value =
+          static_cast<const ParseDataTypeParameterLiteralValue&>(*param).literal_value();
+      const Type *value_type = nullptr;
+      TypedValue value = literal_value.concretize(nullptr, &value_type);
+      DCHECK(value_type != nullptr);
+      values.emplace_back(GenericValue::CreateWithTypedValue(*value_type, value));
+    } else {
+      DCHECK(param->getParameterType() == ParseDataTypeParameter::kDataType);
+      const ParseDataType &element_type =
+          static_cast<const ParseDataTypeParameterDataType&>(*param).data_type();
+      values.emplace_back(
+          GenericValue::CreateWithLiteral(MetaType::InstanceNonNullable(),
+                                          &resolveDataType(element_type)));
+    }
+  }
+
+  if (memory_layout == kParInlinePod || memory_layout == kParOutOfLinePod) {
+    if (values.size() != 1) {
+      THROW_SQL_ERROR_AT(parse_parameters.front())
+          << "Invalid parameter to type " << type_name;
+    }
+    const GenericValue &value = values.front();
+    const Type &value_type = value.getType();
+
+    std::size_t length = 0;
+    if (value_type.getTypeID() == kInt) {
+      length = value.getLiteral<kInt>();
+    } else if (value_type.getTypeID() == kLong) {
+      length = value.getLiteral<kLong>();
+    } else {
+      THROW_SQL_ERROR_AT(parse_parameters.front())
+          << "Invalid parameter to type " << type_name;
+    }
+    return TypeFactory::GetType(type_id, length);
+  }
+
+  DCHECK(memory_layout == kCxxGeneric);
+  if (!TypeFactory::TypeParametersAreValid(type_id, values)) {
+    THROW_SQL_ERROR_AT(parse_parameters.front())
+        << "Invalid parameter to type " << type_name;
+  }
+  return TypeFactory::GetType(type_id, values);
+}
+
 L::LogicalPtr Resolver::resolveSelect(
     const ParseSelect &select_query,
     const std::string &select_name,
@@ -2452,7 +2519,8 @@ E::ScalarPtr Resolver::resolveExpression(
       const Type *concrete_type = nullptr;
       TypedValue concrete = parse_literal_scalar.literal_value()
           ->concretize(type_hint, &concrete_type);
-      return E::ScalarLiteral::Create(GenericValue(*concrete_type, concrete));
+      return E::ScalarLiteral::Create(
+          GenericValue::CreateWithTypedValue(*concrete_type, concrete));
     }
     case ParseExpression::kSearchedCaseExpression: {
       const ParseSearchedCaseExpression &parse_searched_case_expression =
@@ -2496,11 +2564,13 @@ E::ScalarPtr Resolver::resolveArray(
   const auto &parse_elements = parse_array.elements();
   if (parse_elements.empty()) {
     // TODO(jianqiao): Figure out how to handle empty array.
-    const GenericValue meta_null_type_value(
-        MetaType::InstanceNonNullable(), &NullType::InstanceNullable());
+    const GenericValue meta_null_type_value =
+        GenericValue::CreateWithLiteral(MetaType::InstanceNonNullable(),
+                                        &NullType::InstanceNullable());
     return E::ScalarLiteral::Create(
-        GenericValue(ArrayType::InstanceNonNullable({meta_null_type_value}),
-                     ArrayLiteral()));
+        GenericValue::CreateWithLiteral(
+            ArrayType::InstanceNonNullable({meta_null_type_value}),
+            ArrayLiteral()));
   } else {
     // Currently we only support homogeneous array with literal values.
     std::vector<E::ScalarLiteralPtr> literals;
@@ -2530,8 +2600,9 @@ E::ScalarPtr Resolver::resolveArray(
     }
     DCHECK(element_type != nullptr);
 
-    const GenericValue meta_element_type_value(
-        MetaType::InstanceNonNullable(), element_type);
+    const GenericValue meta_element_type_value =
+        GenericValue::CreateWithLiteral(MetaType::InstanceNonNullable(),
+                                        element_type);
     const Type &array_type =
         ArrayType::InstanceNonNullable({meta_element_type_value});
 
@@ -2541,9 +2612,8 @@ E::ScalarPtr Resolver::resolveArray(
       array_literal->emplace_back(
           element_type->cloneValue(literal->value().getValue()));
     }
-    return E::ScalarLiteral::Create(GenericValue(array_type,
-                                                 array_literal.release(),
-                                                 true /* take_ownership */));
+    return E::ScalarLiteral::Create(
+        GenericValue::CreateWithOwnedData(array_type, array_literal.release()));
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/query_optimizer/resolver/Resolver.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.hpp b/query_optimizer/resolver/Resolver.hpp
index c44d8ef..1844493 100644
--- a/query_optimizer/resolver/Resolver.hpp
+++ b/query_optimizer/resolver/Resolver.hpp
@@ -42,6 +42,7 @@ class CatalogDatabase;
 class CatalogRelation;
 class Comparison;
 class ParseArray;
+class ParseDataType;
 class ParseExpression;
 class ParseFunctionCall;
 class ParseGeneratorTableReference;
@@ -581,6 +582,8 @@ class Resolver {
    */
   const CatalogRelation *resolveRelationName(const ParseString *relation_name);
 
+  const Type& resolveDataType(const ParseDataType &parse_data_type);
+
   /**
    * @brief Determines whether \p op can apply to \p left_operand and \p
    *        right_operand.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
index 30cc4a5..765a1a0 100644
--- a/types/ArrayType.cpp
+++ b/types/ArrayType.cpp
@@ -39,6 +39,13 @@ std::string ArrayType::getName() const {
   return name;
 }
 
+bool ArrayType::TypeParametersAreValid(const std::vector<GenericValue> &parameters) {
+  if (parameters.size() != 1u) {
+    return false;
+  }
+  return parameters.front().getType().getTypeID() == kMetaType;
+}
+
 bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs,
                                  const UntypedLiteral *rhs,
                                  const Type &rhs_type) const {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
index f7e2212..5eaff92 100644
--- a/types/ArrayType.hpp
+++ b/types/ArrayType.hpp
@@ -63,19 +63,17 @@ class ArrayType : public TypeSynthesizer<kArray> {
     return false;
   }
 
+  static bool TypeParametersAreValid(const std::vector<GenericValue> &parameters);
+
  private:
   ArrayType(const bool nullable, const std::vector<GenericValue> &parameters)
       : TypeSynthesizer<kArray>(nullable, 0, 0x1000, parameters),
         element_type_(ExtractType(parameters)) {
-    // TODO(refactor-type): Possibly infinite maximum size.
-    // TODO(refactor-type): Validate parameters.
   }
 
   static const Type& ExtractType(const std::vector<GenericValue> &parameters) {
-    DCHECK_EQ(1u, parameters.size());
-    const GenericValue &value = parameters.front();
-    DCHECK(value.getType().getTypeID() == kMetaType);
-    return **static_cast<const MetaTypeLiteral*>(value.getValue());
+    DCHECK(TypeParametersAreValid(parameters));
+    return **static_cast<const MetaTypeLiteral*>(parameters.front().getValue());
   }
 
   const Type &element_type_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
index 62dd9a3..3e8045b 100644
--- a/types/GenericValue.hpp
+++ b/types/GenericValue.hpp
@@ -43,20 +43,30 @@ namespace quickstep {
 
 class GenericValue {
  public:
-  GenericValue(const Type &type)
-      : type_(type), value_(nullptr), owns_(true) {}
+  static GenericValue CreateNullValue(const Type &type) {
+    return GenericValue(type, nullptr, true);
+  }
 
-  GenericValue(const Type &type,
-               const UntypedLiteral *value,
-               const bool take_ownership)
-      : type_(type), value_(value), owns_(take_ownership) {}
+  static GenericValue CreateWithOwnedData(const Type &type,
+                                          const UntypedLiteral *value) {
+    return GenericValue(type, value, true);
+  }
 
-  GenericValue(const Type &type, const TypedValue &value)
-      : type_(type), value_(type.unmarshallTypedValue(value)), owns_(true) {}
+  static GenericValue CreateReference(const Type &type,
+                                      const UntypedLiteral *value) {
+    return GenericValue(type, value, false);
+  }
+
+  static GenericValue CreateWithTypedValue(const Type &type,
+                                           const TypedValue &value) {
+    return GenericValue(type, type.unmarshallTypedValue(value), true);
+  }
 
   template <typename TypeClass>
-  GenericValue(const TypeClass &type, const typename TypeClass::cpptype &value)
-      : type_(type), value_(type.cloneValue(&value)), owns_(true) {}
+  static GenericValue CreateWithLiteral(const TypeClass &type,
+                                        const typename TypeClass::cpptype &value) {
+    return GenericValue(type, type.cloneValue(&value), true);
+  }
 
   GenericValue(const GenericValue &other)
       : type_(other.type_),
@@ -153,6 +163,11 @@ class GenericValue {
   }
 
  private:
+  GenericValue(const Type &type,
+               const UntypedLiteral *value,
+               const bool take_ownership)
+      : type_(type), value_(value), owns_(take_ownership) {}
+
   const Type &type_;
   const UntypedLiteral *value_;
   bool owns_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/types/TypeFactory-decl.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory-decl.hpp b/types/TypeFactory-decl.hpp
index 6edc05b..f67208e 100644
--- a/types/TypeFactory-decl.hpp
+++ b/types/TypeFactory-decl.hpp
@@ -21,6 +21,9 @@
 #define QUICKSTEP_TYPES_TYPE_FACTORY_DECL_HPP_
 
 #include <cstddef>
+#include <string>
+#include <unordered_map>
+#include <vector>
 
 #include "types/GenericValue.hpp"
 #include "types/TypeID.hpp"
@@ -42,6 +45,10 @@ namespace serialization { class Type; }
  **/
 class TypeFactory {
  public:
+  static bool TypeNameIsValid(const std::string &type_name);
+
+  static TypeID GetTypeIDForName(const std::string &type_name);
+
   /**
    * @brief Determine if a length parameter is required when getting a Type of
    *        the specified TypeID.
@@ -51,6 +58,9 @@ class TypeFactory {
    **/
   static bool TypeRequiresLengthParameter(const TypeID id);
 
+  static bool TypeParametersAreValid(const TypeID id,
+                                     const std::vector<GenericValue> &parameters);
+
   /**
    * @brief Factory method to get a Type by its TypeID.
    * @note This version is for Types without a length parameter (currently
@@ -131,6 +141,8 @@ class TypeFactory {
   // instantiated.
   TypeFactory();
 
+  static const std::unordered_map<std::string, TypeID>& GetTypeNameMap();
+
   DISALLOW_COPY_AND_ASSIGN(TypeFactory);
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index 45202f1..9029408 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -21,6 +21,7 @@
 
 #include <cstddef>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 #include "types/GenericValue.hpp"
@@ -30,15 +31,41 @@
 #include "types/TypeSynthesizer.hpp"
 #include "types/TypeUtil.hpp"
 #include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
 
 #include "glog/logging.h"
 
 namespace quickstep {
 
+bool TypeFactory::TypeNameIsValid(const std::string &type_name) {
+  const auto &type_name_map = GetTypeNameMap();
+  return type_name_map.find(type_name) != type_name_map.end();
+}
+
+TypeID TypeFactory::GetTypeIDForName(const std::string &type_name) {
+  DCHECK(TypeNameIsValid(type_name));
+  return GetTypeNameMap().at(type_name);
+}
+
 bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
   return TypeUtil::IsParameterizedPod(id);
 }
 
+bool TypeFactory::TypeParametersAreValid(
+    const TypeID id, const std::vector<GenericValue> &parameters) {
+  if (TypeUtil::GetMemoryLayout(id) != kCxxGeneric) {
+    return false;
+  }
+
+  return InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxGeneric>>(
+      id,
+      [&](auto id) -> bool {  // NOLINT(build/c++11)
+    using TypeClass = typename TypeIDTrait<decltype(id)::value>::TypeClass;
+    return TypeClass::TypeParametersAreValid(parameters);
+  });
+}
+
+
 const Type& TypeFactory::GetType(const TypeID id,
                                  const bool nullable) {
   DCHECK(TypeUtil::GetMemoryLayout(id) == kCxxInlinePod)
@@ -124,12 +151,10 @@ GenericValue TypeFactory::ReconstructValueFromProto(
     const serialization::GenericValue &proto) {
   const Type &type = ReconstructFromProto(proto.type());
   if (proto.has_data()) {
-    return GenericValue(type,
-                        type.unmarshallValue(proto.data().c_str(),
-                                             proto.data().size()),
-                        true /* take_ownership */);
+    return GenericValue::CreateWithOwnedData(
+        type, type.unmarshallValue(proto.data().c_str(), proto.data().size()));
   } else {
-    return GenericValue(type);
+    return GenericValue::CreateNullValue(type);
   }
 }
 
@@ -168,4 +193,14 @@ const Type* TypeFactory::GetUnifyingType(const Type &first, const Type &second)
   return unifier;
 }
 
+const std::unordered_map<std::string, TypeID>& TypeFactory::GetTypeNameMap() {
+  static std::unordered_map<std::string, TypeID> type_name_map;
+  if (type_name_map.empty()) {
+    for (std::size_t i = 0; i < static_cast<std::size_t>(kNumTypeIDs); ++i) {
+      type_name_map.emplace(ToLower(kTypeNames[i]), static_cast<TypeID>(i));
+    }
+  }
+  return type_name_map;
+}
+
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/82697640/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index f0761d1..0b5842f 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -365,6 +365,12 @@ class TypeSynthesizePolicy<
 //    LOG(FATAL) << "Not implemented";
 //  }
 
+  template <typename T = TypeClass>
+  static bool TypeParametersAreValid(const std::vector<GenericValue> &parameters,
+                                     decltype(new T(true)) * = 0) {
+    return parameters.empty();
+  }
+
  protected:
   TypeSynthesizePolicy(const bool nullable,
                        const std::size_t minimum_byte_length,


[38/38] incubator-quickstep git commit: Type as first class citizen

Posted by ji...@apache.org.
Type as first class citizen


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/843a1723
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/843a1723
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/843a1723

Branch: refs/heads/refactor-type
Commit: 843a17231b629e5d4ae841337b9ad08c6a96e12c
Parents: 93c6b7a
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Wed Oct 4 00:26:36 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 parser/CMakeLists.txt                 |   10 +
 parser/ParseAttributeDefinition.cpp   |    8 +-
 parser/ParseAttributeDefinition.hpp   |   48 +-
 parser/ParseBasicExpressions.cpp      |   17 +
 parser/ParseBasicExpressions.hpp      |   48 +
 parser/ParseDataType-decl.hpp         |   24 +
 parser/ParseDataType.cpp              |   71 +
 parser/ParseDataType.hpp              |  183 ++
 parser/ParseExpression.hpp            |    1 +
 parser/SqlLexer.lpp                   |   18 +-
 parser/SqlParser.ypp                  |  204 +-
 parser/preprocessed/SqlLexer_gen.cpp  | 1612 ++++++------
 parser/preprocessed/SqlLexer_gen.hpp  |    2 +-
 parser/preprocessed/SqlParser_gen.cpp | 3952 +++++++++++++---------------
 parser/preprocessed/SqlParser_gen.hpp |  212 +-
 query_optimizer/resolver/Resolver.cpp |   15 +-
 types/CMakeLists.txt                  |   39 +-
 types/MetaType-decl.hpp               |   76 +
 types/MetaType.cpp                    |   19 +-
 types/MetaType.hpp                    |    2 +-
 types/MetaTypeLite.cpp                |   47 -
 types/MetaTypeLite.hpp                |   76 -
 types/TypeFactory-decl.hpp            |  141 +
 types/TypeFactory.cpp                 |  171 ++
 types/TypeFactory.hpp                 |    3 +-
 types/TypeFactoryLite.cpp             |  170 --
 types/TypeFactoryLite.hpp             |  141 -
 types/TypeIDSelectors.hpp             |   31 -
 types/TypeUtil.hpp                    |    2 +-
 29 files changed, 3492 insertions(+), 3851 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/parser/CMakeLists.txt b/parser/CMakeLists.txt
index fb7a3cd..8d6ce91 100644
--- a/parser/CMakeLists.txt
+++ b/parser/CMakeLists.txt
@@ -89,6 +89,7 @@ add_library(quickstep_parser_ParseAttributeDefinition ParseAttributeDefinition.c
 add_library(quickstep_parser_ParseBasicExpressions ParseBasicExpressions.cpp ParseBasicExpressions.hpp)
 add_library(quickstep_parser_ParseBlockProperties ParseBlockProperties.cpp ParseBlockProperties.hpp)
 add_library(quickstep_parser_ParseCaseExpressions ParseCaseExpressions.cpp ParseCaseExpressions.hpp)
+add_library(quickstep_parser_ParseDataType ParseDataType.cpp ParseDataType.hpp)
 add_library(quickstep_parser_ParseExpression ../empty_src.cpp ParseExpression.hpp)
 add_library(quickstep_parser_ParseGeneratorTableReference ParseGeneratorTableReference.cpp ParseGeneratorTableReference.hpp)
 add_library(quickstep_parser_ParseGroupBy ParseGroupBy.cpp ParseGroupBy.hpp)
@@ -128,12 +129,14 @@ target_link_libraries(quickstep_parser_ParseAssignment
                       quickstep_parser_ParseTreeNode
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_parser_ParseAttributeDefinition
+                      quickstep_parser_ParseDataType
                       quickstep_parser_ParseString
                       quickstep_parser_ParseTreeNode
                       quickstep_types_Type
                       quickstep_utility_Macros
                       quickstep_utility_PtrList)
 target_link_libraries(quickstep_parser_ParseBasicExpressions
+                      quickstep_parser_ParseDataType
                       quickstep_parser_ParseExpression
                       quickstep_parser_ParseLiteralValue
                       quickstep_parser_ParseString
@@ -157,6 +160,11 @@ target_link_libraries(quickstep_parser_ParseCaseExpressions
                       quickstep_parser_ParseTreeNode
                       quickstep_utility_Macros
                       quickstep_utility_PtrVector)
+target_link_libraries(quickstep_parser_ParseDataType
+                      quickstep_parser_ParseLiteralValue
+                      quickstep_parser_ParseString
+                      quickstep_parser_ParseTreeNode
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_parser_ParseExpression
                       quickstep_parser_ParseTreeNode
                       quickstep_utility_Macros)
@@ -336,6 +344,7 @@ target_link_libraries(quickstep_parser_SqlParser
                       quickstep_parser_ParseBasicExpressions
                       quickstep_parser_ParseBlockProperties
                       quickstep_parser_ParseCaseExpressions
+                      quickstep_parser_ParseDataType
                       quickstep_parser_ParseExpression
                       quickstep_parser_ParseGeneratorTableReference
                       quickstep_parser_ParseGroupBy
@@ -409,6 +418,7 @@ target_link_libraries(quickstep_parser
                       quickstep_parser_ParseBasicExpressions
                       quickstep_parser_ParseBlockProperties
                       quickstep_parser_ParseCaseExpressions
+                      quickstep_parser_ParseDataType
                       quickstep_parser_ParseExpression
                       quickstep_parser_ParseGeneratorTableReference
                       quickstep_parser_ParseGroupBy

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/ParseAttributeDefinition.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseAttributeDefinition.cpp b/parser/ParseAttributeDefinition.cpp
index ec6508b..0612d9e 100644
--- a/parser/ParseAttributeDefinition.cpp
+++ b/parser/ParseAttributeDefinition.cpp
@@ -54,12 +54,12 @@ void ParseAttributeDefinition::getFieldStringItems(
     std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
   inline_field_names->push_back("name");
   inline_field_values->push_back(name_->value());
-  inline_field_names->push_back("type");
-  inline_field_values->push_back(data_type_->getType().getName());
+  non_container_child_field_names->push_back("type");
+  non_container_child_fields->push_back(data_type_.get());
 }
 
 void ParseColumnConstraintNull::applyTo(ParseAttributeDefinition *target) const {
-  target->data_type_->type_ = &(target->data_type_->type_->getNullableVersion());
+  target->setNullable(true);
 }
 
 void ParseColumnConstraintNull::getFieldStringItems(
@@ -74,7 +74,7 @@ void ParseColumnConstraintNull::getFieldStringItems(
 }
 
 void ParseColumnConstraintNotNull::applyTo(ParseAttributeDefinition *target) const {
-  target->data_type_->type_ = &(target->data_type_->type_->getNonNullableVersion());
+  target->setNullable(false);
 }
 
 void ParseColumnConstraintNotNull::getFieldStringItems(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/ParseAttributeDefinition.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseAttributeDefinition.hpp b/parser/ParseAttributeDefinition.hpp
index 5c20d13..0e79ac4 100644
--- a/parser/ParseAttributeDefinition.hpp
+++ b/parser/ParseAttributeDefinition.hpp
@@ -24,6 +24,7 @@
 #include <string>
 #include <vector>
 
+#include "parser/ParseDataType.hpp"
 #include "parser/ParseString.hpp"
 #include "parser/ParseTreeNode.hpp"
 #include "utility/Macros.hpp"
@@ -31,7 +32,6 @@
 namespace quickstep {
 
 class ParseColumnConstraint;
-class Type;
 
 template <class T> class PtrList;
 
@@ -40,40 +40,6 @@ template <class T> class PtrList;
  */
 
 /**
- * @brief Parsed representation of a data type.
- **/
-class ParseDataType {
- public:
-  /**
-   * @brief Constructor.
-   *
-   * @param type The Type of the data.
-   **/
-  explicit ParseDataType(const Type &type)
-      : type_(&type) {
-  }
-
-  /**
-   * @brief Get the type.
-   *
-   * @return The Type.
-   **/
-  const Type& getType() const {
-    return *type_;
-  }
-
- private:
-  // Use a pointer instead of a reference so that it may be modified by column
-  // constraints.
-  const Type *type_;
-
-  friend class ParseColumnConstraintNull;
-  friend class ParseColumnConstraintNotNull;
-
-  DISALLOW_COPY_AND_ASSIGN(ParseDataType);
-};
-
-/**
  * @brief Parsed representation of an attribute definition
  **/
 class ParseAttributeDefinition : public ParseTreeNode {
@@ -122,6 +88,14 @@ class ParseAttributeDefinition : public ParseTreeNode {
     return *data_type_;
   }
 
+  const bool nullable() const {
+    return nullable_;
+  }
+
+  void setNullable(const bool nullable) {
+    nullable_ = nullable;
+  }
+
  protected:
   void getFieldStringItems(
       std::vector<std::string> *inline_field_names,
@@ -134,9 +108,7 @@ class ParseAttributeDefinition : public ParseTreeNode {
  private:
   std::unique_ptr<ParseString> name_;
   std::unique_ptr<ParseDataType> data_type_;
-
-  friend class ParseColumnConstraintNull;
-  friend class ParseColumnConstraintNotNull;
+  bool nullable_;
 
   DISALLOW_COPY_AND_ASSIGN(ParseAttributeDefinition);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/ParseBasicExpressions.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseBasicExpressions.cpp b/parser/ParseBasicExpressions.cpp
index fd9094c..6425002 100644
--- a/parser/ParseBasicExpressions.cpp
+++ b/parser/ParseBasicExpressions.cpp
@@ -127,6 +127,23 @@ void ParseFunctionCall::getFieldStringItems(
   }
 }
 
+std::string ParseTypeCast::generateName() const {
+  return operand_->generateName();
+}
+
+void ParseTypeCast::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  non_container_child_field_names->emplace_back("operand");
+  non_container_child_fields->emplace_back(operand_.get());
+  non_container_child_field_names->emplace_back("target_type");
+  non_container_child_fields->emplace_back(target_type_.get());
+}
+
 std::string ParseArray::generateName() const {
   string name("{");
   if (!elements_.empty()) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/ParseBasicExpressions.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseBasicExpressions.hpp b/parser/ParseBasicExpressions.hpp
index af2393f..56295e7 100644
--- a/parser/ParseBasicExpressions.hpp
+++ b/parser/ParseBasicExpressions.hpp
@@ -26,6 +26,7 @@
 #include <string>
 #include <vector>
 
+#include "parser/ParseDataType.hpp"
 #include "parser/ParseExpression.hpp"
 #include "parser/ParseLiteralValue.hpp"
 #include "parser/ParseString.hpp"
@@ -345,6 +346,53 @@ class ParseFunctionCall : public ParseExpression {
 };
 
 
+class ParseTypeCast : public ParseExpression {
+ public:
+  ParseTypeCast(const int line_number,
+                const int column_number,
+                ParseExpression *operand,
+                ParseDataType *target_type)
+      : ParseExpression(line_number, column_number),
+        operand_(operand),
+        target_type_(target_type) {}
+
+  ~ParseTypeCast() override {}
+
+  ExpressionType getExpressionType() const override {
+    return kTypeCast;
+  }
+
+  std::string getName() const override {
+    return "TypeCast";
+  }
+
+  std::string generateName() const override;
+
+  const ParseExpression& operand() const {
+    return *operand_;
+  }
+
+  const ParseDataType& target_type() const {
+    return *target_type_;
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  std::unique_ptr<ParseExpression> operand_;
+  std::unique_ptr<ParseDataType> target_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseTypeCast);
+};
+
+
 class ParseArray : public ParseExpression {
  public:
   ParseArray(const int line_number, const int column_number)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/ParseDataType-decl.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseDataType-decl.hpp b/parser/ParseDataType-decl.hpp
new file mode 100644
index 0000000..f85ab55
--- /dev/null
+++ b/parser/ParseDataType-decl.hpp
@@ -0,0 +1,24 @@
+/**
+ * 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_PARSER_PARSE_DATA_TYPE_DECL_HPP_
+#define QUICKSTEP_PARSER_PARSE_DATA_TYPE_DECL_HPP_
+
+
+#endif  // QUICKSTEP_PARSER_PARSE_DATA_TYPE_DECL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/ParseDataType.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseDataType.cpp b/parser/ParseDataType.cpp
new file mode 100644
index 0000000..b960961
--- /dev/null
+++ b/parser/ParseDataType.cpp
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "parser/ParseDataType.hpp"
+
+#include <string>
+#include <vector>
+
+#include "parser/ParseTreeNode.hpp"
+
+namespace quickstep {
+
+void ParseDataType::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  inline_field_names->emplace_back("name");
+  inline_field_values->emplace_back(name_->value());
+
+  inline_field_names->emplace_back("nullable");
+
+
+  container_child_field_names->emplace_back("parameters");
+  container_child_fields->emplace_back();
+  for (const auto &parameter : parameters_) {
+    container_child_fields->back().emplace_back(parameter.get());
+  }
+}
+
+void ParseDataTypeParameterLiteralValue::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  non_container_child_field_names->emplace_back("literal_value");
+  non_container_child_fields->emplace_back(literal_value_.get());
+}
+
+void ParseDataTypeParameterDataType::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  non_container_child_field_names->emplace_back("data_type");
+  non_container_child_fields->emplace_back(data_type_.get());
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/ParseDataType.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseDataType.hpp b/parser/ParseDataType.hpp
new file mode 100644
index 0000000..96b7b96
--- /dev/null
+++ b/parser/ParseDataType.hpp
@@ -0,0 +1,183 @@
+/**
+ * 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_PARSER_PARSE_DATA_TYPE_HPP_
+#define QUICKSTEP_PARSER_PARSE_DATA_TYPE_HPP_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "parser/ParseLiteralValue.hpp"
+#include "parser/ParseString.hpp"
+#include "parser/ParseTreeNode.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class Type;
+
+/** \addtogroup Parser
+ *  @{
+ */
+
+class ParseDataTypeParameter : public ParseTreeNode {
+ public:
+  enum class ParameterType {
+    kDataType,
+    kLiteralValue
+  };
+
+  virtual ParameterType getParameterType() const = 0;
+
+ protected:
+  ParseDataTypeParameter(const int line_number,
+                         const int column_number)
+      : ParseTreeNode(line_number, column_number) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ParseDataTypeParameter);
+};
+
+/**
+ * @brief Parsed representation of a data type.
+ **/
+class ParseDataType : public ParseTreeNode {
+ public:
+  ParseDataType(const int line_number,
+                const int column_number,
+                ParseString *name)
+      : ParseTreeNode(line_number, column_number),
+        name_(name),
+        nullable_(false) {}
+
+  std::string getName() const override {
+    return "DataType";
+  }
+
+  const std::vector<std::unique_ptr<ParseDataTypeParameter>>& parameters() const {
+    return parameters_;
+  }
+
+  bool nullable() const {
+    return nullable_;
+  }
+
+  void addParameter(ParseDataTypeParameter *parameter) {
+    parameters_.emplace_back(std::unique_ptr<ParseDataTypeParameter>(parameter));
+  }
+
+  void setNullable(const bool nullable) {
+    nullable_ = nullable;
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  const std::unique_ptr<ParseString> name_;
+  std::vector<std::unique_ptr<ParseDataTypeParameter>> parameters_;
+  bool nullable_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseDataType);
+};
+
+class ParseDataTypeParameterLiteralValue : public ParseDataTypeParameter {
+ public:
+  ParseDataTypeParameterLiteralValue(const int line_number,
+                                     const int column_number,
+                                     ParseLiteralValue *literal_value)
+      : ParseDataTypeParameter(line_number, column_number),
+        literal_value_(literal_value) {}
+
+  std::string getName() const override {
+    return "DataTypeParameterLiteralValue";
+  }
+
+  ParameterType getParameterType() const override {
+    return ParameterType::kLiteralValue;
+  }
+
+  const ParseLiteralValue& literal_value() const {
+    return *literal_value_;
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  std::unique_ptr<ParseLiteralValue> literal_value_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseDataTypeParameterLiteralValue);
+};
+
+class ParseDataTypeParameterDataType : public ParseDataTypeParameter {
+ public:
+  ParseDataTypeParameterDataType(const int line_number,
+                                 const int column_number,
+                                 ParseDataType *data_type)
+      : ParseDataTypeParameter(line_number, column_number),
+        data_type_(data_type) {}
+
+  std::string getName() const override {
+    return "DataTypeParameterDataType";
+  }
+
+  ParameterType getParameterType() const override {
+    return ParameterType::kDataType;
+  }
+
+  const ParseDataType& data_type() const {
+    return *data_type_;
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  std::unique_ptr<ParseDataType> data_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseDataTypeParameterDataType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_PARSER_PARSE_DATA_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/ParseExpression.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseExpression.hpp b/parser/ParseExpression.hpp
index f9a33a2..01da16a 100644
--- a/parser/ParseExpression.hpp
+++ b/parser/ParseExpression.hpp
@@ -45,6 +45,7 @@ class ParseExpression : public ParseTreeNode {
     kSearchedCaseExpression,
     kSimpleCaseExpression,
     kSubqueryExpression,
+    kTypeCast,
   };
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/SqlLexer.lpp
----------------------------------------------------------------------
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index b45d8ab..4d4d171 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -90,6 +90,7 @@ class ParseSubqueryExpression;
 class ParseSubqueryTableReference;
 class ParseTableReference;
 class ParseTableReferenceSignature;
+class ParseTypeCast;
 class ParseWindow;
 class Type;
 class UnaryOperation;
@@ -178,8 +179,6 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "asc"              return TOKEN_ASC;
   "ascending"        return TOKEN_ASC;
   "between"          return TOKEN_BETWEEN;
-  "bigint"           return TOKEN_BIGINT;
-  "bit"              return TOKEN_BIT;
   "bitweaving"       return TOKEN_BITWEAVING;
   "blockproperties"  return TOKEN_BLOCKPROPERTIES;
   "blocksample"      return TOKEN_BLOCKSAMPLE;
@@ -188,24 +187,18 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "cast"             return TOKEN_CAST;
   "csbtree"          return TOKEN_CSB_TREE;
   "by"               return TOKEN_BY;
-  "char"             return TOKEN_CHARACTER;
-  "character"        return TOKEN_CHARACTER;
   "check"            return TOKEN_CHECK;
   "column"           return TOKEN_COLUMN;
   "constraint"       return TOKEN_CONSTRAINT;
   "copy"             return TOKEN_COPY;
   "create"           return TOKEN_CREATE;
   "current"          return TOKEN_CURRENT;
-  "date"             return TOKEN_DATE;
-  "datetime"         return TOKEN_DATETIME;
   "day"              return TOKEN_DAY;
-  "decimal"          return TOKEN_DECIMAL;
   "default"          return TOKEN_DEFAULT;
   "delete"           return TOKEN_DELETE;
   "desc"             return TOKEN_DESC;
   "descending"       return TOKEN_DESC;
   "distinct"         return TOKEN_DISTINCT;
-  "double"           return TOKEN_DOUBLE;
   "drop"             return TOKEN_DROP;
   "else"             return TOKEN_ELSE;
   "end"              return TOKEN_END;
@@ -213,7 +206,6 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "extract"          return TOKEN_EXTRACT;
   "false"            return TOKEN_FALSE;
   "first"            return TOKEN_FIRST;
-  "float"            return TOKEN_FLOAT;
   "following"        return TOKEN_FOLLOWING;
   "for"              return TOKEN_FOR;
   "foreign"          return TOKEN_FOREIGN;
@@ -227,8 +219,6 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "index"            return TOKEN_INDEX;
   "inner"            return TOKEN_INNER;
   "insert"           return TOKEN_INSERT;
-  "int"              return TOKEN_INTEGER;
-  "integer"          return TOKEN_INTEGER;
   "intersect"        return TOKEN_INTERSECT;
   "interval"         return TOKEN_INTERVAL;
   "into"             return TOKEN_INTO;
@@ -239,7 +229,6 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "left"             return TOKEN_LEFT;
   "like"             return TOKEN_LIKE;
   "limit"            return TOKEN_LIMIT;
-  "long"             return TOKEN_LONG;
   "minute"           return TOKEN_MINUTE;
   "month"            return TOKEN_MONTH;
   "not"              return TOKEN_NOT;
@@ -270,14 +259,11 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "select"           return TOKEN_SELECT;
   "set"              return TOKEN_SET;
   "sma"              return TOKEN_SMA;
-  "smallint"         return TOKEN_SMALLINT;
   "stderr"           return TOKEN_STDERR;
   "stdout"           return TOKEN_STDOUT;
   "substring"        return TOKEN_SUBSTRING;
   "table"            return TOKEN_TABLE;
   "then"             return TOKEN_THEN;
-  "time"             return TOKEN_TIME;
-  "timestamp"        return TOKEN_TIMESTAMP;
   "to"               return TOKEN_TO;
   "true"             return TOKEN_TRUE;
   "tuplesample"      return TOKEN_TUPLESAMPLE;
@@ -287,13 +273,11 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "update"           return TOKEN_UPDATE;
   "using"            return TOKEN_USING;
   "values"           return TOKEN_VALUES;
-  "varchar"          return TOKEN_VARCHAR;
   "when"             return TOKEN_WHEN;
   "where"            return TOKEN_WHERE;
   "window"           return TOKEN_WINDOW;
   "with"             return TOKEN_WITH;
   "year"             return TOKEN_YEAR;
-  "yearmonth"        return TOKEN_YEARMONTH;
 
   "="                return TOKEN_EQ;
   "!="               return TOKEN_NEQ;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/SqlParser.ypp
----------------------------------------------------------------------
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index 01be345..16e30bc 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -30,7 +30,7 @@
  * occurs, Bison resolves it by preferring to shift rather than reduce, which
  * is the correct, expected behavior for both cases in this parser.
  **/
-%expect 2
+%expect 1
 
 %{
 
@@ -72,6 +72,7 @@ typedef struct YYLTYPE {
 #include "parser/ParseBasicExpressions.hpp"
 #include "parser/ParseBlockProperties.hpp"
 #include "parser/ParseCaseExpressions.hpp"
+#include "parser/ParseDataType.hpp"
 #include "parser/ParseExpression.hpp"
 #include "parser/ParseGeneratorTableReference.hpp"
 #include "parser/ParseGroupBy.hpp"
@@ -247,7 +248,6 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_AND;
 %token TOKEN_AS;
 %token TOKEN_ASC;
-%token TOKEN_BIGINT;
 %token TOKEN_BIT;
 %token TOKEN_BITWEAVING;
 %token TOKEN_BLOCKPROPERTIES;
@@ -257,22 +257,17 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_BY;
 %token TOKEN_CASE;
 %token TOKEN_CAST;
-%token TOKEN_CHARACTER;
 %token TOKEN_CHECK;
 %token TOKEN_COLUMN;
 %token TOKEN_CONSTRAINT;
 %token TOKEN_COPY;
 %token TOKEN_CREATE;
 %token TOKEN_CURRENT;
-%token TOKEN_DATE;
-%token TOKEN_DATETIME;
 %token TOKEN_DAY;
-%token TOKEN_DECIMAL;
 %token TOKEN_DEFAULT;
 %token TOKEN_DELETE;
 %token TOKEN_DESC;
 %token TOKEN_DISTINCT;
-%token TOKEN_DOUBLE;
 %token TOKEN_DOUBLECOLON;
 %token TOKEN_DROP;
 %token TOKEN_ELSE;
@@ -281,7 +276,6 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_EXTRACT;
 %token TOKEN_FALSE;
 %token TOKEN_FIRST;
-%token TOKEN_FLOAT;
 %token TOKEN_FOLLOWING;
 %token TOKEN_FOR;
 %token TOKEN_FOREIGN;
@@ -295,7 +289,6 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_INDEX;
 %token TOKEN_INNER;
 %token TOKEN_INSERT;
-%token TOKEN_INTEGER;
 %token TOKEN_INTERSECT;
 %token TOKEN_INTERVAL;
 %token TOKEN_INTO;
@@ -305,7 +298,6 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_LBRACE;
 %token TOKEN_LEFT;
 %token TOKEN_LIMIT;
-%token TOKEN_LONG;
 %token TOKEN_MINUTE;
 %token TOKEN_MONTH;
 %token TOKEN_NOT;
@@ -337,14 +329,11 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_SELECT;
 %token TOKEN_SET;
 %token TOKEN_SMA;
-%token TOKEN_SMALLINT;
 %token TOKEN_STDERR;
 %token TOKEN_STDOUT;
 %token TOKEN_SUBSTRING;
 %token TOKEN_TABLE;
 %token TOKEN_THEN;
-%token TOKEN_TIME;
-%token TOKEN_TIMESTAMP;
 %token TOKEN_TO;
 %token TOKEN_TRUE;
 %token TOKEN_TUPLESAMPLE;
@@ -354,13 +343,11 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_UPDATE;
 %token TOKEN_USING;
 %token TOKEN_VALUES;
-%token TOKEN_VARCHAR;
 %token TOKEN_WHEN;
 %token TOKEN_WHERE;
 %token TOKEN_WINDOW;
 %token TOKEN_WITH;
 %token TOKEN_YEAR;
-%token TOKEN_YEARMONTH;
 %token TOKEN_EOF;
 %token TOKEN_LEX_ERROR;
 
@@ -375,6 +362,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
   boolean_value
   frame_mode
   opt_all_distinct
+  opt_nullable
 
 %type <literal_value_>
   literal_value
@@ -458,6 +446,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 
 %type <data_type_>
   data_type
+  data_type_parameter_commalist
 
 %type <attribute_definition_>
   column_def
@@ -768,102 +757,46 @@ column_def_commalist:
   };
 
 data_type:
-  TOKEN_BIT {
-    $$ = nullptr;
-    NotSupported(&@1, yyscanner, "BIT data type");
-    YYERROR;
-  }
-  | TOKEN_DATE {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDate));
-  }
-  | TOKEN_DATETIME {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime));
-  }
-  | TOKEN_TIME {
-    $$ = nullptr;
-    NotSupported(&@1, yyscanner, "TIME data type");
-    YYERROR;
-  }
-  | TOKEN_TIMESTAMP {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetime));
-  }
-  | TOKEN_DECIMAL {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
-  }
-  | TOKEN_REAL {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
-  }
-  | TOKEN_DOUBLE {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDouble));
-  }
-  | TOKEN_FLOAT {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kFloat));
-  }
-  | TOKEN_SMALLINT {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kInt));
-  }
-  | TOKEN_INTEGER {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kInt));
-  }
-  | TOKEN_BIGINT {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kLong));
+  any_name {
+    $$ = new quickstep::ParseDataType(@1.first_line, @1.first_column, $1);
   }
-  | TOKEN_LONG {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kLong));
+  | data_type_parameter_commalist ')' {
+    $$ = $1;
+  };
+
+data_type_parameter_commalist:
+  any_name '(' data_type opt_nullable {
+    $$ = new quickstep::ParseDataType(@1.first_line, @1.first_column, $1);
+    $3->setNullable($4);
+    $$->addParameter(
+        new quickstep::ParseDataTypeParameterDataType($3->line_number(), $3->column_number(), $3));
   }
-  | TOKEN_INTERVAL {
-    /**
-     * NOTE(chasseur): This pattern exhibits a shift/reduce conflict with the
-     * TOKEN_INTERVAL case in 'literal_value'. Bison prefers to shift rather
-     * than reduce, so the case in 'literal_value' has precedence over this.
-     **/
-    $$ = nullptr;
-    quickstep_yyerror(&@1, yyscanner, nullptr,
-        "INTERVAL is ambiguous as a column type. Specify either DATETIME INTERVAL "
-        "or YEARMONTH INTERVAL");
-    YYERROR;
+  | data_type_parameter_commalist ',' data_type opt_nullable {
+    $$ = $1;
+    $3->setNullable($4);
+    $$->addParameter(
+        new quickstep::ParseDataTypeParameterDataType($3->line_number(), $3->column_number(), $3));
   }
-  | TOKEN_DATETIME TOKEN_INTERVAL {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kDatetimeInterval));
+  | any_name '(' literal_value {
+    $$ = new quickstep::ParseDataType(@1.first_line, @1.first_column, $1);
+    $$->addParameter(
+        new quickstep::ParseDataTypeParameterLiteralValue($3->line_number(), $3->column_number(), $3));
   }
-  | TOKEN_YEARMONTH TOKEN_INTERVAL {
-    $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kYearMonthInterval));
+  | data_type_parameter_commalist ',' literal_value {
+    $$ = $1;
+    $$->addParameter(
+        new quickstep::ParseDataTypeParameterLiteralValue($3->line_number(), $3->column_number(), $3));
+  };
+
+opt_nullable:
+  {
+    $$ = false;  // NOT NULL
   }
-  | TOKEN_CHARACTER '(' TOKEN_UNSIGNED_NUMVAL ')' {
-    if ($3->float_like()) {
-      delete $3;
-      $$ = NULL;
-      quickstep_yyerror(&@3, yyscanner, nullptr, "Non-integer length supplied for CHAR type");
-      YYERROR;
-    } else {
-      if ($3->long_value() <= 0) {
-        delete $3;
-        $$ = NULL;
-        quickstep_yyerror(&@3, yyscanner, nullptr, "Length for CHAR type must be at least 1");
-        YYERROR;
-      } else {
-        $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kChar, $3->long_value(), false));
-        delete $3;
-      }
-    }
+  | TOKEN_NULL {
+    $$ = true;  // NULL
   }
-  | TOKEN_VARCHAR '(' TOKEN_UNSIGNED_NUMVAL ')' {
-    if ($3->float_like()) {
-      delete $3;
-      $$ = NULL;
-      quickstep_yyerror(&@3, yyscanner, nullptr, "Non-integer length supplied for VARCHAR type");
-      YYERROR;
-    } else {
-      if ($3->long_value() < 0) {
-        delete $3;
-        $$ = NULL;
-        quickstep_yyerror(&@3, yyscanner, nullptr, "Negative length supplied for VARCHAR type");
-        YYERROR;
-      } else {
-        $$ = new quickstep::ParseDataType(quickstep::TypeFactory::GetType(quickstep::kVarChar, $3->long_value(), false));
-        delete $3;
-      }
-    }
+  | TOKEN_NOT TOKEN_NULL {
+    $$ = true;  // NOT NULL
   };
 
 column_constraint_def:
@@ -1787,51 +1720,11 @@ function_call:
 
 cast_function:
   TOKEN_CAST '(' add_expression TOKEN_AS data_type ')' {
-    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
-    arguments->push_back($3);
-    arguments->push_back(new quickstep::ParseScalarLiteral(
-        new quickstep::StringParseLiteralValue(
-            new quickstep::ParseString(@5.first_line,
-                                       @5.first_column,
-                                       $5->getType().getName()),
-            nullptr)));
-    delete $5;
-    auto *name = new quickstep::ParseString(@1.first_line, @1.first_column, "cast");
-    $$ = new quickstep::ParseFunctionCall(
-        @1.first_line, @1.first_column, false, name, arguments);
-  }
-  | TOKEN_CAST '(' add_expression TOKEN_AS any_name ')' {
-    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
-    arguments->push_back($3);
-    arguments->push_back(new quickstep::ParseScalarLiteral(
-        new quickstep::StringParseLiteralValue($5, nullptr)));
-    auto *name = new quickstep::ParseString(@1.first_line, @1.first_column, "cast");
-    $$ = new quickstep::ParseFunctionCall(
-        @1.first_line, @1.first_column, false, name, arguments);
+    $$ = new quickstep::ParseTypeCast(@1.first_line, @1.first_column, $3, $5);
   }
   | expression_base TOKEN_DOUBLECOLON data_type {
-    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
-    arguments->push_back($1);
-    arguments->push_back(new quickstep::ParseScalarLiteral(
-        new quickstep::StringParseLiteralValue(
-            new quickstep::ParseString(@3.first_line,
-                                       @3.first_column,
-                                       $3->getType().getName()),
-            nullptr)));
-    delete $3;
-    auto *name = new quickstep::ParseString(@2.first_line, @2.first_column, "cast");
-    $$ = new quickstep::ParseFunctionCall(
-        @2.first_line, @2.first_column, false, name, arguments);
-  }
-  | expression_base TOKEN_DOUBLECOLON any_name {
-    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
-    arguments->push_back($1);
-    arguments->push_back(new quickstep::ParseScalarLiteral(
-        new quickstep::StringParseLiteralValue($3, nullptr)));
-    auto *name = new quickstep::ParseString(@2.first_line, @2.first_column, "cast");
-    $$ = new quickstep::ParseFunctionCall(
-        @2.first_line, @2.first_column, false, name, arguments);
-  }
+    $$ = new quickstep::ParseTypeCast(@2.first_line, @2.first_column, $1, $3);
+  };
 
 extract_function:
   TOKEN_EXTRACT '(' datetime_unit TOKEN_FROM add_expression ')' {
@@ -1976,20 +1869,7 @@ literal_value:
       quickstep_yyerror(&@3, yyscanner, nullptr, "Failed to parse literal as specified type");
       YYERROR;
     }
-  }
-  | data_type TOKEN_STRING_SINGLE_QUOTED {
-    quickstep::StringParseLiteralValue *parse_value
-        = new quickstep::StringParseLiteralValue($2, &($1->getType()));
-    delete $1;
-    if (!parse_value->tryExplicitTypeParse()) {
-      delete parse_value;
-      $$ = nullptr;
-      quickstep_yyerror(&@2, yyscanner, nullptr, "Failed to parse literal as specified type");
-      YYERROR;
-    } else {
-      $$ = parse_value;
-    }
-  }
+  };
 
 datetime_unit:
   TOKEN_YEAR {



[25/38] incubator-quickstep git commit: Add array expression

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/preprocessed/SqlParser_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.cpp b/parser/preprocessed/SqlParser_gen.cpp
index 569408e..7bdc0ab 100644
--- a/parser/preprocessed/SqlParser_gen.cpp
+++ b/parser/preprocessed/SqlParser_gen.cpp
@@ -263,61 +263,63 @@ extern int quickstep_yydebug;
     TOKEN_JOIN = 336,
     TOKEN_KEY = 337,
     TOKEN_LAST = 338,
-    TOKEN_LEFT = 339,
-    TOKEN_LIMIT = 340,
-    TOKEN_LONG = 341,
-    TOKEN_MINUTE = 342,
-    TOKEN_MONTH = 343,
-    TOKEN_NULL = 344,
-    TOKEN_NULLS = 345,
-    TOKEN_OFF = 346,
-    TOKEN_ON = 347,
-    TOKEN_ORDER = 348,
-    TOKEN_OUTER = 349,
-    TOKEN_OVER = 350,
-    TOKEN_PARTITION = 351,
-    TOKEN_PARTITIONS = 352,
-    TOKEN_PERCENT = 353,
-    TOKEN_PRECEDING = 354,
-    TOKEN_PRIMARY = 355,
-    TOKEN_PRIORITY = 356,
-    TOKEN_QUIT = 357,
-    TOKEN_RANGE = 358,
-    TOKEN_REAL = 359,
-    TOKEN_REFERENCES = 360,
-    TOKEN_RIGHT = 361,
-    TOKEN_ROW = 362,
-    TOKEN_ROW_DELIMITER = 363,
-    TOKEN_ROWS = 364,
-    TOKEN_SECOND = 365,
-    TOKEN_SELECT = 366,
-    TOKEN_SET = 367,
-    TOKEN_SMA = 368,
-    TOKEN_SMALLINT = 369,
-    TOKEN_STDERR = 370,
-    TOKEN_STDOUT = 371,
-    TOKEN_SUBSTRING = 372,
-    TOKEN_TABLE = 373,
-    TOKEN_THEN = 374,
-    TOKEN_TIME = 375,
-    TOKEN_TIMESTAMP = 376,
-    TOKEN_TO = 377,
-    TOKEN_TRUE = 378,
-    TOKEN_TUPLESAMPLE = 379,
-    TOKEN_UNBOUNDED = 380,
-    TOKEN_UNIQUE = 381,
-    TOKEN_UPDATE = 382,
-    TOKEN_USING = 383,
-    TOKEN_VALUES = 384,
-    TOKEN_VARCHAR = 385,
-    TOKEN_WHEN = 386,
-    TOKEN_WHERE = 387,
-    TOKEN_WINDOW = 388,
-    TOKEN_WITH = 389,
-    TOKEN_YEAR = 390,
-    TOKEN_YEARMONTH = 391,
-    TOKEN_EOF = 392,
-    TOKEN_LEX_ERROR = 393
+    TOKEN_LBRACE = 339,
+    TOKEN_LEFT = 340,
+    TOKEN_LIMIT = 341,
+    TOKEN_LONG = 342,
+    TOKEN_MINUTE = 343,
+    TOKEN_MONTH = 344,
+    TOKEN_NULL = 345,
+    TOKEN_NULLS = 346,
+    TOKEN_OFF = 347,
+    TOKEN_ON = 348,
+    TOKEN_ORDER = 349,
+    TOKEN_OUTER = 350,
+    TOKEN_OVER = 351,
+    TOKEN_PARTITION = 352,
+    TOKEN_PARTITIONS = 353,
+    TOKEN_PERCENT = 354,
+    TOKEN_PRECEDING = 355,
+    TOKEN_PRIMARY = 356,
+    TOKEN_PRIORITY = 357,
+    TOKEN_QUIT = 358,
+    TOKEN_RANGE = 359,
+    TOKEN_RBRACE = 360,
+    TOKEN_REAL = 361,
+    TOKEN_REFERENCES = 362,
+    TOKEN_RIGHT = 363,
+    TOKEN_ROW = 364,
+    TOKEN_ROW_DELIMITER = 365,
+    TOKEN_ROWS = 366,
+    TOKEN_SECOND = 367,
+    TOKEN_SELECT = 368,
+    TOKEN_SET = 369,
+    TOKEN_SMA = 370,
+    TOKEN_SMALLINT = 371,
+    TOKEN_STDERR = 372,
+    TOKEN_STDOUT = 373,
+    TOKEN_SUBSTRING = 374,
+    TOKEN_TABLE = 375,
+    TOKEN_THEN = 376,
+    TOKEN_TIME = 377,
+    TOKEN_TIMESTAMP = 378,
+    TOKEN_TO = 379,
+    TOKEN_TRUE = 380,
+    TOKEN_TUPLESAMPLE = 381,
+    TOKEN_UNBOUNDED = 382,
+    TOKEN_UNIQUE = 383,
+    TOKEN_UPDATE = 384,
+    TOKEN_USING = 385,
+    TOKEN_VALUES = 386,
+    TOKEN_VARCHAR = 387,
+    TOKEN_WHEN = 388,
+    TOKEN_WHERE = 389,
+    TOKEN_WINDOW = 390,
+    TOKEN_WITH = 391,
+    TOKEN_YEAR = 392,
+    TOKEN_YEARMONTH = 393,
+    TOKEN_EOF = 394,
+    TOKEN_LEX_ERROR = 395
   };
 #endif
 
@@ -401,6 +403,7 @@ union YYSTYPE
   quickstep::ParseString *unary_operation_;
   quickstep::ParseString *binary_operation_;
 
+  quickstep::ParseArray *array_expression_;
   quickstep::ParseFunctionCall *function_call_;
   quickstep::PtrList<quickstep::ParseExpression> *expression_list_;
 
@@ -427,7 +430,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 431 "SqlParser_gen.cpp" /* yacc.c:355  */
+#line 434 "SqlParser_gen.cpp" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -456,13 +459,13 @@ int quickstep_yyparse (yyscan_t yyscanner, quickstep::ParseStatement **parsedSta
 #endif /* !YY_QUICKSTEP_YY_SQLPARSER_GEN_HPP_INCLUDED  */
 
 /* Copy the second part of user declarations.  */
-#line 216 "../SqlParser.ypp" /* yacc.c:358  */
+#line 217 "../SqlParser.ypp" /* yacc.c:358  */
 
 /* This header needs YYSTYPE, which is defined by the %union directive above */
 #include "SqlLexer_gen.hpp"
 void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature);
 
-#line 466 "SqlParser_gen.cpp" /* yacc.c:358  */
+#line 469 "SqlParser_gen.cpp" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -706,21 +709,21 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  50
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1282
+#define YYLAST   1626
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  150
+#define YYNTOKENS  152
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  111
+#define YYNNTS  113
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  303
+#define YYNRULES  308
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  562
+#define YYNSTATES  570
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   393
+#define YYMAXUTOK   395
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -730,11 +733,11 @@ union yyalloc
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     145,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     147,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,   149,     2,     2,
-     146,   147,    23,    21,   148,    22,    27,    24,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,   144,
+       2,     2,     2,     2,     2,     2,     2,   151,     2,     2,
+     148,   149,    23,    21,   150,    22,    27,    24,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,   146,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -768,44 +771,44 @@ static const yytype_uint8 yytranslate[] =
      110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
      120,   121,   122,   123,   124,   125,   126,   127,   128,   129,
      130,   131,   132,   133,   134,   135,   136,   137,   138,   139,
-     140,   141,   142,   143
+     140,   141,   142,   143,   144,   145
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   635,   635,   639,   643,   647,   651,   654,   661,   664,
-     667,   670,   673,   676,   679,   682,   685,   688,   694,   700,
-     707,   713,   720,   729,   734,   743,   748,   753,   757,   763,
-     768,   771,   774,   779,   782,   785,   788,   791,   794,   797,
-     800,   803,   806,   818,   821,   824,   842,   862,   865,   868,
-     873,   878,   884,   890,   899,   903,   909,   912,   917,   922,
-     927,   934,   941,   945,   951,   954,   959,   962,   967,   970,
-     975,   978,   997,  1000,  1005,  1009,  1015,  1018,  1021,  1024,
-    1029,  1032,  1035,  1042,  1047,  1058,  1063,  1068,  1072,  1076,
-    1082,  1085,  1091,  1099,  1102,  1105,  1111,  1116,  1121,  1125,
-    1131,  1135,  1138,  1143,  1146,  1151,  1156,  1161,  1165,  1171,
-    1180,  1183,  1188,  1191,  1210,  1215,  1219,  1225,  1231,  1240,
-    1245,  1253,  1259,  1265,  1268,  1271,  1276,  1279,  1284,  1288,
-    1294,  1297,  1300,  1305,  1310,  1315,  1318,  1321,  1326,  1329,
-    1332,  1335,  1338,  1341,  1344,  1347,  1352,  1355,  1360,  1364,
-    1368,  1371,  1375,  1378,  1383,  1386,  1391,  1394,  1399,  1403,
-    1409,  1412,  1417,  1420,  1425,  1428,  1433,  1436,  1455,  1458,
-    1463,  1467,  1473,  1479,  1484,  1487,  1492,  1495,  1500,  1503,
-    1508,  1511,  1516,  1517,  1520,  1525,  1526,  1529,  1534,  1538,
-    1544,  1551,  1554,  1557,  1562,  1565,  1568,  1574,  1577,  1582,
-    1587,  1596,  1601,  1610,  1615,  1618,  1623,  1626,  1631,  1637,
-    1643,  1646,  1649,  1652,  1655,  1658,  1664,  1673,  1679,  1684,
-    1690,  1695,  1700,  1705,  1708,  1711,  1714,  1718,  1722,  1725,
-    1728,  1731,  1734,  1737,  1742,  1746,  1750,  1753,  1758,  1772,
-    1781,  1795,  1806,  1817,  1825,  1836,  1839,  1844,  1848,  1854,
-    1859,  1863,  1869,  1874,  1877,  1882,  1886,  1892,  1895,  1898,
-    1901,  1913,  1917,  1936,  1949,  1964,  1967,  1970,  1973,  1976,
-    1979,  1984,  1988,  1994,  1997,  2002,  2006,  2013,  2016,  2019,
-    2022,  2025,  2028,  2031,  2034,  2037,  2040,  2045,  2056,  2059,
-    2064,  2067,  2070,  2076,  2080,  2086,  2089,  2097,  2100,  2103,
-    2106,  2112,  2117,  2122
+       0,   643,   643,   647,   651,   655,   659,   662,   669,   672,
+     675,   678,   681,   684,   687,   690,   693,   696,   702,   708,
+     715,   721,   728,   737,   742,   751,   756,   761,   765,   771,
+     776,   779,   782,   787,   790,   793,   796,   799,   802,   805,
+     808,   811,   814,   826,   829,   832,   850,   870,   873,   876,
+     881,   886,   892,   898,   907,   911,   917,   920,   925,   930,
+     935,   942,   949,   953,   959,   962,   967,   970,   975,   978,
+     983,   986,  1005,  1008,  1013,  1017,  1023,  1026,  1029,  1032,
+    1037,  1040,  1043,  1050,  1055,  1066,  1071,  1076,  1080,  1084,
+    1090,  1093,  1099,  1107,  1110,  1113,  1119,  1124,  1129,  1133,
+    1139,  1143,  1146,  1151,  1154,  1159,  1164,  1169,  1173,  1179,
+    1188,  1191,  1196,  1199,  1218,  1223,  1227,  1233,  1239,  1248,
+    1253,  1261,  1267,  1273,  1276,  1279,  1284,  1287,  1292,  1296,
+    1302,  1305,  1308,  1313,  1318,  1323,  1326,  1329,  1334,  1337,
+    1340,  1343,  1346,  1349,  1352,  1355,  1360,  1363,  1368,  1372,
+    1376,  1379,  1383,  1386,  1391,  1394,  1399,  1402,  1407,  1411,
+    1417,  1420,  1425,  1428,  1433,  1436,  1441,  1444,  1463,  1466,
+    1471,  1475,  1481,  1487,  1492,  1495,  1500,  1503,  1508,  1511,
+    1516,  1519,  1524,  1525,  1528,  1533,  1534,  1537,  1542,  1546,
+    1552,  1559,  1562,  1565,  1570,  1573,  1576,  1582,  1585,  1590,
+    1595,  1604,  1609,  1618,  1623,  1626,  1631,  1634,  1639,  1645,
+    1651,  1654,  1657,  1660,  1663,  1666,  1672,  1681,  1687,  1692,
+    1698,  1703,  1708,  1713,  1716,  1719,  1722,  1725,  1729,  1733,
+    1736,  1739,  1742,  1745,  1748,  1753,  1756,  1762,  1766,  1773,
+    1777,  1781,  1784,  1789,  1803,  1812,  1826,  1837,  1848,  1856,
+    1867,  1870,  1875,  1879,  1885,  1890,  1894,  1900,  1905,  1908,
+    1913,  1917,  1923,  1926,  1929,  1932,  1944,  1948,  1967,  1980,
+    1995,  1998,  2001,  2004,  2007,  2010,  2015,  2019,  2025,  2028,
+    2033,  2037,  2044,  2047,  2050,  2053,  2056,  2059,  2062,  2065,
+    2068,  2071,  2076,  2087,  2090,  2095,  2098,  2101,  2107,  2111,
+    2117,  2120,  2128,  2131,  2134,  2137,  2143,  2148,  2153
 };
 #endif
 
@@ -834,19 +837,19 @@ static const char *const yytname[] =
   "TOKEN_FOREIGN", "TOKEN_FROM", "TOKEN_FULL", "TOKEN_GROUP", "TOKEN_HASH",
   "TOKEN_HAVING", "TOKEN_HOUR", "TOKEN_IN", "TOKEN_INDEX", "TOKEN_INNER",
   "TOKEN_INSERT", "TOKEN_INTEGER", "TOKEN_INTERVAL", "TOKEN_INTO",
-  "TOKEN_JOIN", "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT", "TOKEN_LIMIT",
-  "TOKEN_LONG", "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL", "TOKEN_NULLS",
-  "TOKEN_OFF", "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER", "TOKEN_OVER",
-  "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
+  "TOKEN_JOIN", "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LBRACE", "TOKEN_LEFT",
+  "TOKEN_LIMIT", "TOKEN_LONG", "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL",
+  "TOKEN_NULLS", "TOKEN_OFF", "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER",
+  "TOKEN_OVER", "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
   "TOKEN_PRECEDING", "TOKEN_PRIMARY", "TOKEN_PRIORITY", "TOKEN_QUIT",
-  "TOKEN_RANGE", "TOKEN_REAL", "TOKEN_REFERENCES", "TOKEN_RIGHT",
-  "TOKEN_ROW", "TOKEN_ROW_DELIMITER", "TOKEN_ROWS", "TOKEN_SECOND",
-  "TOKEN_SELECT", "TOKEN_SET", "TOKEN_SMA", "TOKEN_SMALLINT",
-  "TOKEN_STDERR", "TOKEN_STDOUT", "TOKEN_SUBSTRING", "TOKEN_TABLE",
-  "TOKEN_THEN", "TOKEN_TIME", "TOKEN_TIMESTAMP", "TOKEN_TO", "TOKEN_TRUE",
-  "TOKEN_TUPLESAMPLE", "TOKEN_UNBOUNDED", "TOKEN_UNIQUE", "TOKEN_UPDATE",
-  "TOKEN_USING", "TOKEN_VALUES", "TOKEN_VARCHAR", "TOKEN_WHEN",
-  "TOKEN_WHERE", "TOKEN_WINDOW", "TOKEN_WITH", "TOKEN_YEAR",
+  "TOKEN_RANGE", "TOKEN_RBRACE", "TOKEN_REAL", "TOKEN_REFERENCES",
+  "TOKEN_RIGHT", "TOKEN_ROW", "TOKEN_ROW_DELIMITER", "TOKEN_ROWS",
+  "TOKEN_SECOND", "TOKEN_SELECT", "TOKEN_SET", "TOKEN_SMA",
+  "TOKEN_SMALLINT", "TOKEN_STDERR", "TOKEN_STDOUT", "TOKEN_SUBSTRING",
+  "TOKEN_TABLE", "TOKEN_THEN", "TOKEN_TIME", "TOKEN_TIMESTAMP", "TOKEN_TO",
+  "TOKEN_TRUE", "TOKEN_TUPLESAMPLE", "TOKEN_UNBOUNDED", "TOKEN_UNIQUE",
+  "TOKEN_UPDATE", "TOKEN_USING", "TOKEN_VALUES", "TOKEN_VARCHAR",
+  "TOKEN_WHEN", "TOKEN_WHERE", "TOKEN_WINDOW", "TOKEN_WITH", "TOKEN_YEAR",
   "TOKEN_YEARMONTH", "TOKEN_EOF", "TOKEN_LEX_ERROR", "';'", "'\\n'", "'('",
   "')'", "','", "'%'", "$accept", "start", "sql_statement",
   "quit_statement", "alter_table_statement", "create_table_statement",
@@ -876,7 +879,8 @@ static const char *const yytname[] =
   "opt_order_direction", "opt_nulls_first", "opt_where_clause",
   "where_clause", "or_expression", "and_expression", "not_expression",
   "predicate_expression_base", "add_expression", "multiply_expression",
-  "unary_expression", "expression_base", "function_call", "cast_function",
+  "unary_expression", "expression_base", "array_expression",
+  "array_element_commalist", "function_call", "cast_function",
   "extract_function", "substr_function", "case_expression",
   "simple_when_clause_list", "simple_when_clause",
   "searched_when_clause_list", "searched_when_clause", "opt_else_clause",
@@ -907,14 +911,15 @@ static const yytype_uint16 yytoknum[] =
      360,   361,   362,   363,   364,   365,   366,   367,   368,   369,
      370,   371,   372,   373,   374,   375,   376,   377,   378,   379,
      380,   381,   382,   383,   384,   385,   386,   387,   388,   389,
-     390,   391,   392,   393,    59,    10,    40,    41,    44,    37
+     390,   391,   392,   393,   394,   395,    59,    10,    40,    41,
+      44,    37
 };
 # endif
 
-#define YYPACT_NINF -370
+#define YYPACT_NINF -280
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-370)))
+  (!!((Yystate) == (-280)))
 
 #define YYTABLE_NINF -139
 
@@ -925,63 +930,63 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     318,  -370,  -370,   -80,    69,   -19,    41,   -25,    43,  -370,
-      42,   242,   242,  -370,   137,   148,  -370,  -370,  -370,  -370,
-    -370,  -370,  -370,  -370,  -370,  -370,   173,    70,   114,  -370,
-     132,   215,   242,  -370,  -370,    11,     5,   242,   242,   242,
-     242,   242,  -370,  -370,   662,   111,    99,  -370,   233,   122,
-    -370,  -370,  -370,   186,   221,    70,    42,   206,  -370,   186,
-    -370,  -370,  -370,    74,    67,   175,   321,   175,   231,   195,
-     205,  -370,   -34,  -370,  -370,   337,   342,  -370,  -370,  -370,
-     730,   208,   228,  -370,   268,  -370,  -370,   244,  -370,  -370,
-     353,  -370,  -370,  -370,  -370,   246,  -370,  -370,   247,   299,
-     825,   386,   322,   255,  -370,  -370,   314,    27,  -370,   333,
-     304,  -370,  -370,  -370,  -370,  -370,  -370,   988,    -5,   242,
-     242,   259,   242,    11,   242,  -370,   186,   399,  -370,   155,
-     236,  -370,  -370,  -370,   261,  -370,   175,  -370,   242,   242,
-     567,  -370,  -370,   265,   242,  -370,  -370,  -370,   567,    25,
-     -15,  -370,  1056,   405,  -370,   146,   146,  1056,   409,  -370,
-       3,    32,  -370,    19,   205,  1056,  -370,  -370,   242,  1056,
-    -370,  -370,  -370,  -370,  1056,   635,    23,   342,   333,   242,
-     392,    60,  -370,   408,  -370,   186,  -370,   -68,  -370,   175,
-     186,   114,  -370,   242,   165,   242,   242,   242,  -370,   274,
-    -370,   112,   798,   893,   259,   499,   413,   415,  -370,  -370,
-    1201,   402,  1141,   150,    33,  1056,   149,  -370,  1056,  -370,
-     362,   220,   283,  -370,  -370,  -370,  -370,  -370,  -370,   358,
-    -370,    46,   285,  -370,  -370,     7,   190,   248,  -370,   290,
-     190,    38,   364,  -370,  -370,    27,  -370,  -370,  -370,  -370,
-     332,  -370,  -370,   293,  1056,  -370,   279,   163,   242,  -370,
-    1056,  -370,   242,  -370,  -370,  -370,   295,   355,   356,   300,
-    -370,  -370,  -370,   169,  -370,  -370,  -370,  -370,  -370,    14,
-     242,   316,   165,   242,   194,  -370,  -370,     4,    73,   567,
-     567,   245,  -370,  -370,  -370,  -370,  -370,  -370,  -370,  -370,
-    1056,   307,  1056,    53,  -370,   183,   320,  1056,    75,  -370,
-     395,   279,  -370,   635,  -370,  1056,   449,  -370,   124,   242,
-    -370,  -370,   363,  -370,   365,   366,   377,    19,  -370,   459,
-     460,   190,   426,   393,   427,   325,   375,  -370,   185,  -370,
-    1056,  -370,   279,  -370,   567,   328,   331,   242,  -370,   242,
-    -370,  -370,  -370,  -370,  -370,  -370,  -370,   242,  -370,  -370,
-    -370,   191,   452,   189,  -370,   334,   345,  -370,   387,   339,
-    1141,  -370,   400,   242,  -370,  -370,   194,  -370,  -370,   415,
-    -370,  -370,  -370,  1056,   343,   212,   825,  -370,   279,   394,
-    -370,  -370,  1141,   344,   279,  1056,  -370,   346,   347,    34,
-     -22,  -370,  -370,  -370,  -370,  -370,    19,   248,   388,   389,
-    -370,  1056,   567,   397,  1056,  -370,   455,   135,  -370,   279,
-      16,   242,   242,   209,  -370,   214,  -370,   242,  -370,  -370,
-    -370,  -370,   352,   165,   461,   401,  -370,   567,  -370,  -370,
-     354,  -370,   235,   825,  -370,  1056,   216,  -370,  -370,  1141,
-     279,  -370,  -370,  -370,   501,  -370,   416,  -370,  -370,   367,
-     413,   468,   422,   367,  1056,  -370,  -370,  -370,   497,  -370,
-     218,   223,  -370,  -370,  -370,   242,  -370,  -370,   376,   481,
-    -370,    31,   242,  1056,   225,   279,  -370,   230,   378,   567,
-    1056,   517,   390,   381,  -370,   193,     9,   420,  -370,   234,
-     242,     0,  -370,   379,   279,  -370,  -370,  -370,   413,   381,
-    -370,   242,  -370,   390,  -370,  1056,  -370,  -370,   436,   428,
-     424,   437,   531,   242,  -370,   237,  -370,  -370,   403,  -370,
-     513,  -370,  -370,    39,  -370,  -370,  -370,  -370,    52,   404,
-    -370,   242,   407,  -370,  -370,   477,   443,   478,  -370,   242,
-     239,   332,  -370,  -370,  -370,   241,   454,   410,  -370,   551,
-    -370,  -370
+     185,  -280,  -280,   -26,    38,     6,    29,    16,    26,  -280,
+      47,   210,   210,  -280,   215,    84,  -280,  -280,  -280,  -280,
+    -280,  -280,  -280,  -280,  -280,  -280,   173,    66,   201,  -280,
+     -54,   222,   210,  -280,  -280,     1,   135,   210,   210,   210,
+     210,   210,  -280,  -280,   768,   138,   113,  -280,   236,   117,
+    -280,  -280,  -280,   154,   189,    66,    47,   187,  -280,   154,
+    -280,  -280,  -280,    50,    22,   151,   294,   151,   214,   160,
+     177,  -280,   -14,  -280,  -280,   314,   317,  -280,  -280,  -280,
+     865,   170,   174,  -280,   246,  -280,  -280,   190,  -280,  -280,
+     337,   962,  -280,  -280,  -280,  -280,   204,  -280,  -280,   209,
+     279,  1059,   355,   292,   217,  -280,  -280,   358,    40,  -280,
+     313,  -280,   -18,   277,  -280,  -280,  -280,  -280,  -280,  -280,
+    1265,     5,   210,   210,   235,   210,     1,   210,  -280,   154,
+     379,  -280,    81,   162,  -280,  -280,  -280,   242,  -280,   151,
+    -280,   210,   210,   671,  -280,  -280,   260,   210,  -280,  -280,
+    -280,   671,    63,    51,  -280,  1362,   387,  -280,   183,   183,
+    -280,   276,  1362,   410,  -280,    -9,    46,  -280,     9,   177,
+    1362,  -280,  -280,   210,  1362,  -280,  -280,  -280,  -280,  1362,
+     340,  -280,  1362,    19,   317,   313,   210,   437,    73,  -280,
+     424,  -280,   154,  -280,   191,  -280,   151,   154,   201,  -280,
+     210,   172,   210,   210,   210,  -280,   288,  -280,   200,  1483,
+    1168,   235,   562,   430,   431,  -280,  -280,   525,   419,  1442,
+     205,    52,  1362,    54,  -280,  1362,  -280,   381,   315,   297,
+    -280,  -280,  -280,  -280,  -280,  -280,   374,  -280,   198,   299,
+    -280,  -280,    18,   220,   253,  -280,   300,   220,     2,   377,
+    -280,  -280,    40,  -280,  -280,  -280,  -280,   276,   347,  -280,
+    -280,   304,  1362,  -280,   276,   221,   210,  -280,  1362,  -280,
+     210,  -280,  -280,  -280,   306,   368,   370,   316,  -280,  -280,
+    -280,   223,  -280,  -280,  -280,  -280,  -280,    12,   210,   327,
+     172,   210,   195,  -280,  -280,    21,    36,   671,   671,   231,
+    -280,  -280,  -280,  -280,  -280,  -280,  -280,  -280,  1362,   318,
+    1362,    86,  -280,   232,   329,  1362,    67,  -280,   405,   276,
+    -280,   340,  -280,  1362,   463,  -280,   155,   210,  -280,  -280,
+     371,  -280,   375,   376,   388,     9,  -280,   471,   477,   220,
+     443,   414,   445,   344,   395,  -280,   239,  -280,  1362,  -280,
+     276,  -280,   671,   350,   351,   210,  -280,   210,  -280,  -280,
+    -280,  -280,  -280,  -280,  -280,   210,  -280,  -280,  -280,   247,
+     468,    60,  -280,   352,   359,  -280,   406,   357,  1442,  -280,
+     420,   210,  -280,  -280,   195,  -280,  -280,   431,  -280,  -280,
+    -280,  1362,   360,   237,  1059,  -280,   276,   415,  -280,  -280,
+    1442,   361,   276,  1362,  -280,   362,   363,    55,    -1,  -280,
+    -280,  -280,  -280,  -280,     9,   253,   409,   412,  -280,  1362,
+     671,   418,  1362,  -280,   472,   -22,  -280,   276,    23,   210,
+     210,   249,  -280,   252,  -280,   210,  -280,  -280,  -280,  -280,
+     380,   172,   480,   417,  -280,   671,  -280,  -280,   382,  -280,
+     293,  1059,  -280,  1362,   254,  -280,  -280,  1442,   276,  -280,
+    -280,  -280,   515,  -280,   425,  -280,  -280,   383,   430,   482,
+     434,   383,  1362,  -280,  -280,  -280,   512,  -280,   257,   262,
+    -280,  -280,  -280,   210,  -280,  -280,   386,   507,  -280,    35,
+     210,  1362,   265,   276,  -280,   270,   401,   671,  1362,   544,
+     416,   402,  -280,   311,    31,   442,  -280,   272,   210,    15,
+    -280,   408,   276,  -280,  -280,  -280,   430,   402,  -280,   210,
+    -280,   416,  -280,  1362,  -280,  -280,   459,   454,   446,   457,
+     554,   210,  -280,   278,  -280,  -280,   422,  -280,   538,  -280,
+    -280,    37,  -280,  -280,  -280,  -280,    62,   427,  -280,   210,
+     428,  -280,  -280,   503,   464,   509,  -280,   210,   280,   347,
+    -280,  -280,  -280,   284,   474,   432,  -280,   575,  -280,  -280
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -989,97 +994,97 @@ static const yytype_int16 yypact[] =
      means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
-       0,     6,   303,     0,     0,     0,     0,     0,     0,    18,
+       0,     6,   308,     0,     0,     0,     0,     0,     0,    18,
      123,     0,     0,     7,     0,     0,    15,     8,    10,    11,
       13,    14,     9,    17,    12,    16,     0,   112,   119,   121,
-       0,   301,     0,   295,   296,     0,     0,     0,     0,     0,
+       0,   306,     0,   300,   301,     0,     0,     0,     0,     0,
        0,     0,   124,   125,     0,     0,   114,   115,     0,   156,
        1,     3,     2,     0,     0,   112,   123,     0,   110,     0,
-       5,     4,   302,     0,     0,   103,     0,   103,     0,     0,
-     197,    25,     0,   261,   258,     0,   287,   126,    40,    29,
+       5,     4,   307,     0,     0,   103,     0,   103,     0,     0,
+     197,    25,     0,   266,   263,     0,   292,   126,    40,    29,
        0,     0,     0,    30,    31,    34,    36,     0,    37,    39,
-       0,    41,   257,    35,    38,     0,    32,    33,     0,     0,
-       0,     0,     0,   127,   128,   233,   132,   218,   220,   222,
-     225,   228,   229,   230,   231,   224,   223,     0,   273,     0,
-       0,     0,     0,     0,     0,   111,     0,     0,   120,     0,
-       0,   100,   102,   101,     0,    98,   103,    97,     0,     0,
-       0,   106,   198,     0,     0,    94,   259,   260,     0,     0,
-     253,   250,     0,     0,    43,     0,   262,     0,     0,    44,
-       0,     0,   264,     0,   197,     0,   288,   289,     0,     0,
-     131,   291,   292,   290,     0,     0,     0,     0,   221,     0,
-       0,   197,   108,     0,   116,     0,   117,     0,   293,   103,
-       0,   118,   113,     0,     0,     0,     0,     0,    96,    66,
-      27,     0,     0,     0,     0,     0,   199,   201,   203,   205,
-       0,   223,     0,     0,     0,     0,   253,   247,     0,   251,
-       0,     0,     0,   267,   268,   269,   266,   270,   265,     0,
-     263,     0,     0,   134,   232,     0,     0,   158,   147,   133,
-     152,   135,   160,   129,   130,   217,   219,    42,   240,   241,
-     174,   226,   274,     0,     0,   234,   255,     0,     0,   105,
-       0,   157,     0,    99,    95,    19,     0,     0,     0,     0,
-      20,    21,    22,     0,    74,    76,    77,    78,    79,     0,
-       0,     0,    64,     0,    56,   204,   212,     0,     0,     0,
-       0,     0,   277,   279,   280,   281,   282,   278,   283,   285,
-       0,     0,     0,     0,   271,     0,     0,     0,     0,   248,
-       0,   254,   246,     0,    45,     0,     0,    46,   138,     0,
-     148,   154,   144,   139,   140,   142,     0,     0,   151,     0,
-       0,   150,     0,   162,     0,     0,   176,   235,     0,   236,
-       0,   107,   109,   294,     0,     0,     0,     0,   104,     0,
-      81,    84,    82,   299,   300,   298,   297,     0,    80,    85,
-     275,     0,   273,     0,    63,    65,    68,    28,     0,     0,
-       0,    47,     0,     0,    49,    55,    57,    26,   211,   200,
-     202,   284,   286,     0,     0,     0,     0,   213,   210,     0,
-     209,    93,     0,     0,   252,     0,   245,     0,     0,     0,
-       0,   153,   155,   145,   141,   143,     0,   159,     0,     0,
-     149,     0,     0,   164,     0,   227,     0,   178,   237,   256,
-       0,     0,     0,     0,    75,     0,    67,     0,    86,    87,
-      88,    89,    90,     0,     0,    70,    48,     0,    51,    50,
-       0,    54,     0,     0,   215,     0,     0,   208,   272,     0,
-     249,   238,   239,   242,     0,   243,     0,   136,   137,   161,
-     163,     0,   166,   175,     0,   181,   180,   173,     0,    61,
-       0,     0,    58,    83,   276,     0,    24,    62,     0,     0,
-      23,     0,     0,     0,     0,   206,   214,     0,     0,     0,
-       0,     0,   168,   177,   188,   191,     0,     0,    59,     0,
-       0,     0,    52,     0,   207,   216,    92,   244,   146,   165,
-     167,     0,   122,   169,   170,     0,   192,   193,   194,     0,
-       0,     0,     0,     0,    91,     0,    72,    73,     0,    53,
-       0,   171,   189,     0,   190,   182,   184,   183,     0,     0,
-      69,     0,     0,   195,   196,     0,     0,     0,   179,     0,
-       0,   174,   185,   187,   186,     0,     0,     0,    60,     0,
-     172,    71
+       0,     0,    41,   262,    35,    38,     0,    32,    33,     0,
+       0,     0,     0,     0,   127,   128,   234,   132,   218,   220,
+     222,   225,     0,   226,   229,   230,   231,   232,   224,   223,
+       0,   278,     0,     0,     0,     0,     0,     0,   111,     0,
+       0,   120,     0,     0,   100,   102,   101,     0,    98,   103,
+      97,     0,     0,     0,   106,   198,     0,     0,    94,   264,
+     265,     0,     0,   258,   255,     0,     0,    43,     0,   267,
+     236,   238,     0,     0,    44,     0,     0,   269,     0,   197,
+       0,   293,   294,     0,     0,   131,   296,   297,   295,     0,
+       0,   235,     0,     0,     0,   221,     0,     0,   197,   108,
+       0,   116,     0,   117,     0,   298,   103,     0,   118,   113,
+       0,     0,     0,     0,     0,    96,    66,    27,     0,     0,
+       0,     0,     0,   199,   201,   203,   205,     0,   223,     0,
+       0,     0,     0,   258,   252,     0,   256,     0,     0,     0,
+     272,   273,   274,   271,   275,   270,     0,   268,     0,     0,
+     134,   233,     0,     0,   158,   147,   133,   152,   135,   160,
+     129,   130,   217,   219,    42,   245,   246,   237,   174,   227,
+     279,     0,     0,   239,   260,     0,     0,   105,     0,   157,
+       0,    99,    95,    19,     0,     0,     0,     0,    20,    21,
+      22,     0,    74,    76,    77,    78,    79,     0,     0,     0,
+      64,     0,    56,   204,   212,     0,     0,     0,     0,     0,
+     282,   284,   285,   286,   287,   283,   288,   290,     0,     0,
+       0,     0,   276,     0,     0,     0,     0,   253,     0,   259,
+     251,     0,    45,     0,     0,    46,   138,     0,   148,   154,
+     144,   139,   140,   142,     0,     0,   151,     0,     0,   150,
+       0,   162,     0,     0,   176,   240,     0,   241,     0,   107,
+     109,   299,     0,     0,     0,     0,   104,     0,    81,    84,
+      82,   304,   305,   303,   302,     0,    80,    85,   280,     0,
+     278,     0,    63,    65,    68,    28,     0,     0,     0,    47,
+       0,     0,    49,    55,    57,    26,   211,   200,   202,   289,
+     291,     0,     0,     0,     0,   213,   210,     0,   209,    93,
+       0,     0,   257,     0,   250,     0,     0,     0,     0,   153,
+     155,   145,   141,   143,     0,   159,     0,     0,   149,     0,
+       0,   164,     0,   228,     0,   178,   242,   261,     0,     0,
+       0,     0,    75,     0,    67,     0,    86,    87,    88,    89,
+      90,     0,     0,    70,    48,     0,    51,    50,     0,    54,
+       0,     0,   215,     0,     0,   208,   277,     0,   254,   243,
+     244,   247,     0,   248,     0,   136,   137,   161,   163,     0,
+     166,   175,     0,   181,   180,   173,     0,    61,     0,     0,
+      58,    83,   281,     0,    24,    62,     0,     0,    23,     0,
+       0,     0,     0,   206,   214,     0,     0,     0,     0,     0,
+     168,   177,   188,   191,     0,     0,    59,     0,     0,     0,
+      52,     0,   207,   216,    92,   249,   146,   165,   167,     0,
+     122,   169,   170,     0,   192,   193,   194,     0,     0,     0,
+       0,     0,    91,     0,    72,    73,     0,    53,     0,   171,
+     189,     0,   190,   182,   184,   183,     0,     0,    69,     0,
+       0,   195,   196,     0,     0,     0,   179,     0,     0,   174,
+     185,   187,   186,     0,     0,     0,    60,     0,   172,    71
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -370,  -370,  -370,  -370,  -370,  -370,  -370,  -370,  -135,  -370,
-    -145,   184,  -370,  -370,  -279,  -370,  -370,  -370,  -370,  -370,
-    -370,  -369,   213,  -370,  -370,  -370,  -370,  -370,  -370,  -370,
-    -370,   -10,    -3,  -370,  -370,  -370,   303,  -370,   508,  -370,
-    -370,   446,   287,   441,   -28,   514,  -370,  -370,   411,  -370,
-    -111,  -370,  -370,  -169,   172,  -202,   -11,  -370,  -370,  -370,
-    -370,  -370,  -370,  -370,    56,    24,  -370,  -370,  -370,  -370,
-    -370,  -370,    89,    65,  -370,  -370,   -38,  -370,  -143,   292,
-     294,   382,   -35,   417,   418,   470,  -161,  -370,  -370,  -370,
-    -370,  -370,   380,  -370,   444,   383,  -237,  -197,   435,   151,
-    -134,  -370,  -370,  -370,  -370,  -370,  -140,    -4,  -370,  -370,
-    -370
+    -280,  -280,  -280,  -280,  -280,  -280,  -280,  -280,  -126,  -280,
+    -170,   203,  -280,  -280,  -279,  -280,  -280,  -280,  -280,  -280,
+    -280,  -229,   233,  -280,  -280,  -280,  -280,  -280,  -280,  -280,
+    -280,    42,   -41,  -280,  -280,  -280,   322,  -280,   534,  -280,
+    -280,   469,   256,   462,     0,   537,  -280,  -280,   426,  -280,
+    -103,  -280,  -280,  -181,   180,  -164,    -7,  -280,  -280,  -280,
+    -280,  -280,  -280,  -280,    74,    41,  -280,  -280,  -280,  -280,
+    -280,  -280,   101,    78,  -280,  -280,   -62,  -280,  -150,   305,
+     310,   393,   -35,   435,   433,   490,  -280,  -280,  -162,  -280,
+    -280,  -280,  -280,  -280,   390,  -280,   458,   396,  -248,  -217,
+     461,   159,  -139,  -280,  -280,  -280,  -280,  -280,  -144,    -4,
+    -280,  -280,  -280
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    14,    15,    16,    17,    18,    19,    20,   200,   201,
-     101,   375,   376,   377,   270,   365,   366,   281,   435,   480,
-     528,   273,   274,   275,   276,   277,   278,   432,   476,    21,
-      22,    65,   135,    23,    24,   181,   182,    25,    58,    26,
-      46,    47,   160,    28,    29,    44,   102,   103,   104,   164,
-     105,   331,   326,   237,   238,   320,   321,   239,   333,   413,
-     462,   492,   512,   513,   514,   335,   336,   417,   467,   468,
-     522,   548,   493,   494,   518,   534,   141,   142,   206,   207,
-     208,   209,   210,   107,   108,   109,   110,   111,   112,   113,
-     114,   216,   217,   150,   151,   220,   257,   115,   229,   305,
-     116,   361,   302,   117,   169,   174,   187,   118,   359,    30,
-      31
+      -1,    14,    15,    16,    17,    18,    19,    20,   207,   208,
+     102,   383,   384,   385,   278,   373,   374,   289,   443,   488,
+     536,   281,   282,   283,   284,   285,   286,   440,   484,    21,
+      22,    65,   138,    23,    24,   188,   189,    25,    58,    26,
+      46,    47,   165,    28,    29,    44,   103,   104,   105,   169,
+     106,   339,   334,   244,   245,   328,   329,   246,   341,   421,
+     470,   500,   520,   521,   522,   343,   344,   425,   475,   476,
+     530,   556,   501,   502,   526,   542,   144,   145,   213,   214,
+     215,   216,   217,   108,   109,   110,   111,   112,   113,   114,
+     115,   116,   117,   223,   224,   153,   154,   227,   265,   118,
+     236,   313,   119,   369,   310,   120,   174,   179,   194,   121,
+     367,    30,    31
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -1087,367 +1092,435 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      36,    48,   240,   364,   213,   214,   211,    45,    49,   106,
-     186,    33,   289,    34,   211,   304,   519,   338,    33,   350,
-      34,   351,   179,    33,   289,    34,    67,    33,    63,    34,
-     248,   128,    56,    68,    69,    70,    71,    72,   328,   289,
-      56,   289,   352,    32,   145,   149,   166,   167,   218,   454,
-     171,   172,   236,   166,   167,   166,   167,   284,   265,   545,
-     520,    37,   287,   389,   137,   161,   318,   166,   167,   211,
-      42,   211,   131,    33,   240,    34,   526,   329,    66,   261,
-     262,   353,    10,   291,   292,   293,   294,   295,   296,   297,
-     298,   299,   300,   286,   166,   167,   166,   167,    40,    56,
-     143,    43,   170,   546,    38,   129,   499,   543,   527,    48,
-     354,   355,   144,   189,    39,   183,    49,   221,   188,   316,
-     190,   148,   231,    10,   236,   455,   242,   544,    41,   410,
-     106,   525,    64,   198,   199,   202,   130,    50,    64,   521,
-     188,   180,   356,   259,    59,   256,   360,   390,   367,   446,
-     233,   378,   301,   235,   477,   211,   211,   307,   407,   241,
-     357,   215,   264,   469,   244,   235,   240,   330,   397,   250,
-     288,   249,   251,   438,   459,   252,   173,   463,   502,   234,
-     308,   453,   547,   311,   180,    10,   263,   132,   133,   202,
-     387,   271,   272,   279,    33,   448,    34,   140,   322,   395,
-     223,   420,   193,   194,   368,   323,   484,   423,   258,    57,
-     211,   266,   218,   324,   166,   167,   236,   425,    62,   256,
-     234,   445,    53,   319,   224,   342,   428,   516,   119,   429,
-     430,   241,    49,   166,   167,   325,    49,   267,   225,   226,
-     369,   166,   167,   465,   483,   240,    33,   120,    34,   466,
-     370,   517,   304,   313,   183,    54,   166,   167,   343,   282,
-     283,   227,   381,   382,   383,   385,   121,   388,   122,   460,
-     268,   401,   394,   444,    60,   358,   362,    61,   211,   202,
-     399,   470,   471,   195,   196,   215,   228,    27,   371,    10,
-      51,    35,    52,   474,   481,   236,   269,   306,   262,   372,
-     166,   167,    10,   211,   373,   419,   124,   431,   402,   398,
-     339,   340,   127,    55,   134,    49,   348,   349,    33,     1,
-      34,     2,   322,   241,   384,   374,   136,    49,   138,   323,
-     391,   392,   418,   340,  -138,   166,   167,   324,   426,   427,
-     123,   139,   140,   188,   146,   279,   508,   168,   442,   147,
-       3,   256,   154,   188,   152,   211,   472,   262,   156,   325,
-     450,   473,   262,   486,   340,   497,   262,     4,     5,   440,
-     498,   262,   505,   340,   153,     6,   256,   506,   392,   256,
-       7,   524,   349,   159,   540,   349,   556,   262,   558,   262,
-     155,   162,   157,   158,   175,   163,    33,    73,    34,    74,
-       8,   550,   241,   165,   176,   185,   192,   197,   256,   555,
-     485,   212,   222,    75,    76,   253,   232,   188,   188,   260,
-     280,   289,   303,   362,   290,     9,   312,    78,    79,   495,
-     314,   315,   317,   334,    10,    80,    81,    82,   327,   332,
-     337,   344,   345,   346,    83,    84,   347,    85,   504,   363,
-      11,   254,    86,   386,   393,   495,   400,    12,    87,   396,
-      13,    88,   403,   406,   404,   405,   408,   409,   411,   414,
-     412,   279,   415,   416,   421,    89,    90,   422,   503,   179,
-     495,   436,   433,    91,   434,   437,    92,   439,   447,   443,
-     449,   457,   458,   451,   452,   461,   279,   464,   475,   478,
-     482,    93,   479,    33,    73,    34,    74,   530,   488,   203,
-     490,    94,   491,   489,    95,   340,   496,    96,    97,   539,
-      75,    76,   500,   501,   510,   507,   529,    98,   511,   515,
-     523,   533,   535,    99,    78,    79,   536,   188,   100,   255,
-     538,   537,    80,    81,    82,   188,   542,   552,   554,   541,
-     549,    83,    84,   551,    85,   553,   559,   560,   561,    86,
-     441,   341,   424,   125,   204,    87,   184,   191,    88,   531,
-     126,    33,    73,    34,    74,   557,   243,   203,   456,   509,
-     532,   379,    89,    90,   380,   285,   245,   178,    75,    76,
-      91,   230,   246,    92,   219,     0,   309,     0,     0,   310,
-     487,     0,    78,    79,     0,     0,     0,     0,    93,     0,
-      80,    81,    82,     0,     0,    10,     0,     0,    94,    83,
-      84,    95,    85,     0,    96,    97,     0,    86,     0,     0,
-       0,     0,   204,    87,    98,     0,    88,     0,     0,    33,
-      99,    34,     0,     0,     0,   205,     0,     0,     0,     0,
-      89,    90,     0,     0,     0,     0,     0,     0,    91,     0,
-       0,    92,     0,     0,     0,     0,    33,    73,    34,    74,
-      78,    79,     0,     0,     0,     0,    93,     0,     0,     0,
-      82,     0,     0,    75,    76,    77,    94,    83,    84,    95,
-      85,     0,    96,    97,     0,    86,     0,    78,    79,     0,
-       0,     0,    98,     0,    88,    80,    81,    82,    99,     0,
-       0,     0,     0,   205,    83,    84,     0,    85,    89,   247,
-       0,     0,    86,     0,     0,     0,    91,     0,    87,     0,
-       0,    88,     0,     0,    33,    73,    34,    74,     0,     0,
-       0,     0,     0,     0,    93,    89,    90,     0,     0,     0,
-       0,    75,    76,    91,    94,     0,    92,     0,     0,     0,
-      96,    97,     0,     0,     0,    78,    79,     0,     0,     0,
-      98,    93,     0,    80,    81,    82,    99,     0,     0,     0,
-       0,    94,    83,    84,    95,    85,     0,    96,    97,     0,
-      86,     0,     0,     0,     0,     0,    87,    98,     0,    88,
-       0,     0,     0,    99,     0,     0,     0,     0,   100,     0,
-       0,     0,     0,    89,    90,     0,     0,     0,     0,     0,
-       0,    91,     0,     0,    92,     0,     0,     0,     0,    33,
-      73,    34,    74,    78,    79,     0,     0,     0,     0,    93,
-       0,     0,     0,    82,     0,     0,    75,    76,     0,    94,
-      83,    84,    95,    85,     0,    96,    97,     0,    86,     0,
-      78,    79,     0,     0,     0,    98,   148,    88,    80,    81,
-      82,    99,     0,     0,     0,     0,   100,    83,    84,     0,
-      85,    89,   247,     0,     0,    86,     0,     0,     0,    91,
-       0,    87,     0,     0,    88,     0,     0,    33,    73,    34,
-      74,     0,     0,     0,     0,     0,     0,    93,    89,    90,
-       0,     0,     0,     0,    75,    76,    91,    94,     0,    92,
-       0,     0,     0,    96,    97,     0,     0,     0,    78,    79,
-       0,     0,     0,    98,    93,     0,    80,    81,    82,    99,
-       0,    10,     0,     0,    94,    83,    84,    95,    85,     0,
-      96,    97,     0,    86,     0,     0,     0,     0,   204,    87,
-      98,     0,    88,     0,     0,     0,    99,     0,     0,     0,
-       0,   100,     0,     0,     0,     0,    89,    90,     0,     0,
-       0,     0,     0,     0,    91,     0,     0,    92,     0,     0,
+      36,   221,   312,   220,   218,    48,   247,    45,    49,   107,
+     255,   372,   218,    33,   346,    34,    33,   358,    34,   359,
+      56,   193,    33,    33,    34,    34,   140,   134,    63,   297,
+      56,   297,   186,    68,    69,    70,    71,    72,   527,   292,
+     360,   337,    33,   297,    34,   152,   299,   300,   301,   302,
+     303,   304,   305,   306,   307,   308,   161,   171,   172,   131,
+     297,   326,   295,   176,   177,   243,   166,   171,   172,   553,
+     462,   218,   148,   218,   273,    42,   171,   172,    67,   361,
+     247,   132,   528,   336,   171,   172,    37,   473,   171,   172,
+      60,   534,   181,    61,   474,    56,   397,   436,   205,    32,
+     437,   438,    39,   175,    10,   551,    43,   249,   294,   362,
+     363,    41,   133,   554,   225,   309,    48,   225,   190,    49,
+     228,   195,   146,   197,   535,   552,   267,   238,   200,   201,
+      64,    38,   182,   338,   147,   107,    10,   206,   209,   243,
+     240,    40,   364,   195,   135,   136,   454,   257,   463,   368,
+     187,   405,   264,   187,   415,   271,    10,   242,   218,   218,
+     365,   446,   485,   529,   248,   375,   242,   258,   196,   251,
+     386,   467,   477,   247,   471,   418,   256,   296,   315,   259,
+     439,   398,   260,   456,   510,   241,     1,   316,     2,   151,
+     319,   178,   222,   403,   555,   241,   209,   272,   279,   280,
+     287,   222,   428,   492,   461,   376,   395,    57,    66,   202,
+     203,   431,   143,   218,    33,    50,    34,     3,   274,   171,
+     172,   433,    53,   266,    33,    62,    34,   264,    51,   330,
+      52,    59,   243,   350,     4,     5,   331,   230,   248,    49,
+     312,   377,     6,    49,   275,   332,   453,     7,   389,   390,
+     391,   378,   247,   327,   507,    54,    27,   122,   171,   172,
+      35,   231,   190,   123,    64,   125,   351,     8,   333,   124,
+     468,   324,    10,   393,   127,   396,   232,   233,   276,   533,
+     402,   218,    55,   366,   370,   478,   479,   209,   407,   452,
+     379,    10,   137,     9,   130,   489,   482,   171,   172,   139,
+     234,   380,   491,    10,   409,   277,   218,   381,   142,   126,
+     392,   243,   141,   427,   171,   172,   143,   406,   155,    11,
+     410,   149,   156,    49,   150,   235,    12,   330,   382,    13,
+     157,   248,   171,   172,   331,    49,   171,   172,   158,  -138,
+     269,   270,   159,   332,    33,   524,    34,   516,   321,   290,
+     291,   195,   162,   287,   314,   270,   450,   163,   218,   264,
+     167,   195,    33,   164,    34,   168,   333,   170,   458,   525,
+     347,   348,   356,   357,   180,    78,    79,   448,   183,   171,
+     172,   399,   400,   192,   264,    82,   199,   264,   426,   348,
+     204,   173,    83,    84,   229,    85,   434,   435,   480,   270,
+      86,   481,   270,   494,   348,   558,   505,   270,   219,    88,
+     248,   506,   270,   563,   513,   348,   264,   239,   493,   514,
+     400,   532,   357,    89,   254,   195,   195,   548,   357,   564,
+     270,   370,    92,   566,   270,   268,   288,   503,   297,   311,
+     298,    33,    73,    34,    74,   320,   322,   323,   325,   342,
+     335,    94,   340,   345,   352,   353,   512,   354,    75,    76,
+     261,    95,   371,   503,   355,   401,   394,    97,    98,   404,
+     408,   411,    78,    79,   414,   412,   413,    99,   416,   287,
+      80,    81,    82,   100,   417,   419,   511,   422,   503,    83,
+      84,   420,    85,   423,   424,   186,   262,    86,   429,   430,
+     442,   444,   441,    87,   287,   445,    88,   447,   451,   457,
+     455,   459,   460,   465,   472,   538,   466,   469,   486,   487,
+      89,    90,   496,   497,   498,   499,    91,   547,   483,    92,
+     490,   504,    93,   348,   508,   299,   300,   301,   302,   303,
+     304,   305,   306,   307,   308,   195,   171,   172,    94,   509,
+     515,   518,   523,   195,   531,   541,   519,   537,    95,   543,
+     544,    96,   545,   546,    97,    98,    33,    73,    34,    74,
+     549,   550,   210,   560,    99,   557,   559,   567,   561,   562,
+     100,   568,   569,    75,    76,   101,   263,   449,   349,   128,
+     432,   198,   191,   129,   464,   539,   250,    78,    79,   517,
+     565,   540,   387,   293,   309,    80,    81,    82,   388,   252,
+     185,   226,   253,   317,    83,    84,   495,    85,     0,   318,
+     237,     0,    86,     0,     0,     0,     0,   211,    87,     0,
+       0,    88,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    89,    90,     0,     0,     0,
+       0,    91,     0,     0,    92,     0,     0,    93,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    94,     0,    33,    73,    34,    74,     0,
+      10,   210,     0,    95,     0,     0,    96,     0,     0,    97,
+      98,     0,    75,    76,     0,     0,     0,     0,     0,    99,
+       0,     0,     0,     0,     0,   100,    78,    79,     0,     0,
+     212,     0,     0,     0,    80,    81,    82,     0,     0,     0,
+       0,     0,     0,    83,    84,     0,    85,     0,     0,     0,
+       0,    86,     0,     0,     0,     0,   211,    87,     0,     0,
+      88,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    89,    90,     0,     0,     0,     0,
+      91,     0,     0,    92,     0,     0,    93,     0,     0,     0,
        0,     0,    33,    73,    34,    74,     0,     0,     0,     0,
-       0,     0,    93,     0,     0,     0,     0,     0,     0,    75,
-     177,     0,    94,     0,     0,    95,     0,     0,    96,    97,
-       0,     0,     0,    78,    79,     0,     0,     0,    98,     0,
-       0,    80,    81,    82,    99,     0,     0,     0,     0,   205,
+       0,     0,    94,     0,     0,     0,     0,     0,     0,    75,
+      76,    77,    95,     0,     0,    96,     0,     0,    97,    98,
+       0,     0,     0,    78,    79,     0,     0,     0,    99,     0,
+       0,    80,    81,    82,   100,     0,     0,     0,     0,   212,
       83,    84,     0,    85,     0,     0,     0,     0,    86,     0,
        0,     0,     0,     0,    87,     0,     0,    88,     0,     0,
-      33,    73,    34,    74,     0,     0,     0,     0,     0,     0,
-       0,    89,    90,     0,     0,     0,     0,    75,    76,    91,
-       0,     0,    92,     0,     0,     0,     0,     0,     0,     0,
-       0,    78,    79,     0,     0,     0,     0,    93,     0,    80,
-      81,    82,     0,     0,     0,     0,     0,    94,    83,    84,
-      95,    85,     0,    96,    97,     0,    86,     0,     0,     0,
-       0,     0,    87,    98,     0,    88,     0,     0,     0,    99,
-       0,     0,     0,     0,   100,     0,     0,     0,     0,    89,
-      90,     0,     0,     0,     0,     0,    73,    91,    74,     0,
-      92,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    75,   177,     0,    93,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    94,    78,    79,    95,     0,
-       0,    96,    97,     0,     0,     0,    82,     0,     0,     0,
-       0,    98,     0,    83,    84,     0,    85,    99,     0,     0,
-       0,    86,   100,     0,     0,     0,     0,     0,     0,     0,
-      88,   291,   292,   293,   294,   295,   296,   297,   298,   299,
-     300,     0,   166,   167,    89,    90,     0,     0,     0,     0,
-       0,     0,    91,     0,     0,    92,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      94,     0,     0,     0,     0,     0,    96,    97,     0,     0,
-       0,     0,     0,     0,     0,     0,    98,     0,     0,     0,
-     301,     0,    99
+       0,    89,    90,     0,     0,     0,     0,    91,     0,     0,
+      92,     0,     0,    93,     0,     0,     0,     0,     0,    33,
+      73,    34,    74,     0,     0,     0,     0,     0,     0,    94,
+       0,     0,     0,     0,     0,     0,    75,    76,     0,    95,
+       0,     0,    96,     0,     0,    97,    98,     0,     0,     0,
+      78,    79,     0,     0,     0,    99,     0,     0,    80,    81,
+      82,   100,     0,     0,     0,     0,   101,    83,    84,     0,
+      85,     0,     0,     0,     0,    86,     0,     0,     0,     0,
+       0,    87,     0,     0,    88,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    89,    90,
+       0,     0,     0,     0,    91,     0,     0,    92,     0,     0,
+      93,     0,     0,     0,     0,     0,    33,    73,    34,    74,
+       0,     0,     0,     0,     0,     0,    94,     0,     0,     0,
+       0,     0,     0,    75,    76,     0,    95,     0,     0,    96,
+       0,     0,    97,    98,     0,     0,     0,    78,    79,     0,
+       0,     0,    99,   151,     0,    80,    81,    82,   100,     0,
+       0,     0,     0,   101,    83,    84,     0,    85,     0,     0,
+       0,     0,    86,     0,     0,     0,     0,     0,    87,     0,
+       0,    88,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    89,    90,     0,     0,     0,
+       0,    91,     0,     0,    92,     0,     0,    93,     0,     0,
+       0,     0,     0,    33,    73,    34,    74,     0,     0,     0,
+       0,     0,   160,    94,     0,     0,     0,     0,     0,     0,
+      75,    76,     0,    95,     0,     0,    96,     0,     0,    97,
+      98,     0,     0,     0,    78,    79,     0,     0,     0,    99,
+       0,     0,    80,    81,    82,   100,     0,     0,     0,     0,
+     101,    83,    84,     0,    85,     0,     0,     0,     0,    86,
+       0,     0,     0,     0,     0,    87,     0,     0,    88,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    89,    90,     0,     0,     0,     0,    91,     0,
+       0,    92,     0,     0,    93,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      94,     0,    33,    73,    34,    74,     0,    10,     0,     0,
+      95,     0,     0,    96,     0,     0,    97,    98,     0,    75,
+      76,     0,     0,     0,     0,     0,    99,     0,     0,     0,
+       0,     0,   100,    78,    79,     0,     0,   101,     0,     0,
+       0,    80,    81,    82,     0,     0,     0,     0,     0,     0,
+      83,    84,     0,    85,     0,     0,     0,     0,    86,     0,
+       0,     0,     0,   211,    87,     0,     0,    88,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    89,    90,     0,     0,     0,     0,    91,     0,     0,
+      92,     0,     0,    93,     0,     0,     0,     0,     0,    33,
+      73,    34,    74,     0,     0,     0,     0,     0,     0,    94,
+       0,     0,     0,     0,     0,     0,    75,   184,     0,    95,
+       0,     0,    96,     0,     0,    97,    98,     0,     0,     0,
+      78,    79,     0,     0,     0,    99,     0,     0,    80,    81,
+      82,   100,     0,     0,     0,     0,   212,    83,    84,     0,
+      85,     0,     0,     0,     0,    86,     0,     0,     0,     0,
+       0,    87,     0,     0,    88,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    89,    90,
+       0,     0,     0,     0,    91,     0,     0,    92,     0,     0,
+      93,     0,     0,     0,     0,     0,    33,    73,    34,    74,
+       0,     0,     0,     0,     0,     0,    94,     0,     0,     0,
+       0,     0,     0,    75,    76,     0,    95,     0,     0,    96,
+       0,     0,    97,    98,     0,     0,     0,    78,    79,     0,
+       0,     0,    99,     0,     0,    80,    81,    82,   100,     0,
+       0,     0,     0,   101,    83,    84,     0,    85,     0,     0,
+       0,     0,    86,     0,     0,     0,     0,     0,    87,     0,
+       0,    88,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    89,    90,    73,     0,    74,
+       0,    91,     0,     0,    92,     0,     0,    93,     0,     0,
+       0,     0,     0,    75,   184,     0,     0,     0,     0,     0,
+       0,     0,     0,    94,     0,     0,     0,    78,    79,     0,
+       0,     0,     0,    95,     0,     0,    96,    82,     0,    97,
+      98,     0,     0,     0,    83,    84,     0,    85,     0,    99,
+       0,     0,    86,     0,     0,   100,     0,     0,     0,     0,
+     101,    88,     0,     0,     0,     0,     0,     0,    78,    79,
+       0,     0,     0,     0,     0,    89,    90,     0,    82,     0,
+       0,     0,     0,     0,    92,    83,    84,    93,    85,     0,
+       0,     0,     0,    86,     0,     0,     0,     0,     0,     0,
+       0,     0,    88,    94,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    95,     0,     0,    89,   254,     0,    97,
+      98,     0,     0,     0,     0,    92,     0,     0,     0,    99,
+       0,     0,     0,     0,     0,   100,     0,     0,     0,     0,
+       0,     0,     0,     0,    94,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    95,     0,     0,     0,     0,     0,
+      97,    98,     0,     0,     0,     0,     0,     0,     0,     0,
+      99,     0,     0,     0,     0,     0,   100
 };
 
 static const yytype_int16 yycheck[] =
 {
-       4,    12,   163,   282,   144,   148,   140,    11,    12,    44,
-     121,     4,     8,     6,   148,   212,     7,   254,     4,     5,
-       6,     7,    27,     4,     8,     6,    36,     4,    32,     6,
-     175,    59,    29,    37,    38,    39,    40,    41,   240,     8,
-      29,     8,    28,   123,    72,    80,    21,    22,    63,    71,
-      23,    24,   163,    21,    22,    21,    22,   202,   193,     7,
-      51,    80,   205,    10,    67,   100,   235,    21,    22,   203,
-      28,   205,     5,     4,   235,     6,    76,    39,    73,   147,
-     148,    67,   116,    10,    11,    12,    13,    14,    15,    16,
-      17,    18,    19,   204,    21,    22,    21,    22,   123,    29,
-     134,    59,   106,    51,   123,    31,   475,    68,   108,   120,
-      96,    97,   146,   123,    73,   119,   120,   152,   122,    73,
-     124,   136,   157,   116,   235,   147,   164,    88,    85,   331,
-     165,   500,   127,   136,   138,   139,    62,     0,   127,   130,
-     144,   146,   128,   181,    30,   180,   280,    94,   283,   386,
-     147,   147,    79,   146,   433,   289,   290,   124,   327,   163,
-     146,   136,   190,   147,   168,   146,   327,   129,   313,   146,
-     205,   175,   176,   370,   411,   179,   149,   414,   147,   147,
-     215,   147,   130,   218,   146,   116,   189,   120,   121,   193,
-     301,   195,   196,   197,     4,   392,     6,   137,    74,   124,
-      54,   344,    47,    48,    10,    81,   443,   347,   148,   139,
-     344,    46,    63,    89,    21,    22,   327,   357,     3,   254,
-     147,     9,    49,    33,    78,   260,    37,    34,   117,    40,
-      41,   235,   236,    21,    22,   111,   240,    72,    92,    93,
-      46,    21,    22,   108,     9,   406,     4,   148,     6,   114,
-      56,    58,   449,    33,   258,    82,    21,    22,   262,   147,
-     148,   115,    17,    18,    19,   300,    33,   302,   146,   412,
-     105,   147,   307,   384,   142,   279,   280,   145,   412,   283,
-     315,   421,   422,    47,    48,   136,   140,     0,    94,   116,
-     142,     4,   144,   427,   437,   406,   131,   147,   148,   105,
-      21,    22,   116,   437,   110,   340,    85,   118,   319,   313,
-     147,   148,   106,    26,   139,   319,   147,   148,     4,     1,
-       6,     3,    74,   327,    79,   131,     5,   331,    97,    81,
-     147,   148,   147,   148,    86,    21,    22,    89,   147,   148,
-      53,   146,   137,   347,     7,   349,   489,    33,   383,     7,
-      32,   386,    84,   357,   146,   489,   147,   148,     5,   111,
-     395,   147,   148,   147,   148,   147,   148,    49,    50,   373,
-     147,   148,   147,   148,   146,    57,   411,   147,   148,   414,
-      62,   147,   148,    84,   147,   148,   147,   148,   147,   148,
-     146,     5,   146,   146,    61,    73,     4,     5,     6,     7,
-      82,   541,   406,   148,   100,   146,     7,   146,   443,   549,
-     445,   146,     7,    21,    22,    23,     7,   421,   422,    11,
-     146,     8,    20,   427,     9,   107,    64,    35,    36,   464,
-     147,    73,   147,   101,   116,    43,    44,    45,   148,    75,
-     147,   146,    87,    87,    52,    53,   146,    55,   483,   133,
-     132,    59,    60,   146,   134,   490,     7,   139,    66,    64,
-     142,    69,    99,    86,    99,    99,     7,     7,    42,    42,
-      77,   475,   147,    98,   146,    83,    84,   146,   482,    27,
-     515,    94,   148,    91,   139,   146,    94,    87,    94,   146,
-     146,   103,   103,   147,   147,    98,   500,    42,   146,    38,
-     146,   109,   101,     4,     5,     6,     7,   511,     7,    10,
-      42,   119,    90,    97,   122,   148,    19,   125,   126,   523,
-      21,    22,   146,    42,     7,   147,   147,   135,   138,   148,
-     110,    95,   104,   141,    35,    36,   112,   541,   146,   147,
-       9,   104,    43,    44,    45,   549,    33,    70,    70,   146,
-     146,    52,    53,   146,    55,   112,   102,   147,     7,    60,
-     376,   258,   349,    55,    65,    66,   120,   126,    69,   513,
-      56,     4,     5,     6,     7,   551,   165,    10,   406,   490,
-     515,   289,    83,    84,   290,   203,   169,   117,    21,    22,
-      91,   156,   174,    94,   150,    -1,   216,    -1,    -1,   216,
-     449,    -1,    35,    36,    -1,    -1,    -1,    -1,   109,    -1,
-      43,    44,    45,    -1,    -1,   116,    -1,    -1,   119,    52,
-      53,   122,    55,    -1,   125,   126,    -1,    60,    -1,    -1,
-      -1,    -1,    65,    66,   135,    -1,    69,    -1,    -1,     4,
-     141,     6,    -1,    -1,    -1,   146,    -1,    -1,    -1,    -1,
-      83,    84,    -1,    -1,    -1,    -1,    -1,    -1,    91,    -1,
-      -1,    94,    -1,    -1,    -1,    -1,     4,     5,     6,     7,
-      35,    36,    -1,    -1,    -1,    -1,   109,    -1,    -1,    -1,
-      45,    -1,    -1,    21,    22,    23,   119,    52,    53,   122,
-      55,    -1,   125,   126,    -1,    60,    -1,    35,    36,    -1,
-      -1,    -1,   135,    -1,    69,    43,    44,    45,   141,    -1,
-      -1,    -1,    -1,   146,    52,    53,    -1,    55,    83,    84,
-      -1,    -1,    60,    -1,    -1,    -1,    91,    -1,    66,    -1,
-      -1,    69,    -1,    -1,     4,     5,     6,     7,    -1,    -1,
-      -1,    -1,    -1,    -1,   109,    83,    84,    -1,    -1,    -1,
-      -1,    21,    22,    91,   119,    -1,    94,    -1,    -1,    -1,
-     125,   126,    -1,    -1,    -1,    35,    36,    -1,    -1,    -1,
-     135,   109,    -1,    43,    44,    45,   141,    -1,    -1,    -1,
-      -1,   119,    52,    53,   122,    55,    -1,   125,   126,    -1,
-      60,    -1,    -1,    -1,    -1,    -1,    66,   135,    -1,    69,
-      -1,    -1,    -1,   141,    -1,    -1,    -1,    -1,   146,    -1,
-      -1,    -1,    -1,    83,    84,    -1,    -1,    -1,    -1,    -1,
-      -1,    91,    -1,    -1,    94,    -1,    -1,    -1,    -1,     4,
-       5,     6,     7,    35,    36,    -1,    -1,    -1,    -1,   109,
-      -1,    -1,    -1,    45,    -1,    -1,    21,    22,    -1,   119,
-      52,    53,   122,    55,    -1,   125,   126,    -1,    60,    -1,
-      35,    36,    -1,    -1,    -1,   135,   136,    69,    43,    44,
-      45,   141,    -1,    -1,    -1,    -1,   146,    52,    53,    -1,
-      55,    83,    84,    -1,    -1,    60,    -1,    -1,    -1,    91,
-      -1,    66,    -1,    -1,    69,    -1,    -1,     4,     5,     6,
-       7,    -1,    -1,    -1,    -1,    -1,    -1,   109,    83,    84,
-      -1,    -1,    -1,    -1,    21,    22,    91,   119,    -1,    94,
-      -1,    -1,    -1,   125,   126,    -1,    -1,    -1,    35,    36,
-      -1,    -1,    -1,   135,   109,    -1,    43,    44,    45,   141,
-      -1,   116,    -1,    -1,   119,    52,    53,   122,    55,    -1,
-     125,   126,    -1,    60,    -1,    -1,    -1,    -1,    65,    66,
-     135,    -1,    69,    -1,    -1,    -1,   141,    -1,    -1,    -1,
-      -1,   146,    -1,    -1,    -1,    -1,    83,    84,    -1,    -1,
-      -1,    -1,    -1,    -1,    91,    -1,    -1,    94,    -1,    -1,
+       4,   151,   219,   147,   143,    12,   168,    11,    12,    44,
+     180,   290,   151,     4,   262,     6,     4,     5,     6,     7,
+      29,   124,     4,     4,     6,     6,    67,     5,    32,     8,
+      29,     8,    27,    37,    38,    39,    40,    41,     7,   209,
+      28,    39,     4,     8,     6,    80,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    91,    21,    22,    59,
+       8,   242,   212,    23,    24,   168,   101,    21,    22,     7,
+      71,   210,    72,   212,   200,    28,    21,    22,    36,    67,
+     242,    31,    51,   247,    21,    22,    80,   109,    21,    22,
+     144,    76,   110,   147,   116,    29,    10,    37,   139,   125,
+      40,    41,    73,   107,   118,    68,    59,   169,   211,    97,
+      98,    85,    62,    51,    63,    79,   123,    63,   122,   123,
+     155,   125,   136,   127,   109,    88,   188,   162,    47,    48,
+     129,   125,   150,   131,   148,   170,   118,   141,   142,   242,
+     149,   125,   130,   147,   122,   123,   394,   182,   149,   288,
+     148,   321,   187,   148,   335,   196,   118,   148,   297,   298,
+     148,   378,   441,   132,   168,   291,   148,   148,   126,   173,
+     149,   419,   149,   335,   422,   339,   180,   212,   126,   183,
+     120,    95,   186,   400,   149,   149,     1,   222,     3,   138,
+     225,   151,   138,   126,   132,   149,   200,   197,   202,   203,
+     204,   138,   352,   451,   149,    10,   309,   141,    73,    47,
+      48,   355,   139,   352,     4,     0,     6,    32,    46,    21,
+      22,   365,    49,   150,     4,     3,     6,   262,   144,    74,
+     146,    30,   335,   268,    49,    50,    81,    54,   242,   243,
+     457,    46,    57,   247,    72,    90,     9,    62,    17,    18,
+      19,    56,   414,    33,   483,    82,     0,   119,    21,    22,
+       4,    78,   266,   150,   129,   148,   270,    82,   113,    33,
+     420,    73,   118,   308,    85,   310,    93,    94,   106,   508,
+     315,   420,    26,   287,   288,   429,   430,   291,   323,   392,
+      95,   118,   141,   108,   107,   445,   435,    21,    22,     5,
+     117,   106,     9,   118,   149,   133,   445,   112,   148,    53,
+      79,   414,    98,   348,    21,    22,   139,   321,   148,   134,
+     327,     7,   148,   327,     7,   142,   141,    74,   133,   144,
+      84,   335,    21,    22,    81,   339,    21,    22,   148,    86,
+     149,   150,     5,    90,     4,    34,     6,   497,    33,   149,
+     150,   355,   148,   357,   149,   150,   391,   148,   497,   394,
+       5,   365,     4,    84,     6,    73,   113,   150,   403,    58,
+     149,   150,   149,   150,    61,    35,    36,   381,   101,    21,
+      22,   149,   150,   148,   419,    45,     7,   422,   149,   150,
+     148,    33,    52,    53,     7,    55,   149,   150,   149,   150,
+      60,   149,   150,   149,   150,   549,   149,   150,   148,    69,
+     414,   149,   150,   557,   149,   150,   451,     7,   453,   149,
+     150,   149,   150,    83,    84,   429,   430,   149,   150,   149,
+     150,   435,    92,   149,   150,    11,   148,   472,     8,    20,
+       9,     4,     5,     6,     7,    64,   149,    73,   149,   102,
+     150,   111,    75,   149,   148,    87,   491,    87,    21,    22,
+      23,   121,   135,   498,   148,   136,   148,   127,   128,    64,
+       7,   100,    35,    36,    86,   100,   100,   137,     7,   483,
+      43,    44,    45,   143,     7,    42,   490,    42,   523,    52,
+      53,    77,    55,   149,    99,    27,    59,    60,   148,   148,
+     141,    95,   150,    66,   508,   148,    69,    87,   148,   148,
+      95,   149,   149,   104,    42,   519,   104,    99,    38,   102,
+      83,    84,     7,    98,    42,    91,    89,   531,   148,    92,
+     148,    19,    95,   150,   148,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,   549,    21,    22,   111,    42,
+     149,     7,   150,   557,   112,    96,   140,   149,   121,   105,
+     114,   124,   105,     9,   127,   128,     4,     5,     6,     7,
+     148,    33,    10,    70,   137,   148,   148,   103,   114,    70,
+     143,   149,     7,    21,    22,   148,   149,   384,   266,    55,
+     357,   129,   123,    56,   414,   521,   170,    35,    36,   498,
+     559,   523,   297,   210,    79,    43,    44,    45,   298,   174,
+     120,   153,   179,   223,    52,    53,   457,    55,    -1,   223,
+     159,    -1,    60,    -1,    -1,    -1,    -1,    65,    66,    -1,
+      -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    83,    84,    -1,    -1,    -1,
+      -1,    89,    -1,    -1,    92,    -1,    -1,    95,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   111,    -1,     4,     5,     6,     7,    -1,
+     118,    10,    -1,   121,    -1,    -1,   124,    -1,    -1,   127,
+     128,    -1,    21,    22,    -1,    -1,    -1,    -1,    -1,   137,
+      -1,    -1,    -1,    -1,    -1,   143,    35,    36,    -1,    -1,
+     148,    -1,    -1,    -1,    43,    44,    45,    -1,    -1,    -1,
+      -1,    -1,    -1,    52,    53,    -1,    55,    -1,    -1,    -1,
+      -1,    60,    -1,    -1,    -1,    -1,    65,    66,    -1,    -1,
+      69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    83,    84,    -1,    -1,    -1,    -1,
+      89,    -1,    -1,    92,    -1,    -1,    95,    -1,    -1,    -1,
       -1,    -1,     4,     5,     6,     7,    -1,    -1,    -1,    -1,
-      -1,    -1,   109,    -1,    -1,    -1,    -1,    -1,    -1,    21,
-      22,    -1,   119,    -1,    -1,   122,    -1,    -1,   125,   126,
-      -1,    -1,    -1,    35,    36,    -1,    -1,    -1,   135,    -1,
-      -1,    43,    44,    45,   141,    -1,    -1,    -1,    -1,   146,
+      -1,    -1,   111,    -1,    -1,    -1,    -1,    -1,    -1,    21,
+      22,    23,   121,    -1,    -1,   124,    -1,    -1,   127,   128,
+      -1,    -1,    -1,    35,    36,    -1,    -1,    -1,   137,    -1,
+      -1,    43,    44,    45,   143,    -1,    -1,    -1,    -1,   148,
       52,    53,    -1,    55,    -1,    -1,    -1,    -1,    60,    -1,
       -1,    -1,    -1,    -1,    66,    -1,    -1,    69,    -1,    -1,
-       4,     5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    83,    84,    -1,    -1,    -1,    -1,    21,    22,    91,
-      -1,    -1,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    35,    36,    -1,    -1,    -1,    -1,   109,    -1,    43,
-      44,    45,    -1,    -1,    -1,    -1,    -1,   119,    52,    53,
-     122,    55,    -1,   125,   126,    -1,    60,    -1,    -1,    -1,
-      -1,    -1,    66,   135,    -1,    69,    -1,    -1,    -1,   141,
-      -1,    -1,    -1,    -1,   146,    -1,    -1,    -1,    -1,    83,
-      84,    -1,    -1,    -1,    -1,    -1,     5,    91,     7,    -1,
-      94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    21,    22,    -1,   109,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,   119,    35,    36,   122,    -1,
-      -1,   125,   126,    -1,    -1,    -1,    45,    -1,    -1,    -1,
-      -1,   135,    -1,    52,    53,    -1,    55,   141,    -1,    -1,
-      -1,    60,   146,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      69,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    -1,    21,    22,    83,    84,    -1,    -1,    -1,    -1,
-      -1,    -1,    91,    -1,    -1,    94,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     109,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     119,    -1,    -1,    -1,    -1,    -1,   125,   126,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,   135,    -1,    -1,    -1,
-      79,    -1,   141
+      -1,    83,    84,    -1,    -1,    -1,    -1,    89,    -1,    -1,
+      92,    -1,    -1,    95,    -1,    -1,    -1,    -1,    -1,     4,
+       5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,   111,
+      -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    -1,   121,
+      -1,    -1,   124,    -1,    -1,   127,   128,    -1,    -1,    -1,
+      35,    36,    -1,    -1,    -1,   137,    -1,    -1,    43,    44,
+      45,   143,    -1,    -1,    -1,    -1,   148,    52,    53,    -1,
+      55,    -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,
+      -1,    66,    -1,    -1,    69,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    83,    84,
+      -1,    -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,
+      95,    -1,    -1,    -1,    -1,    -1,     4,     5,     6,     7,
+      -1,    -1,    -1,    -1,    -1,    -1,   111,    -1,    -1,    -1,
+      -1,    -1,    -1,    21,    22,    -1,   121,    -1,    -1,   124,
+      -1,    -1,   127,   128,    -1,    -1,    -1,    35,    36,    -1,
+      -1,    -1,   137,   138,    -1,    43,    44,    45,   143,    -1,
+      -1,    -1,    -1,   148,    52,    53,    -1,    55,    -1,    -1,
+      -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,    66,    -1,
+      -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    83,    84,    -1,    -1,    -1,
+      -1,    89,    -1,    -1,    92,    -1,    -1,    95,    -1,    -1,
+      -1,    -1,    -1,     4,     5,     6,     7,    -1,    -1,    -1,
+      -1,    -1,   110,   111,    -1,    -1,    -1,    -1,    -1,    -1,
+      21,    22,    -1,   121,    -1,    -1,   124,    -1,    -1,   127,
+     128,    -1,    -1,    -1,    35,    36,    -1,    -1,    -1,   137,
+      -1,    -1,    43,    44,    45,   143,    -1,    -1,    -1,    -1,
+     148,    52,    53,    -1,    55,    -1,    -1,    -1,    -1,    60,
+      -1,    -1,    -1,    -1,    -1,    66,    -1,    -1,    69,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    83,    84,    -1,    -1,    -1,    -1,    89,    -1,
+      -1,    92,    -1,    -1,    95,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     111,    -1,     4,     5,     6,     7,    -1,   118,    -1,    -1,
+     121,    -1,    -1,   124,    -1,    -1,   127,   128,    -1,    21,
+      22,    -1,    -1,    -1,    -1,    -1,   137,    -1,    -1,    -1,
+      -1,    -1,   143,    35,    36,    -1,    -1,   148,    -1,    -1,
+      -1,    43,    44,    45,    -1,    -1,    -1,    -1,    -1,    -1,
+      52,    53,    -1,    55,    -1,    -1,    -1,    -1,    60,    -1,
+      -1,    -1,    -1,    65,    66,    -1,    -1,    69,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    83,    84,    -1,    -1,    -1,    -1,    89,    -1,    -1,
+      92,    -1,    -1,    95,    -1,    -1,    -1,    -1,    -1,     4,
+       5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,   111,
+      -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    -1,   121,
+      -1,    -1,   124,    -1,    -1,   127,   128,    -1,    -1,    -1,
+      35,    36,    -1,    -1,    -1,   137,    -1,    -1,    43,    44,
+      45,   143,    -1,    -1,    -1,    -1,   148,    52,    53,    -1,
+      55,    -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,
+      -1,    66,    -1,    -1,    69,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    83,    84,
+      -1,    -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,
+      95,    -1,    -1,    -1,    -1,    -1,     4,     5,     6,     7,
+      -1,    -1,    -1,    -1,    -1,    -1,   111,    -1,    -1,    -1,
+      -1,    -1,    -1,    21,    22,    -1,   121,    -1,    -1,   124,
+      -1,    -1,   127,   128,    -1,    -1,    -1,    35,    36,    -1,
+      -1,    -1,   137,    -1,    -1,    43,    44,    45,   143,    -1,
+      -1,    -1,    -1,   148,    52,    53,    -1,    55,    -1,    -1,
+      -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,    66,    -1,
+      -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    83,    84,     5,    -1,     7,
+      -1,    89,    -1,    -1,    92,    -1,    -1,    95,    -1,    -1,
+      -1,    -1,    -1,    21,    22,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   111,    -1,    -1,    -1,    35,    36,    -1,
+      -1,    -1,    -1,   121,    -1,    -1,   124,    45,    -1,   127,
+     128,    -1,    -1,    -1,    52,    53,    -1,    55,    -1,   137,
+      -1,    -1,    60,    -1,    -1,   143,    -1,    -1,    -1,    -1,
+     148,    69,    -1,    -1,    -1,    -1,    -1,    -1,    35,    36,
+      -1,    -1,    -1,    -1,    -1,    83,    84,    -1,    45,    -1,
+      -1,    -1,    -1,    -1,    92,    52,    53,    95,    55,    -1,
+      -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    69,   111,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   121,    -1,    -1,    83,    84,    -1,   127,
+     128,    -1,    -1,    -1,    -1,    92,    -1,    -1,    -1,   137,
+      -1,    -1,    -1,    -1,    -1,   143,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   111,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   121,    -1,    -1,    -1,    -1,    -1,
+     127,   128,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     137,    -1,    -1,    -1,    -1,    -1,   143
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint16 yystos[] =
 {
-       0,     1,     3,    32,    49,    50,    57,    62,    82,   107,
-     116,   132,   139,   142,   151,   152,   153,   154,   155,   156,
-     157,   179,   180,   183,   184,   187,   189,   192,   193,   194,
-     259,   260,   123,     4,     6,   192,   257,    80,   123,    73,
-     123,    85,    28,    59,   195,   257,   190,   191,   206,   257,
-       0,   142,   144,    49,    82,   192,    29,   139,   188,    30,
-     142,   145,     3,   257,   127,   181,    73,   181,   257,   257,
-     257,   257,   257,     5,     7,    21,    22,    23,    35,    36,
+       0,     1,     3,    32,    49,    50,    57,    62,    82,   108,
+     118,   134,   141,   144,   153,   154,   155,   156,   157,   158,
+     159,   181,   182,   185,   186,   189,   191,   194,   195,   196,
+     263,   264,   125,     4,     6,   194,   261,    80,   125,    73,
+     125,    85,    28,    59,   197,   261,   192,   193,   208,   261,
+       0,   144,   146,    49,    82,   194,    29,   141,   190,    30,
+     144,   147,     3,   261,   129,   183,    73,   183,   261,   261,
+     261,   261,   261,     5,     7,    21,    22,    23,    35,    36,
       43,    44,    45,    52,    53,    55,    60,    66,    69,    83,
-      84,    91,    94,   109,   119,   122,   125,   126,   135,   141,
-     146,   160,   196,   197,   198,   200,   232,   233,   234,   235,
-     236,   237,   238,   239,   240,   247,   250,   253,   257,   117,
-     148,    33,   146,   192,    85,   188,   195,   106,   194,    31,
-      62,     5,   120,   121,   139,   182,     5,   182,    97,   146,
-     137,   226,   227,   134,   146,   194,     7,     7,   136,   232,
-     243,   244,   146,   146,    84,   146,     5,   146,   146,    84,
-     192,   232,     5,    73,   199,   148,    21,    22,    33,   254,
-     257,    23,    24,   149,   255,    61,   100,    22,   235,    27,
-     146,   185,   186,   257,   191,   146,   200,   256,   257,   181,
-     257,   193,     7,    47,    48,    47,    48,   146,   182,   257,
-     158,   159,   257,    10,    65,   146,   228,   229,   230,   231,
-     232,   250,   146,   256,   228,   136,   241,   242,    63,   244,
-     245,   232,     7,    54,    78,    92,    93,   115,   140,   248,
-     248,   232,     7,   147,   147,   146,   200,   203,   204,   207,
-     236,   257,   226,   198,   257,   233,   234,    84,   160,   257,
-     146,   257,   257,    23,    59,   147,   232,   246,   148,   226,
-      11,   147,   148,   182,   194,   158,    46,    72,   105,   131,
-     164,   257,   257,   171,   172,   173,   174,   175,   176,   257,
-     146,   167,   147,   148,   160,   231,   200,   228,   232,     8,
-       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    79,   252,    20,   247,   249,   147,   124,   232,   242,
-     245,   232,    64,    33,   147,    73,    73,   147,   203,    33,
-     205,   206,    74,    81,    89,   111,   202,   148,   205,    39,
-     129,   201,    75,   208,   101,   215,   216,   147,   246,   147,
-     148,   186,   232,   257,   146,    87,    87,   146,   147,   148,
-       5,     7,    28,    67,    96,    97,   128,   146,   257,   258,
-     250,   251,   257,   133,   164,   165,   166,   158,    10,    46,
-      56,    94,   105,   110,   131,   161,   162,   163,   147,   229,
-     230,    17,    18,    19,    79,   232,   146,   200,   232,    10,
-      94,   147,   148,   134,   232,   124,    64,   160,   257,   232,
-       7,   147,   206,    99,    99,    99,    86,   203,     7,     7,
-     205,    42,    77,   209,    42,   147,    98,   217,   147,   232,
-     228,   146,   146,   256,   172,   256,   147,   148,    37,    40,
-      41,   118,   177,   148,   139,   168,    94,   146,   247,    87,
-     257,   161,   232,   146,   200,     9,   246,    94,   247,   146,
-     232,   147,   147,   147,    71,   147,   204,   103,   103,   246,
-     228,    98,   210,   246,    42,   108,   114,   218,   219,   147,
-     256,   256,   147,   147,   250,   146,   178,   164,    38,   101,
-     169,   228,   146,     9,   246,   232,   147,   249,     7,    97,
-      42,    90,   211,   222,   223,   232,    19,   147,   147,   171,
-     146,    42,   147,   257,   232,   147,   147,   147,   228,   222,
-       7,   138,   212,   213,   214,   148,    34,    58,   224,     7,
-      51,   130,   220,   110,   147,   171,    76,   108,   170,   147,
-     257,   214,   223,    95,   225,   104,   112,   104,     9,   257,
-     147,   146,    33,    68,    88,     7,    51,   130,   221,   146,
-     256,   146,    70,   112,    70,   256,   147,   215,   147,   102,
-     147,     7
+      84,    89,    92,    95,   111,   121,   124,   127,   128,   137,
+     143,   148,   162,   198,   199,   200,   202,   234,   235,   236,
+     237,   238,   239,   240,   241,   242,   243,   244,   251,   254,
+     257,   261,   119,   150,    33,   148,   194,    85,   190,   197,
+     107,   196,    31,    62,     5,   122,   123,   141,   184,     5,
+     184,    98,   148,   139,   228,   229,   136,   148,   196,     7,
+       7,   138,   234,   247,   248,   148,   148,    84,   148,     5,
+     110,   234,   148,   148,    84,   194,   234,     5,    73,   201,
+     150,    21,    22,    33,   258,   261,    23,    24,   151,   259,
+      61,   110,   150,   101,    22,   237,    27,   148,   187,   188,
+     261,   193,   148,   202,   260,   261,   183,   261,   195,     7,
+      47,    48,    47,    48,   148,   184,   261,   160,   161,   261,
+      10,    65,   148,   230,   231,   232,   233,   234,   254,   148,
+     260,   230,   138,   245,   246,    63,   248,   249,   234,     7,
+      54,    78,    93,    94,   117,   142,   252,   252,   234,     7,
+     149,   149,   148,   202,   205,   206,   209,   240,   261,   228,
+     200,   261,   235,   236,    84,   162,   261,   234,   148,   261,
+     261,    23,    59,   149,   234,   250,   150,   228,    11,   149,
+     150,   184,   196,   160,    46,    72,   106,   133,   166,   261,
+     261,   173,   174,   175,   176,   177,   178,   261,   148,   169,
+     149,   150,   162,   233,   202,   230,   234,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    79,
+     256,    20,   251,   253,   149,   126,   234,   246,   249,   234,
+      64,    33,   149,    73,    73,   149,   205,    33,   207,   208,
+      74,    81,    90,   113,   204,   150,   207,    39,   131,   203,
+      75,   210,   102,   217,   218,   149,   250,   149,   150,   188,
+     234,   261,   148,    87,    87,   148,   149,   150,     5,     7,
+      28,    67,    97,    98,   130,   148,   261,   262,   254,   255,
+     261,   135,   166,   167,   168,   160,    10,    46,    56,    95,
+     106,   112,   133,   163,   164,   165,   149,   231,   232,    17,
+      18,    19,    79,   234,   148,   202,   234,    10,    95,   149,
+     150,   136,   234,   126,    64,   162,   261,   234,     7,   149,
+     208,   100,   100,   100,    86,   205,     7,     7,   207,    42,
+      77,   211,    42,   149,    99,   219,   149,   234,   230,   148,
+     148,   260,   174,   260,   149,   150,    37,    40,    41,   120,
+     179,   150,   141,   170,    95,   148,   251,    87,   261,   163,
+     234,   148,   202,     9,   250,    95,   251,   148,   234,   149,
+     149,   149,    71,   149,   206,   104,   104,   250,   230,    99,
+     212,   250,    42,   109,   116,   220,   221,   149,   260,   260,
+     149,   149,   254,   148,   180,   166,    38,   102,   171,   230,
+     148,     9,   250,   234,   149,   253,     7,    98,    42,    91,
+     213,   224,   225,   234,    19,   149,   149,   173,   148,    42,
+     149,   261,   234,   149,   149,   149,   230,   224,     7,   140,
+     214,   215,   216,   150,    34,    58,   226,     7,    51,   132,
+     222,   112,   149,   173,    76,   109,   172,   149,   261,   216,
+     225,    96,   227,   105,   114,   105,     9,   261,   149,   148,
+      33,    68,    88,     7,    51,   132,   223,   148,   260,   148,
+      70,   114,    70,   260,   149,   217,   149,   103,   149,     7
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint16 yyr1[] =
 {
-       0,   150,   151,   151,   151,   151,   151,   151,   152,   152,
-     152,   152,   152,   152,   152,   152,   152,   152,   153,   154,
-     154,   154,   154,   155,   156,   157,   158,   159,   159,   160,
-     160,   160,   160,   160,   160,   160,   160,   160,   160,   160,
-     160,   160,   160,   160,   160,   160,   160,   161,   161,   161,
-     161,   161,   161,   161,   162,   162,   163,   163,   164,   164,
-     164,   164,   165,   165,   166,   166,   167,   167,   168,   168,
-     169,   169,   170,   170,   171,   171,   172,   172,   172,   172,
-     173,   173,   173,   174,   175,   176,   177,   177,   177,   177,
-     178,   178,   179,   179,   179,   179,   180,   180,   180,   180,
-     181,   181,   181,   182,   182,   183,   184,   185,   185,   186,
-     187,   187,   188,   188,   189,   190,   190,   191,   192,   192,
-     193,   193,   194,   195,   195,   195,   196,   196,   197,   197,
-     198,   198,   198,   199,   200,   201,   201,   201,   202,   202,
-     202,   202,   202,   202,   202,   202,   203,   203,   204,   204,
-     204,   204,   204,   204,   205,   205,   206,   206,   207,   207,
-     208,   208,   209,   209,   210,   210,   211,   211,   212,   212,
-     213,   213,   214,   215,   216,   216,   217,   217,   218,   218,
-     219,   219,   220,   220,   220,   221,   221,   221,   222,   222,
-     223,   224,   224,   224,   225,   225,   225,   226,   226,   227,
-     228,   228,   229,   229,   230,   230,   231,   231,   231,   231,
-     231,   231,   231,   231,   231,   231,   231,   232,   232,   233,
-     233,   234,   234,   235,   235,   235,   235,   235,   235,   235,
-     235,   235,   235,   235,   236,   236,   236,   236,   237,   237,
-     237,   237,   238,   239,   239,   240,   240,   241,   241,   242,
-     243,   243,   244,   245,   245,   246,   246,   247,   247,   247,
-     247,   247,   247,   247,   247,   248,   248,   248,   248,   248,
-     248,   249,   249,   250,   250,   251,   251,   252,   252,   252,
-     252,   252,   252,   252,   252,   252,   252,   253,   254,   254,
-     255,   255,   255,   256,   256,   257,   257,   258,   258,   258,
-     258,   259,   260,   260
+       0,   152,   153,   153,   153,   153,   153,   153,   154,   154,
+     154,   154,   154,   154,   154,   154,   154,   154,   155,   156,
+     156,   156,   156,   157,   158,   159,   160,   161,   161,   162,
+     162,   162,   162,   162,   162,   162,   162,   162,   162,   162,
+     162,   162,   162,   162,   162,   162,   162,   163,   163,   163,
+     163,   163,   163,   163,   164,   164,   165,   165,   166,   166,
+     166,   166,   167,   167,   168,   168,   169,   169,   170,   170,
+     171,   171,   172,   172,   173,   173,   174,   174,   174,   174,
+     175,   175,   175,   176,   177,   178,   179,   179,   179,   179,
+ 

<TRUNCATED>


[09/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/MultiplyBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/MultiplyBinaryOperation.cpp b/types/operations/binary_operations/MultiplyBinaryOperation.cpp
deleted file mode 100644
index a206364..0000000
--- a/types/operations/binary_operations/MultiplyBinaryOperation.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/binary_operations/MultiplyBinaryOperation.hpp"
-
-#include <string>
-#include <utility>
-
-#include "types/DateOperatorOverloads.hpp"
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/IntervalLit.hpp"
-#include "types/LongType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperators.hpp"
-#include "utility/EqualsAnyConstant.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool MultiplyBinaryOperation::canApplyToTypes(const Type &left, const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      return (right.getSuperTypeID() == Type::kNumeric ||
-              right.getTypeID() == kDatetimeInterval   ||
-              right.getTypeID() == kYearMonthInterval);
-    }
-    case kDatetimeInterval:
-    case kYearMonthInterval: {
-      return (right.getSuperTypeID() == Type::kNumeric);
-    }
-    default:
-      return false;
-  }
-}
-
-const Type* MultiplyBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const {
-  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-    return TypeFactory::GetUnifyingType(left, right);
-  } else if ((left.getSuperTypeID() == Type::kNumeric && right.getTypeID() == kDatetimeInterval) ||
-             (left.getTypeID() == kDatetimeInterval && right.getSuperTypeID() == Type::kNumeric)) {
-    return &(DatetimeIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else if ((left.getSuperTypeID() == Type::kNumeric && right.getTypeID() == kYearMonthInterval) ||
-             (left.getTypeID() == kYearMonthInterval && right.getSuperTypeID() == Type::kNumeric)) {
-    return &(YearMonthIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else {
-    return nullptr;
-  }
-}
-
-const Type* MultiplyBinaryOperation::resultTypeForPartialArgumentTypes(
-    const Type *left,
-    const Type *right) const {
-  if ((left == nullptr) && (right == nullptr)) {
-    return nullptr;
-  }
-
-  if ((left != nullptr) && (right != nullptr)) {
-    return resultTypeForArgumentTypes(*left, *right);
-  }
-
-  // Multiplication is commutative, so we just determine based on the known
-  // type, left or right.
-  const Type *known_type = (left != nullptr) ? left : right;
-  switch (known_type->getTypeID()) {
-    case kDatetimeInterval:
-      // DatetimeInterval can be multiplied against any numeric type, yielding
-      // DatetimeInterval.
-      return &TypeFactory::GetType(kDatetimeInterval, true);
-    case kYearMonthInterval:
-      // Same deal for YearMonthInterval.
-      return &TypeFactory::GetType(kYearMonthInterval, true);
-    default:
-      // Ambiguous or inapplicable. Note that we can't apply numeric precedence
-      // order for a Double argument, because the other argument could be a
-      // numeric type OR an interval type.
-      return nullptr;
-  }
-}
-
-bool MultiplyBinaryOperation::partialTypeSignatureIsPlausible(
-    const Type *result_type,
-    const Type *left_argument_type,
-    const Type *right_argument_type) const {
-  if ((left_argument_type == nullptr) && (right_argument_type == nullptr)) {
-    if (result_type == nullptr) {
-      return true;
-    } else if (!result_type->isNullable()) {
-      // Unknown arguments are assumed to be nullable, since they arise from
-      // untyped NULL literals in the parser. Therefore, a non-nullable result
-      // Type is not plausible with unknown arguments.
-      return false;
-    } else {
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          result_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-    }
-  }
-
-  if ((left_argument_type != nullptr) && (right_argument_type != nullptr)) {
-    const Type *actual_result_type = resultTypeForArgumentTypes(*left_argument_type,
-                                                                *right_argument_type);
-    if (actual_result_type == nullptr) {
-      // Both argument Types are known, but this operation is NOT applicable to
-      // them. No matter what the result_type is, the signature is not
-      // plausible.
-      return false;
-    } else if (result_type == nullptr) {
-      return true;
-    } else {
-      return result_type->equals(*actual_result_type);
-    }
-  }
-
-  // Multiplication is commutative, so we just determine based on the known
-  // type, left or right.
-  const Type *known_argument_type = (left_argument_type != nullptr)
-                                    ? left_argument_type
-                                    : right_argument_type;
-  if (result_type == nullptr) {
-    return QUICKSTEP_EQUALS_ANY_CONSTANT(
-        known_argument_type->getTypeID(),
-        kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-  }
-
-  if (!result_type->isNullable()) {
-    // One of the arguments is unknown, but it is nevertheless assumed
-    // nullable, since unknown argument Types arise from untyped NULL literals
-    // in the parser. Therefore, a non-nullable result Type is not plausible
-    // with an unknown argument.
-    return false;
-  }
-
-  switch (result_type->getTypeID()) {
-    case kInt:
-      return (known_argument_type->getTypeID() == kInt);
-    case kLong:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong);
-    case kFloat:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kFloat);
-    case kDouble:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble);
-    case kDatetimeInterval:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble, kDatetimeInterval);
-    case kYearMonthInterval:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble, kYearMonthInterval);
-    default:
-      return false;
-  }
-}
-
-std::pair<const Type*, const Type*> MultiplyBinaryOperation::pushDownTypeHint(
-    const Type *result_type_hint) const {
-  if (result_type_hint == nullptr) {
-    return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-
-  switch (result_type_hint->getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-      return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint);
-    case kDatetimeInterval:
-    case kYearMonthInterval:
-      // Ambiguous hint. One of the arguments should be the same as the
-      // '*type_hint', the other can be any numeric type, but either order is
-      // OK.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-    default:
-      // Inapplicable.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-}
-
-TypedValue MultiplyBinaryOperation::applyToChecked(const TypedValue &left,
-                                                   const Type &left_type,
-                                                   const TypedValue &right,
-                                                   const Type &right_type) const {
-  switch (left_type.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedNumericHelper<MultiplyFunctor>(left, left_type,
-                                                            right, right_type);
-      } else if (right_type.getTypeID() == kDatetimeInterval) {
-        return applyToCheckedIntervalMultiplyNumericHelper<DatetimeIntervalType>(right, right_type,
-                                                                                 left, left_type);
-      } else if (right_type.getTypeID() == kYearMonthInterval) {
-        return applyToCheckedIntervalMultiplyNumericHelper<YearMonthIntervalType>(right, right_type,
-                                                                                  left, left_type);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedIntervalMultiplyNumericHelper<DatetimeIntervalType>(left, left_type,
-                                                                                 right, right_type);
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedIntervalMultiplyNumericHelper<YearMonthIntervalType>(left, left_type,
-                                                                                  right, right_type);
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-             << left_type.getName() << " and " << right_type.getName();
-}
-
-UncheckedBinaryOperator* MultiplyBinaryOperation::makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                                                      const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 IntType::cpptype, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 IntType::cpptype, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kLong: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 LongType::cpptype, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 LongType::cpptype, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kFloat: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 FloatType::cpptype, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 FloatType::cpptype, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDouble: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 DoubleType::cpptype, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 DoubleType::cpptype, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      switch (right.getTypeID()) {
-        case kInt: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, IntType::cpptype>(left, right);
-        }
-        case kLong: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, LongType::cpptype>(left, right);
-        }
-        case kFloat: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, FloatType::cpptype>(left, right);
-        }
-        case kDouble: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, DoubleType::cpptype>(left, right);
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      switch (right.getTypeID()) {
-        case kInt: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, IntType::cpptype>(left, right);
-        }
-        case kLong: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, LongType::cpptype>(left, right);
-        }
-        case kFloat: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, FloatType::cpptype>(left, right);
-        }
-        case kDouble: {
-          return makeDateBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, DoubleType::cpptype>(left, right);
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-}
-
-template <typename IntervalType>
-TypedValue MultiplyBinaryOperation::applyToCheckedIntervalMultiplyNumericHelper(
-    const TypedValue &left,
-    const Type &left_type,
-    const TypedValue &right,
-    const Type &right_type) const {
-  DCHECK(IntervalType::kStaticTypeID == kDatetimeInterval ||
-         IntervalType::kStaticTypeID == kYearMonthInterval);
-  DCHECK(IntervalType::kStaticTypeID == left_type.getTypeID());
-  DCHECK_EQ(Type::kNumeric, right_type.getSuperTypeID());
-
-  if (left.isNull() || right.isNull()) {
-    return TypedValue(IntervalType::kStaticTypeID);
-  }
-
-  switch (right_type.getTypeID()) {
-    case kInt: {
-      return TypedValue(left.getLiteral<typename IntervalType::cpptype>() * right.getLiteral<IntType::cpptype>());
-    }
-    case kLong: {
-      return TypedValue(left.getLiteral<typename IntervalType::cpptype>() * right.getLiteral<LongType::cpptype>());
-    }
-    case kFloat: {
-      return TypedValue(left.getLiteral<typename IntervalType::cpptype>() * right.getLiteral<FloatType::cpptype>());
-    }
-    case kDouble: {
-      return TypedValue(left.getLiteral<typename IntervalType::cpptype>() * right.getLiteral<DoubleType::cpptype>());
-    }
-    default: {
-      LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-                 << left_type.getName() << " and " << right_type.getName();
-    }
-  }
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/SubtractBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/SubtractBinaryOperation.cpp b/types/operations/binary_operations/SubtractBinaryOperation.cpp
deleted file mode 100644
index 53e4266..0000000
--- a/types/operations/binary_operations/SubtractBinaryOperation.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/binary_operations/SubtractBinaryOperation.hpp"
-
-#include <string>
-#include <utility>
-
-#include "types/DateOperatorOverloads.hpp"
-#include "types/DateType.hpp"
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DatetimeLit.hpp"
-#include "types/DatetimeType.hpp"
-#include "types/IntervalLit.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperators.hpp"
-#include "utility/EqualsAnyConstant.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool SubtractBinaryOperation::canApplyToTypes(const Type &left, const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      return (right.getSuperTypeID() == Type::kNumeric);
-    }
-    case kDate: {
-      return (right.getTypeID() == kYearMonthInterval);
-    }
-    case kDatetime: {
-      return (right.getTypeID() == kDatetime         ||
-              right.getTypeID() == kDatetimeInterval ||
-              right.getTypeID() == kYearMonthInterval);
-    }
-    case kDatetimeInterval: {
-      return (right.getTypeID() == kDatetimeInterval);
-    }
-    case kYearMonthInterval: {
-      return (right.getTypeID() == kYearMonthInterval ||
-              right.getTypeID() == kDate);
-    }
-    default:
-      return false;
-  }
-}
-
-const Type* SubtractBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const {
-  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-    return TypeFactory::GetUnifyingType(left, right);
-  } else if ((left.getTypeID() == kDate && right.getTypeID() == kYearMonthInterval)) {
-    // For DATE type, only one possibility: DATE - YEAR-MONTH-INTERVAL.
-    return &(DateType::Instance(left.isNullable() || right.isNullable()));
-  } else if ((left.getTypeID() == kDatetime && right.getTypeID() == kDatetime) ||
-             (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval)) {
-    // NOTE(zuyu): we set the result type of the Subtract
-    // between two Datetimes as DatetimeInterval, instead of YearMonthInterval.
-    return &(DatetimeIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kDatetime && right.getTypeID() == kDatetimeInterval) {
-    return &(DatetimeType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kDatetime && right.getTypeID() == kYearMonthInterval) {
-    return &(DatetimeType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval) {
-    return &(YearMonthIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else {
-    return nullptr;
-  }
-}
-
-const Type* SubtractBinaryOperation::resultTypeForPartialArgumentTypes(
-    const Type *left,
-    const Type *right) const {
-  if (left == nullptr) {
-    if (right == nullptr) {
-      return nullptr;
-    } else {
-      switch (right->getTypeID()) {
-        case kDouble:
-          // Double has highest precedence of numeric types.
-          return &TypeFactory::GetType(kDouble, true);
-        case kDatetime:
-          // If the subtrahend is Datetime, then the only allowed minuend is
-          // another Datetime, and the result is an interval.
-          return &TypeFactory::GetType(kDatetimeInterval, true);
-        default:
-          // Ambiguous or inapplicable.
-          return nullptr;
-      }
-    }
-  } else {
-    if (right == nullptr) {
-      switch (left->getTypeID()) {
-        case kDouble:
-          // Double has highest precedence of numeric types.
-          return &TypeFactory::GetType(kDouble, true);
-        case kDate:
-          // If left is a Date, right must be a YearMonthInterval and the result
-          // must be a Date.
-          return &TypeFactory::GetType(kDate, true);
-        case kDatetimeInterval:
-          // If minuend is a DatetimeInterval, the subtrahend and result must
-          // also be DatetimeInterval.
-          return &TypeFactory::GetType(kDatetimeInterval, true);
-        case kYearMonthInterval:
-          // Similarly, if minuend is a YearMonthInterval, the subtrahend and
-          // result must also be YearMonthInterval.
-          return &TypeFactory::GetType(kYearMonthInterval, true);
-        default:
-          // Ambiguous or inapplicable.
-          return nullptr;
-      }
-    } else {
-      return resultTypeForArgumentTypes(*left, *right);
-    }
-  }
-}
-
-bool SubtractBinaryOperation::partialTypeSignatureIsPlausible(
-    const Type *result_type,
-    const Type *left_argument_type,
-    const Type *right_argument_type) const {
-  // Early check: if either argument type is nullable or unknown, result type
-  // must also be nullable.
-  if ((left_argument_type == nullptr)
-      || left_argument_type->isNullable()
-      || (right_argument_type == nullptr)
-      || right_argument_type->isNullable()) {
-    if ((result_type != nullptr) && (!result_type->isNullable())) {
-      return false;
-    }
-  }
-
-  if (left_argument_type == nullptr) {
-    if (right_argument_type == nullptr) {
-      if (result_type == nullptr) {
-        // All types unknown.
-        return true;
-      } else {
-        // Only result type is known, just check that it is one of the types
-        // that can possibly be returned.
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(result_type->getTypeID(),
-                                             kInt,
-                                             kLong,
-                                             kFloat,
-                                             kDouble,
-                                             kDate,
-                                             kDatetime,
-                                             kDatetimeInterval,
-                                             kYearMonthInterval);
-      }
-    }
-
-    if (result_type == nullptr) {
-      // Right (minuend) argument type is known, left (subtrahend) argument and
-      // result types are unknown. Just check that right (minuend) type can be
-      // subtracted.
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(right_argument_type->getTypeID(),
-                                           kInt,
-                                           kLong,
-                                           kFloat,
-                                           kDouble,
-                                           kDatetime,
-                                           kDatetimeInterval,
-                                           kYearMonthInterval);
-    }
-
-    // Return type and right (minuend) argument type are known, left
-    // (subtrahend) argument type is unknown. Check that result and subtrahend
-    // are compatible.
-    switch (right_argument_type->getTypeID()) {
-      case kInt:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kInt, kLong, kFloat, kDouble);
-      case kLong:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kLong, kDouble);
-      case kFloat:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kFloat, kDouble);
-      case kDouble:
-        return (result_type->getTypeID() == kDouble);
-      case kDate:
-        return (result_type->getTypeID() == kDate);
-      case kDatetime:
-        return (result_type->getTypeID() == kDatetimeInterval);
-      case kDatetimeInterval:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kDatetime, kDatetimeInterval);
-      case kYearMonthInterval:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kDate, kDatetime, kYearMonthInterval);
-      default:
-        return false;
-    }
-  } else {  // left_argument_type != nullptr
-    if (right_argument_type == nullptr) {
-      if (result_type == nullptr) {
-        // Left (subtrahend) argument type is known, right (minuend) argument
-        // type and result type are unknown. Just check that the left
-        // (subtrahend) type can be subtracted from.
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(left_argument_type->getTypeID(),
-                                             kInt,
-                                             kLong,
-                                             kFloat,
-                                             kDouble,
-                                             kDate,
-                                             kDatetime,
-                                             kDatetimeInterval,
-                                             kYearMonthInterval);
-      }
-
-      // Result type and left (subtrahend) argument type are known, but right
-      // (minuend) argument type is unknown. Check that result and minuend are
-      // compatible.
-      switch (left_argument_type->getTypeID()) {
-        case kInt:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kInt, kLong, kFloat, kDouble);
-        case kLong:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kLong, kDouble);
-        case kFloat:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kFloat, kDouble);
-        case kDouble:
-          return (result_type->getTypeID() == kDouble);
-        case kDate:
-          return (result_type->getTypeID() == kDate);
-        case kDatetime:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kDatetime, kDatetimeInterval);
-        case kDatetimeInterval:
-          return (result_type->getTypeID() == kDatetimeInterval);
-        case kYearMonthInterval:
-          return (result_type->getTypeID() == kYearMonthInterval);
-        default:
-          return false;
-      }
-    }
-
-    // Left and right (subtrahend and minuend) argument types are both known.
-    const Type *actual_result_type = resultTypeForArgumentTypes(*left_argument_type,
-                                                                *right_argument_type);
-    if (actual_result_type == nullptr) {
-      // Both argument Types are known, but this operation is NOT applicable to
-      // them. No matter what the result_type is, the signature is not
-      // plausible.
-      return false;
-    } else if (result_type == nullptr) {
-      return true;
-    } else {
-      // Check if result type matches.
-      return result_type->equals(*actual_result_type);
-    }
-  }
-}
-
-std::pair<const Type*, const Type*> SubtractBinaryOperation::pushDownTypeHint(
-    const Type *result_type_hint) const {
-  if (result_type_hint == nullptr) {
-    return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-
-  switch (result_type_hint->getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kYearMonthInterval:
-      return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint);
-    case kDate:
-      // Left should be a Date, right should be YearMonthInterval.
-      return std::pair<const Type *, const Type *>(
-          result_type_hint, &TypeFactory::GetType(kYearMonthInterval, true));
-    case kDatetime:
-      // Left should be a Datetime, right may be either interval type.
-      return std::pair<const Type*, const Type*>(result_type_hint, nullptr);
-    case kDatetimeInterval:
-      // Ambiguous: could be subtracting two Datetimes or two DatetimeIntervals.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-    default:
-      // Inapplicable.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-}
-
-TypedValue SubtractBinaryOperation::applyToChecked(const TypedValue &left,
-                                                   const Type &left_type,
-                                                   const TypedValue &right,
-                                                   const Type &right_type) const {
-  switch (left_type.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedNumericHelper<SubtractFunctor>(left, left_type,
-                                                            right, right_type);
-      }
-      break;
-    }
-    case kDate: {
-      if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDate);
-        }
-
-        return TypedValue(left.getLiteral<DateLit>() - right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    case kDatetime: {
-      if (right_type.getTypeID() == kDatetime) {
-        // NOTE(zuyu): The result type of the Subtract between two Datetimes is DatetimeInterval,
-        // instead of YearMonthInterval.
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetimeInterval);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeLit>() - right.getLiteral<DatetimeLit>());
-      } else if (right_type.getTypeID() == kDatetimeInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeLit>() - right.getLiteral<DatetimeIntervalLit>());
-      } else if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeLit>() - right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      if (right_type.getTypeID() == kDatetimeInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetimeInterval);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeIntervalLit>() - right.getLiteral<DatetimeIntervalLit>());
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kYearMonthInterval);
-        }
-
-        return TypedValue(left.getLiteral<YearMonthIntervalLit>() - right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-             << left_type.getName() << " and " << right_type.getName();
-}
-
-UncheckedBinaryOperator* SubtractBinaryOperation::makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                                                      const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator>(left, right);
-      }
-      break;
-    }
-    case kDate: {
-      if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<
-            SubtractArithmeticUncheckedBinaryOperator,
-            DateType,
-            DateLit,
-            YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDatetime: {
-      if (right.getTypeID() == kDatetime) {
-        // NOTE(zuyu): The result type of the Subtract between two Datetimes is DatetimeInterval,
-        // instead of YearMonthInterval.
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 DatetimeLit, DatetimeLit>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 DatetimeType,
-                                                 DatetimeLit, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 DatetimeType,
-                                                 DatetimeLit, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 DatetimeIntervalLit, DatetimeIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 YearMonthIntervalLit, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/SubtractBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/SubtractBinaryOperation.hpp b/types/operations/binary_operations/SubtractBinaryOperation.hpp
deleted file mode 100644
index 8e54362..0000000
--- a/types/operations/binary_operations/SubtractBinaryOperation.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_SUBTRACT_BINARY_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_SUBTRACT_BINARY_OPERATION_HPP_
-
-#include <utility>
-
-#include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-class UncheckedBinaryOperator;
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief The BinaryOperation for subtraction.
- *
- * @note SubtractBinaryOperation is not commutative: the left argument is the
- *       minuend and the right argument is the subtrahend.
- **/
-class SubtractBinaryOperation : public ArithmeticBinaryOperation {
- public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const SubtractBinaryOperation& Instance() {
-    static SubtractBinaryOperation instance;
-    return instance;
-  }
-
-  bool canApplyToTypes(const Type &left,
-                       const Type &right) const override;
-
-  const Type* resultTypeForArgumentTypes(const Type &left,
-                                         const Type &right) const override;
-
-  const Type* resultTypeForPartialArgumentTypes(const Type *left,
-                                                const Type *right) const override;
-
-  bool partialTypeSignatureIsPlausible(const Type *result_type,
-                                       const Type *left_argument_type,
-                                       const Type *right_argument_type) const override;
-
-  std::pair<const Type*, const Type*> pushDownTypeHint(
-      const Type *result_type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &left,
-                            const Type &left_type,
-                            const TypedValue &right,
-                            const Type &right_type) const override;
-
-  UncheckedBinaryOperator *makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                               const Type &right) const override;
-
- private:
-  SubtractBinaryOperation()
-      : ArithmeticBinaryOperation(BinaryOperationID::kSubtract) {
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(SubtractBinaryOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_SUBTRACT_BINARY_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/comparisons/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/CMakeLists.txt b/types/operations/comparisons/CMakeLists.txt
index 321c0f6..933f4fa 100644
--- a/types/operations/comparisons/CMakeLists.txt
+++ b/types/operations/comparisons/CMakeLists.txt
@@ -105,11 +105,13 @@ target_link_libraries(quickstep_types_operations_comparisons_ComparisonID
 target_link_libraries(quickstep_types_operations_comparisons_ComparisonUtil
                       glog
                       quickstep_catalog_CatalogTypedefs
+                      quickstep_types_CharType
                       quickstep_types_DatetimeLit
                       quickstep_types_IntervalLit
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
+                      quickstep_types_VarCharType
                       quickstep_types_containers_Tuple
                       quickstep_types_operations_comparisons_AsciiStringComparators
                       quickstep_types_operations_comparisons_Comparison
@@ -179,8 +181,8 @@ target_link_libraries(quickstep_types_operations_comparisons_PatternMatchingComp
                       quickstep_types_operations_comparisons_PatternMatchingComparators
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonID
-                      quickstep_utility_TemplateUtil
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_Dispatchers)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_comparisons ../../../empty_src.cpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/comparisons/Comparison.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/Comparison.hpp b/types/operations/comparisons/Comparison.hpp
index c300e74..33c853d 100644
--- a/types/operations/comparisons/Comparison.hpp
+++ b/types/operations/comparisons/Comparison.hpp
@@ -606,11 +606,7 @@ class Comparison : public Operation {
 
  protected:
   explicit Comparison(const ComparisonID comparison_id)
-      : Operation(Operation::kComparison,
-                  kComparisonNames[
-                      static_cast<typename std::underlying_type<ComparisonID>::type>(comparison_id)],
-                  kComparisonShortNames[
-                      static_cast<typename std::underlying_type<ComparisonID>::type>(comparison_id)]),
+      : Operation(Operation::kComparison),
         comparison_id_(comparison_id) {
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/comparisons/ComparisonUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/ComparisonUtil.hpp b/types/operations/comparisons/ComparisonUtil.hpp
index 5d868fc..425566d 100644
--- a/types/operations/comparisons/ComparisonUtil.hpp
+++ b/types/operations/comparisons/ComparisonUtil.hpp
@@ -28,11 +28,13 @@
 #include <type_traits>
 
 #include "catalog/CatalogTypedefs.hpp"
+#include "types/CharType.hpp"
 #include "types/DatetimeLit.hpp"
 #include "types/IntervalLit.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
+#include "types/VarCharType.hpp"
 #include "types/containers/Tuple.hpp"
 #include "types/operations/comparisons/AsciiStringComparators.hpp"
 #include "types/operations/comparisons/AsciiStringComparators-inl.hpp"
@@ -153,7 +155,7 @@ auto InvokeOnLessComparatorForTypeIgnoreNullability(const Type &type,
     }
     case kChar: {
       const std::size_t string_length
-          = static_cast<const AsciiStringSuperType&>(type).getStringLength();
+          = static_cast<const CharType&>(type).getStringLength();
       LessAsciiStringUncheckedComparator<false, false, false,
                                          false, false, false>
           comp(string_length, string_length);
@@ -340,11 +342,11 @@ auto InvokeOnLessComparatorForDifferentTypesIgnoreNullability(
     }
     case kChar: {
       const std::size_t left_string_length
-          = static_cast<const AsciiStringSuperType&>(left_type).getStringLength();
+          = static_cast<const CharType&>(left_type).getStringLength();
       switch (right_type.getTypeID()) {
         case kChar: {
           const std::size_t right_string_length
-              = static_cast<const AsciiStringSuperType&>(right_type).getStringLength();
+              = static_cast<const CharType&>(right_type).getStringLength();
           if (left_string_length < right_string_length) {
             LessAsciiStringUncheckedComparator<false, false, false,
                                                false, false, true>
@@ -364,7 +366,7 @@ auto InvokeOnLessComparatorForDifferentTypesIgnoreNullability(
         }
         case kVarChar: {
           const std::size_t right_string_length
-              = static_cast<const AsciiStringSuperType&>(right_type).getStringLength();
+              = static_cast<const VarCharType&>(right_type).getStringLength();
           if (left_string_length < right_string_length) {
             LessAsciiStringUncheckedComparator<false, false, false,
                                                false, true, true>
@@ -389,11 +391,11 @@ auto InvokeOnLessComparatorForDifferentTypesIgnoreNullability(
     }
     case kVarChar: {
       const std::size_t left_string_length
-          = static_cast<const AsciiStringSuperType&>(left_type).getStringLength();
+          = static_cast<const VarCharType&>(left_type).getStringLength();
       switch (right_type.getTypeID()) {
         case kChar: {
           const std::size_t right_string_length
-              = static_cast<const AsciiStringSuperType&>(right_type).getStringLength();
+              = static_cast<const CharType&>(right_type).getStringLength();
           if (left_string_length < right_string_length) {
             LessAsciiStringUncheckedComparator<false, true, false,
                                                false, false, true>
@@ -413,7 +415,7 @@ auto InvokeOnLessComparatorForDifferentTypesIgnoreNullability(
         }
         case kVarChar: {
           const std::size_t right_string_length
-              = static_cast<const AsciiStringSuperType&>(right_type).getStringLength();
+              = static_cast<const VarCharType&>(right_type).getStringLength();
           if (left_string_length < right_string_length) {
             LessAsciiStringUncheckedComparator<false, true, false,
                                                false, true, true>
@@ -653,11 +655,11 @@ auto InvokeOnBothLessComparatorsForDifferentTypesIgnoreNullability(
     }
     case kChar: {
       const std::size_t left_string_length
-          = static_cast<const AsciiStringSuperType&>(left_type).getStringLength();
+          = static_cast<const CharType&>(left_type).getStringLength();
       switch (right_type.getTypeID()) {
         case kChar: {
           const std::size_t right_string_length
-              = static_cast<const AsciiStringSuperType&>(right_type).getStringLength();
+              = static_cast<const CharType&>(right_type).getStringLength();
           if (left_string_length < right_string_length) {
             LessAsciiStringUncheckedComparator<false, false, false,
                                                false, false, true>
@@ -686,7 +688,7 @@ auto InvokeOnBothLessComparatorsForDifferentTypesIgnoreNullability(
         }
         case kVarChar: {
           const std::size_t right_string_length
-              = static_cast<const AsciiStringSuperType&>(right_type).getStringLength();
+              = static_cast<const VarCharType&>(right_type).getStringLength();
           if (left_string_length < right_string_length) {
             LessAsciiStringUncheckedComparator<false, false, false,
                                                false, true, true>
@@ -720,11 +722,11 @@ auto InvokeOnBothLessComparatorsForDifferentTypesIgnoreNullability(
     }
     case kVarChar: {
       const std::size_t left_string_length
-          = static_cast<const AsciiStringSuperType&>(left_type).getStringLength();
+          = static_cast<const VarCharType&>(left_type).getStringLength();
       switch (right_type.getTypeID()) {
         case kChar: {
           const std::size_t right_string_length
-              = static_cast<const AsciiStringSuperType&>(right_type).getStringLength();
+              = static_cast<const CharType&>(right_type).getStringLength();
           if (left_string_length < right_string_length) {
             LessAsciiStringUncheckedComparator<false, true, false,
                                                false, false, true>
@@ -753,7 +755,7 @@ auto InvokeOnBothLessComparatorsForDifferentTypesIgnoreNullability(
         }
         case kVarChar: {
           const std::size_t right_string_length
-              = static_cast<const AsciiStringSuperType&>(right_type).getStringLength();
+              = static_cast<const VarCharType&>(right_type).getStringLength();
           if (left_string_length < right_string_length) {
             LessAsciiStringUncheckedComparator<false, true, false,
                                                false, true, true>
@@ -991,7 +993,7 @@ inline bool CheckUntypedValuesEqual(const Type &type, const void *left, const vo
     case kDouble:
       return STLLiteralEqual<double>()(left, right);
     case kChar:
-      return STLCharEqual(static_cast<const AsciiStringSuperType&>(type).getStringLength())(left, right);
+      return STLCharEqual(static_cast<const CharType&>(type).getStringLength())(left, right);
     case kVarChar:
       return STLVarCharEqual()(left, right);
     case kDate:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/comparisons/PatternMatchingComparison.cpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/PatternMatchingComparison.cpp b/types/operations/comparisons/PatternMatchingComparison.cpp
index 4207f0f..c94ba52 100644
--- a/types/operations/comparisons/PatternMatchingComparison.cpp
+++ b/types/operations/comparisons/PatternMatchingComparison.cpp
@@ -29,7 +29,7 @@
 #include "types/operations/comparisons/ComparisonID.hpp"
 #include "types/operations/comparisons/PatternMatchingComparators.hpp"
 #include "types/operations/comparisons/PatternMatchingComparators-inl.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Dispatchers.hpp"
 
 #include "glog/logging.h"
 
@@ -121,11 +121,19 @@ UncheckedComparator* PatternMatchingComparison::makeUncheckedComparatorForTypes(
                  << " in PatternMatchinComparison::makeUncheckedComparatorForTypes()";
   }
 
-  return CreateBoolInstantiatedInstance<PatternMatchingUncheckedComparator, UncheckedComparator>(
-      std::forward_as_tuple(left_max_length, right_max_length),
+  return meta::InvokeOnBools(
       is_like_pattern, is_negation,
-      left.isNullable(), right.isNullable());
+      left.isNullable(), right.isNullable(),
+      [&](auto is_like_pattern,  // NOLINT(build/c++11)
+          auto is_negation,
+          auto is_left_nullable,
+          auto is_right_nullable) -> UncheckedComparator* {
+    return new PatternMatchingUncheckedComparator<
+        decltype(is_like_pattern)::value,
+        decltype(is_negation)::value,
+        decltype(is_left_nullable)::value,
+        decltype(is_right_nullable)::value>(left_max_length, right_max_length);
+  });
 }
 
-
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/ArithmeticUnaryOperations.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/ArithmeticUnaryOperations.cpp b/types/operations/unary_operations/ArithmeticUnaryOperations.cpp
deleted file mode 100644
index c10d5cf..0000000
--- a/types/operations/unary_operations/ArithmeticUnaryOperations.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp"
-
-#include <string>
-
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/unary_operations/ArithmeticUnaryOperators.hpp"
-#include "utility/EqualsAnyConstant.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool ArithmeticUnaryOperation::canApplyToType(const Type &type) const {
-  return QUICKSTEP_EQUALS_ANY_CONSTANT(
-      type.getTypeID(),
-      kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-}
-
-const Type* ArithmeticUnaryOperation::resultTypeForArgumentType(const Type &type) const {
-  if (canApplyToType(type)) {
-    return &type;
-  } else {
-    return nullptr;
-  }
-}
-
-const Type* ArithmeticUnaryOperation::pushDownTypeHint(const Type *type_hint) const {
-  if (type_hint == nullptr) {
-    return nullptr;
-  }
-
-  if (canApplyToType(*type_hint)) {
-    return type_hint;
-  } else {
-    return nullptr;
-  }
-}
-
-bool NegateUnaryOperation::resultTypeIsPlausible(const Type &result_type) const {
-  return QUICKSTEP_EQUALS_ANY_CONSTANT(
-      result_type.getTypeID(),
-      kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-}
-
-TypedValue NegateUnaryOperation::applyToChecked(const TypedValue &argument,
-                                                const Type &argument_type) const {
-  DCHECK_EQ(argument.getTypeID(), argument_type.getTypeID());
-
-  if (argument.isNull()) {
-    return argument;
-  }
-
-  switch (argument.getTypeID()) {
-    case kInt:
-      return TypedValue(-argument.getLiteral<typename IntType::cpptype>());
-    case kLong:
-      return TypedValue(-argument.getLiteral<typename LongType::cpptype>());
-    case kFloat:
-      return TypedValue(-argument.getLiteral<typename FloatType::cpptype>());
-    case kDouble:
-      return TypedValue(-argument.getLiteral<typename DoubleType::cpptype>());
-    case kDatetimeInterval:
-      return TypedValue(-argument.getLiteral<typename DatetimeIntervalType::cpptype>());
-    case kYearMonthInterval:
-      return TypedValue(-argument.getLiteral<typename YearMonthIntervalType::cpptype>());
-    default: {
-      LOG(FATAL) << "Can not apply UnaryOperation " << getName()
-                 << " to argument of type " << argument_type.getName();
-    }
-  }
-}
-
-UncheckedUnaryOperator* NegateUnaryOperation::makeUncheckedUnaryOperatorForType(const Type &type) const {
-  switch (type.getTypeID()) {
-    case kInt:
-      if (type.isNullable()) {
-        return new NegateUncheckedUnaryOperator<IntType, true>();
-      } else {
-        return new NegateUncheckedUnaryOperator<IntType, false>();
-      }
-    case kLong:
-      if (type.isNullable()) {
-        return new NegateUncheckedUnaryOperator<LongType, true>();
-      } else {
-        return new NegateUncheckedUnaryOperator<LongType, false>();
-      }
-    case kFloat:
-      if (type.isNullable()) {
-        return new NegateUncheckedUnaryOperator<FloatType, true>();
-      } else {
-        return new NegateUncheckedUnaryOperator<FloatType, false>();
-      }
-    case kDouble:
-      if (type.isNullable()) {
-        return new NegateUncheckedUnaryOperator<DoubleType, true>();
-      } else {
-        return new NegateUncheckedUnaryOperator<DoubleType, false>();
-      }
-    case kDatetimeInterval:
-      if (type.isNullable()) {
-        return new NegateUncheckedUnaryOperator<DatetimeIntervalType, true>();
-      } else {
-        return new NegateUncheckedUnaryOperator<DatetimeIntervalType, false>();
-      }
-    case kYearMonthInterval:
-      if (type.isNullable()) {
-        return new NegateUncheckedUnaryOperator<YearMonthIntervalType, true>();
-      } else {
-        return new NegateUncheckedUnaryOperator<YearMonthIntervalType, false>();
-      }
-    default:
-      throw OperationInapplicableToType(getName(), 1, type.getName().c_str());
-  }
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/ArithmeticUnaryOperations.hpp b/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
index 5eed073..4c212c0 100644
--- a/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
+++ b/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
@@ -20,73 +20,60 @@
 #ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_OPERATIONS_HPP_
 #define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_OPERATIONS_HPP_
 
-#include "types/TypedValue.hpp"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
-#include "utility/Macros.hpp"
+#include <string>
 
-namespace quickstep {
+#include "types/DatetimeIntervalType.hpp"
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/YearMonthIntervalType.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
 
-class Type;
+namespace quickstep {
 
 /** \addtogroup Types
  *  @{
  */
 
-/**
- * @brief A UnaryOperation which applies to and yields numeric values.
- **/
-class ArithmeticUnaryOperation : public UnaryOperation {
- public:
-  bool canApplyToType(const Type &type) const override;
-
-  const Type* resultTypeForArgumentType(const Type &type) const override;
-
-  const Type* pushDownTypeHint(const Type *type_hint) const override;
-
- protected:
-  explicit ArithmeticUnaryOperation(const UnaryOperationID operation_id)
-      : UnaryOperation(operation_id) {
+template <typename ArgumentT, typename ResultT>
+struct NegateFunctor : public UnaryFunctor<ArgumentT, ResultT> {
+  inline typename ResultT::cpptype apply(
+      const typename ArgumentT::cpptype &argument) const {
+    return -argument;
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ArithmeticUnaryOperation);
-};
-
-/**
- * @brief The UnaryOperation for negation.
- **/
-class NegateUnaryOperation : public ArithmeticUnaryOperation {
- public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const NegateUnaryOperation& Instance() {
-    static NegateUnaryOperation instance;
-    return instance;
+  inline static std::string GetName() {
+    return "-";
   }
+};
 
-  const Type* fixedNullableResultType() const override {
-    return nullptr;
+template <typename ArgumentT>
+struct SgnFunctor : public UnaryFunctor<ArgumentT, IntType> {
+  inline int apply(const typename ArgumentT::cpptype &argument) const {
+    return (argument > 0) - (argument < 0);
   }
-
-  bool resultTypeIsPlausible(const Type &result_type) const override;
-
-  TypedValue applyToChecked(const TypedValue &argument,
-                            const Type &argument_type) const override;
-
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override;
-
- private:
-  NegateUnaryOperation()
-      : ArithmeticUnaryOperation(UnaryOperationID::kNegate) {
+  inline static std::string GetName() {
+    return "Sgn";
   }
-
-  DISALLOW_COPY_AND_ASSIGN(NegateUnaryOperation);
 };
 
+using ArithmeticUnaryFunctorPack = FunctorPack<
+// negate
+  NegateFunctor<IntType, IntType>,
+  NegateFunctor<LongType, LongType>,
+  NegateFunctor<FloatType, FloatType>,
+  NegateFunctor<DoubleType, DoubleType>,
+  NegateFunctor<DatetimeIntervalType, DatetimeIntervalType>,
+  NegateFunctor<YearMonthIntervalType, YearMonthIntervalType>,
+
+// sgn (Sign of a numeric value)
+  SgnFunctor<IntType>,
+  SgnFunctor<LongType>,
+  SgnFunctor<FloatType>,
+  SgnFunctor<DoubleType>
+>;
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/ArithmeticUnaryOperators.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/ArithmeticUnaryOperators.hpp b/types/operations/unary_operations/ArithmeticUnaryOperators.hpp
deleted file mode 100644
index bf3f7b6..0000000
--- a/types/operations/unary_operations/ArithmeticUnaryOperators.hpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_OPERATORS_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_OPERATORS_HPP_
-
-#include <cstddef>
-#include <utility>
-#include <vector>
-
-#include "catalog/CatalogTypedefs.hpp"
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-#include "storage/StorageBlockInfo.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief The UncheckedUnaryOperator for negation.
- **/
-template <class ResultType, bool argument_nullable>
-class NegateUncheckedUnaryOperator : public UncheckedUnaryOperator {
- public:
-  NegateUncheckedUnaryOperator() : UncheckedUnaryOperator() {
-  }
-
-  inline TypedValue applyToTypedValue(const TypedValue &argument) const override {
-    return applyToTypedValueInl(argument);
-  }
-
-  inline TypedValue applyToTypedValueInl(const TypedValue &argument) const {
-    if (argument_nullable && argument.isNull()) {
-      return argument;
-    }
-    return TypedValue(-argument.getLiteral<typename ResultType::cpptype>());
-  }
-
-  inline TypedValue applyToDataPtr(const void *argument) const override {
-    return applyToDataPtrInl(argument);
-  }
-
-  inline TypedValue applyToDataPtrInl(const void *argument) const {
-    if (argument_nullable && (argument == nullptr)) {
-      return TypedValue(ResultType::kStaticTypeID);
-    }
-    return TypedValue(-*static_cast<const typename ResultType::cpptype*>(argument));
-  }
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
-    DCHECK(NativeColumnVector::UsableForType(ResultType::Instance(argument_nullable)));
-    // All arithmetic types (numbers, datetime, and intervals) are usable with
-    // NativeColumnVector, so 'argument' should always be native.
-    DCHECK(argument.isNative());
-    const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
-    NativeColumnVector *result = new NativeColumnVector(
-        ResultType::Instance(argument_nullable),
-        native_argument.size());
-    for (std::size_t pos = 0;
-         pos < native_argument.size();
-         ++pos) {
-      const typename ResultType::cpptype *scalar_arg
-          = static_cast<const typename ResultType::cpptype*>(
-              native_argument.getUntypedValue<argument_nullable>(pos));
-      if (argument_nullable && (scalar_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-            = -(*scalar_arg);
-      }
-    }
-    return result;
-  }
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id argument_attr_id) const override {
-    DCHECK(NativeColumnVector::UsableForType(ResultType::Instance(argument_nullable)));
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      NativeColumnVector *result = new NativeColumnVector(
-          ResultType::Instance(argument_nullable),
-          accessor->getNumTuples());
-      accessor->beginIteration();
-      while (accessor->next()) {
-        const typename ResultType::cpptype *scalar_arg
-            = static_cast<const typename ResultType::cpptype*>(
-                accessor->template getUntypedValue<argument_nullable>(argument_attr_id));
-        if (argument_nullable && (scalar_arg == nullptr)) {
-          result->appendNullValue();
-        } else {
-          *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-              = -(*scalar_arg);
-        }
-      }
-      return result;
-    });
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  ColumnVector* applyToValueAccessorForJoin(
-      ValueAccessor *accessor,
-      const bool use_left_relation,
-      const attribute_id argument_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
-    DCHECK(NativeColumnVector::UsableForType(ResultType::Instance(argument_nullable)));
-    NativeColumnVector *result = new NativeColumnVector(ResultType::Instance(argument_nullable),
-                                                        joined_tuple_ids.size());
-    InvokeOnValueAccessorNotAdapter(
-        accessor,
-        [&](auto *accessor) -> void {  // NOLINT(build/c++11)
-      for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-        const typename ResultType::cpptype *scalar_arg
-            = static_cast<const typename ResultType::cpptype*>(
-                accessor->template getUntypedValueAtAbsolutePosition<argument_nullable>(
-                    argument_attr_id,
-                    use_left_relation ? joined_pair.first : joined_pair.second));
-        if (argument_nullable && (scalar_arg == nullptr)) {
-          result->appendNullValue();
-        } else {
-          *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-              = -(*scalar_arg);
-        }
-      }
-    });
-    return result;
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NegateUncheckedUnaryOperator);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_OPERATORS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/AsciiStringUnaryOperations.hpp b/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
new file mode 100644
index 0000000..1ee1867
--- /dev/null
+++ b/types/operations/unary_operations/AsciiStringUnaryOperations.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_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_OPERATIONS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_OPERATIONS_HPP_
+
+#include <cctype>
+#include <cstring>
+#include <string>
+
+#include "types/CharType.hpp"
+#include "types/IntType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/VarCharType.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/port/strnlen.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT>
+struct AsciiStringLengthFunctor : public UnaryFunctor<ArgumentT, IntType> {
+  explicit AsciiStringLengthFunctor(const ArgumentT &argument_type)
+      : max_string_length_(argument_type.getStringLength()) {}
+  inline int apply(const void *argument) const {
+    return strnlen(static_cast<const char*>(argument), max_string_length_);
+  }
+  inline int apply(const TypedValue &argument) const {
+    DCHECK(argument.getTypeID() == kVarChar);
+    return std::strlen(static_cast<const char*>(argument.getOutOfLineData()));
+  }
+  inline static std::string GetName() {
+    return "length";
+  }
+  const std::size_t max_string_length_;
+};
+
+template <typename ArgumentT, int transform(int), typename FunctorNameT>
+struct AsciiStringTranformFunctor : public UnaryFunctor<ArgumentT, ArgumentT> {
+  explicit AsciiStringTranformFunctor(const ArgumentT &argument_type)
+      : max_string_length_(argument_type.getStringLength()) {}
+  inline void apply(const void *argument, void *result) const {
+    DCHECK(ArgumentT::kStaticTypeID == kChar);
+    const char *argument_str = static_cast<const char*>(argument);
+    char *result_str = static_cast<char*>(result);
+    for (std::size_t i = 0; i < max_string_length_; ++i) {
+      if ((result_str[i] = transform(argument_str[i])) == 0) {
+        break;
+      }
+    }
+  }
+  inline TypedValue apply(const TypedValue &argument) const {
+    DCHECK(argument.getTypeID() == kVarChar);
+    const char *argument_str = static_cast<const char*>(argument.getOutOfLineData());
+    const std::size_t length = argument.getDataSize();
+    char *buf = static_cast<char*>(std::malloc(length));
+
+    for (std::size_t i = 0; i < length; ++i) {
+      buf[i] = transform(argument_str[i]);
+    }
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, length);
+  }
+  inline static std::string GetName() {
+    return FunctorNameT::ToString();
+  }
+  inline static const Type* GetResultType(const Type &argument_type) {
+    DCHECK(argument_type.getTypeID() == ArgumentT::kStaticTypeID);
+    return &argument_type;
+  }
+  const std::size_t max_string_length_;
+};
+
+template <typename ArgumentT>
+using AsciiStringToLowerCaseFunctor =
+    AsciiStringTranformFunctor<ArgumentT, std::tolower,
+                               meta::StringLiteral<'t', 'o', 'l', 'o', 'w', 'e', 'r'>>;
+
+template <typename ArgumentT>
+using AsciiStringToUpperCaseFunctor =
+    AsciiStringTranformFunctor<ArgumentT, std::toupper,
+                               meta::StringLiteral<'t', 'o', 'u', 'p', 'p', 'e', 'r'>>;
+
+using AsciiStringUnaryFunctorPack = FunctorPack<
+// length
+    AsciiStringLengthFunctor<CharType>,
+    AsciiStringLengthFunctor<VarCharType>,
+// tolower
+    AsciiStringToLowerCaseFunctor<CharType>,
+    AsciiStringToLowerCaseFunctor<VarCharType>,
+// toupper
+    AsciiStringToUpperCaseFunctor<CharType>,
+    AsciiStringToUpperCaseFunctor<VarCharType>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index 6e1923a..bcd756e 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -16,14 +16,26 @@
 # under the License.
 
 # Declare micro-libs:
-add_library(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations ArithmeticUnaryOperations.cpp ArithmeticUnaryOperations.hpp)
-add_library(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperators ../../../empty_src.cpp ArithmeticUnaryOperators.hpp)
-add_library(quickstep_types_operations_unaryoperations_DateExtractOperation DateExtractOperation.cpp DateExtractOperation.hpp)
-add_library(quickstep_types_operations_unaryoperations_NumericCastOperation ../../../empty_src.cpp NumericCastOperation.hpp)
-add_library(quickstep_types_operations_unaryoperations_SubstringOperation SubstringOperation.cpp SubstringOperation.hpp)
+add_library(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+            ../../../empty_src.cpp
+            ArithmeticUnaryOperations.hpp)
+add_library(quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+            ../../../empty_src.cpp
+            AsciiStringUnaryOperations.hpp)
+add_library(quickstep_types_operations_unaryoperations_CMathUnaryOperations
+            ../../../empty_src.cpp
+            CMathUnaryOperations.hpp)
+add_library(quickstep_types_operations_unaryoperations_CastOperation CastOperation.cpp CastOperation.hpp)
+add_library(quickstep_types_operations_unaryoperations_DateExtractOperation
+            DateExtractOperation.cpp
+            DateExtractOperation.hpp)
+add_library(quickstep_types_operations_unaryoperations_SubstringOperation
+            SubstringOperation.cpp
+            SubstringOperation.hpp)
 add_library(quickstep_types_operations_unaryoperations_UnaryOperation UnaryOperation.cpp UnaryOperation.hpp)
-add_library(quickstep_types_operations_unaryoperations_UnaryOperationFactory UnaryOperationFactory.cpp UnaryOperationFactory.hpp)
-add_library(quickstep_types_operations_unaryoperations_UnaryOperationID UnaryOperationID.cpp UnaryOperationID.hpp)
+add_library(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+            ../../../empty_src.cpp
+            UnaryOperationWrapper.hpp)
 
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
@@ -33,109 +45,110 @@ target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnary
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
+                      quickstep_types_YearMonthIntervalType
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper)
+target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+                      quickstep_types_CharType
+                      quickstep_types_IntType
                       quickstep_types_Type
-                      quickstep_types_TypeErrors
+                      quickstep_types_TypeFactory
                       quickstep_types_TypeID
-                      quickstep_types_TypedValue
-                      quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperators
-                      quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
-                      quickstep_utility_EqualsAnyConstant
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperators
-                      glog
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_StorageBlockInfo
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
-                      quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOperation
+                      quickstep_types_VarCharType
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_port_strnlen
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryOperations
+                      quickstep_types_DoubleType
+                      quickstep_types_FloatType
+                      quickstep_types_IntType
+                      quickstep_types_LongType
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_unaryoperations_CastOperation
                       glog
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_StorageBlockInfo
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
-                      quickstep_types_DatetimeLit
+                      quickstep_types_CharType
+                      quickstep_types_DoubleType
+                      quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
+                      quickstep_types_TypeUtil
                       quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_Operation_proto
+                      quickstep_types_VarCharType
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_NumericCastOperation
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_port_strnlen
+                      quickstep_utility_EqualsAnyConstant
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
+target_link_libraries(quickstep_types_operations_unaryoperations_DateExtractOperation
                       glog
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
-                      quickstep_types_DoubleType
-                      quickstep_types_FloatType
+                      quickstep_types_DateType
+                      quickstep_types_DatetimeLit
+                      quickstep_types_DatetimeType
                       quickstep_types_IntType
                       quickstep_types_LongType
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_Operation_proto
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
                       quickstep_utility_Macros
-                      quickstep_utility_PtrMap)
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_ValueAccessor
                       quickstep_storage_ValueAccessorUtil
+                      quickstep_types_CharType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
+                      quickstep_types_VarCharType
                       quickstep_types_containers_ColumnVector
                       quickstep_types_containers_ColumnVectorUtil
-                      quickstep_types_operations_Operation_proto
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_types_port_strnlen
-                      quickstep_utility_HashPair
                       quickstep_utility_Macros
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Dispatchers)
 target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_StorageBlockInfo
                       quickstep_types_TypedValue
                       quickstep_types_operations_Operation
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_Operation_proto
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationFactory
+target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
                       glog
+                      quickstep_catalog_CatalogTypedefs
+                      quickstep_storage_ValueAccessor
+                      quickstep_storage_ValueAccessorUtil
+                      quickstep_types_Type
                       quickstep_types_TypeFactory
-                      quickstep_types_operations_Operation_proto
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
-                      quickstep_types_operations_unaryoperations_DateExtractOperation
-                      quickstep_types_operations_unaryoperations_NumericCastOperation
-                      quickstep_types_operations_unaryoperations_SubstringOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
+                      quickstep_types_TypeID
+                      quickstep_types_TypedValue
+                      quickstep_types_containers_ColumnVector
+                      quickstep_types_operations_OperationSignature
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_utility_Macros)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_unaryoperations ../../../empty_src.cpp)
 target_link_libraries(quickstep_types_operations_unaryoperations
                       quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperators
+                      quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+                      quickstep_types_operations_unaryoperations_CMathUnaryOperations
+                      quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
-                      quickstep_types_operations_unaryoperations_NumericCastOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
-                      quickstep_types_operations_unaryoperations_UnaryOperationID)
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper)
 
 # Tests:
 
@@ -160,11 +173,9 @@ target_link_libraries(UnaryOperation_tests
                       quickstep_types_containers_ColumnVector
                       quickstep_types_operations_Operation_proto
                       quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+                      quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
-                      quickstep_types_operations_unaryoperations_NumericCastOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros)
 add_test(UnaryOperation_tests UnaryOperation_tests)



[24/38] incubator-quickstep git commit: Add array expression

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index 035e325..69b78e7 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -126,61 +126,63 @@ extern int quickstep_yydebug;
     TOKEN_JOIN = 336,
     TOKEN_KEY = 337,
     TOKEN_LAST = 338,
-    TOKEN_LEFT = 339,
-    TOKEN_LIMIT = 340,
-    TOKEN_LONG = 341,
-    TOKEN_MINUTE = 342,
-    TOKEN_MONTH = 343,
-    TOKEN_NULL = 344,
-    TOKEN_NULLS = 345,
-    TOKEN_OFF = 346,
-    TOKEN_ON = 347,
-    TOKEN_ORDER = 348,
-    TOKEN_OUTER = 349,
-    TOKEN_OVER = 350,
-    TOKEN_PARTITION = 351,
-    TOKEN_PARTITIONS = 352,
-    TOKEN_PERCENT = 353,
-    TOKEN_PRECEDING = 354,
-    TOKEN_PRIMARY = 355,
-    TOKEN_PRIORITY = 356,
-    TOKEN_QUIT = 357,
-    TOKEN_RANGE = 358,
-    TOKEN_REAL = 359,
-    TOKEN_REFERENCES = 360,
-    TOKEN_RIGHT = 361,
-    TOKEN_ROW = 362,
-    TOKEN_ROW_DELIMITER = 363,
-    TOKEN_ROWS = 364,
-    TOKEN_SECOND = 365,
-    TOKEN_SELECT = 366,
-    TOKEN_SET = 367,
-    TOKEN_SMA = 368,
-    TOKEN_SMALLINT = 369,
-    TOKEN_STDERR = 370,
-    TOKEN_STDOUT = 371,
-    TOKEN_SUBSTRING = 372,
-    TOKEN_TABLE = 373,
-    TOKEN_THEN = 374,
-    TOKEN_TIME = 375,
-    TOKEN_TIMESTAMP = 376,
-    TOKEN_TO = 377,
-    TOKEN_TRUE = 378,
-    TOKEN_TUPLESAMPLE = 379,
-    TOKEN_UNBOUNDED = 380,
-    TOKEN_UNIQUE = 381,
-    TOKEN_UPDATE = 382,
-    TOKEN_USING = 383,
-    TOKEN_VALUES = 384,
-    TOKEN_VARCHAR = 385,
-    TOKEN_WHEN = 386,
-    TOKEN_WHERE = 387,
-    TOKEN_WINDOW = 388,
-    TOKEN_WITH = 389,
-    TOKEN_YEAR = 390,
-    TOKEN_YEARMONTH = 391,
-    TOKEN_EOF = 392,
-    TOKEN_LEX_ERROR = 393
+    TOKEN_LBRACE = 339,
+    TOKEN_LEFT = 340,
+    TOKEN_LIMIT = 341,
+    TOKEN_LONG = 342,
+    TOKEN_MINUTE = 343,
+    TOKEN_MONTH = 344,
+    TOKEN_NULL = 345,
+    TOKEN_NULLS = 346,
+    TOKEN_OFF = 347,
+    TOKEN_ON = 348,
+    TOKEN_ORDER = 349,
+    TOKEN_OUTER = 350,
+    TOKEN_OVER = 351,
+    TOKEN_PARTITION = 352,
+    TOKEN_PARTITIONS = 353,
+    TOKEN_PERCENT = 354,
+    TOKEN_PRECEDING = 355,
+    TOKEN_PRIMARY = 356,
+    TOKEN_PRIORITY = 357,
+    TOKEN_QUIT = 358,
+    TOKEN_RANGE = 359,
+    TOKEN_RBRACE = 360,
+    TOKEN_REAL = 361,
+    TOKEN_REFERENCES = 362,
+    TOKEN_RIGHT = 363,
+    TOKEN_ROW = 364,
+    TOKEN_ROW_DELIMITER = 365,
+    TOKEN_ROWS = 366,
+    TOKEN_SECOND = 367,
+    TOKEN_SELECT = 368,
+    TOKEN_SET = 369,
+    TOKEN_SMA = 370,
+    TOKEN_SMALLINT = 371,
+    TOKEN_STDERR = 372,
+    TOKEN_STDOUT = 373,
+    TOKEN_SUBSTRING = 374,
+    TOKEN_TABLE = 375,
+    TOKEN_THEN = 376,
+    TOKEN_TIME = 377,
+    TOKEN_TIMESTAMP = 378,
+    TOKEN_TO = 379,
+    TOKEN_TRUE = 380,
+    TOKEN_TUPLESAMPLE = 381,
+    TOKEN_UNBOUNDED = 382,
+    TOKEN_UNIQUE = 383,
+    TOKEN_UPDATE = 384,
+    TOKEN_USING = 385,
+    TOKEN_VALUES = 386,
+    TOKEN_VARCHAR = 387,
+    TOKEN_WHEN = 388,
+    TOKEN_WHERE = 389,
+    TOKEN_WINDOW = 390,
+    TOKEN_WITH = 391,
+    TOKEN_YEAR = 392,
+    TOKEN_YEARMONTH = 393,
+    TOKEN_EOF = 394,
+    TOKEN_LEX_ERROR = 395
   };
 #endif
 
@@ -264,6 +266,7 @@ union YYSTYPE
   quickstep::ParseString *unary_operation_;
   quickstep::ParseString *binary_operation_;
 
+  quickstep::ParseArray *array_expression_;
   quickstep::ParseFunctionCall *function_call_;
   quickstep::PtrList<quickstep::ParseExpression> *expression_list_;
 
@@ -290,7 +293,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 294 "SqlParser_gen.hpp" /* yacc.c:1915  */
+#line 297 "SqlParser_gen.hpp" /* yacc.c:1915  */
 };
 
 typedef union YYSTYPE YYSTYPE;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 959fc7e..7c257bb 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -2381,6 +2381,11 @@ E::ScalarPtr Resolver::resolveExpression(
     const Type *type_hint,
     ExpressionResolutionInfo *expression_resolution_info) {
   switch (parse_expression.getExpressionType()) {
+    case ParseExpression::kArray: {
+      const ParseArray &parse_array =
+          static_cast<const ParseArray&>(parse_expression);
+      return resolveArray(parse_array, type_hint, expression_resolution_info);
+    }
     case ParseExpression::kAttribute: {
       const ParseAttribute &parse_attribute_scalar =
           static_cast<const ParseAttribute&>(parse_expression);
@@ -2484,6 +2489,29 @@ E::ScalarPtr Resolver::resolveExpression(
   }
 }
 
+E::ScalarPtr Resolver::resolveArray(
+    const ParseArray &parse_array,
+    const Type *type_hint,
+    ExpressionResolutionInfo *expression_resolution_info) {
+//  std::vector<E::ScalarPtr> elements;
+//  const auto &parse_elements = parse_array.elements();
+//  if (parse_elements.empty()) {
+//    // TODO(jianqiao): Figure out how to handle empty array.
+//
+//  } else {
+//    elements.reserve(parse_elements.size());
+//    for (const auto &parse_element : parse_elements) {
+//      elements.emplace_back(
+//          resolveExpression(*parse_element, nullptr, expression_resolution_info));
+//    }
+//
+//    // Currently we only support homogeneous array with literal values.
+//  }
+
+  LOG(FATAL) << "Not supported";
+}
+
+
 E::ScalarPtr Resolver::resolveSearchedCaseExpression(
     const ParseSearchedCaseExpression &parse_searched_case_expression,
     const Type *type_hint,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/query_optimizer/resolver/Resolver.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.hpp b/query_optimizer/resolver/Resolver.hpp
index bb924bb..c44d8ef 100644
--- a/query_optimizer/resolver/Resolver.hpp
+++ b/query_optimizer/resolver/Resolver.hpp
@@ -41,6 +41,7 @@ namespace quickstep {
 class CatalogDatabase;
 class CatalogRelation;
 class Comparison;
+class ParseArray;
 class ParseExpression;
 class ParseFunctionCall;
 class ParseGeneratorTableReference;
@@ -446,6 +447,11 @@ class Resolver {
       const Type *type_hint,
       ExpressionResolutionInfo *expression_resolution_info);
 
+  expressions::ScalarPtr resolveArray(
+      const ParseArray &parse_array,
+      const Type *type_hint,
+      ExpressionResolutionInfo *expression_resolution_info);
+
   /**
    * @brief Resolves a searched CASE expression.
    *

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
index 198e580..c0f3a87 100644
--- a/types/ArrayType.cpp
+++ b/types/ArrayType.cpp
@@ -35,7 +35,7 @@ std::string ArrayType::printValueToString(const UntypedLiteral *value) const {
   if (!literals.empty()) {
     ret.append(element_type_.printValueToString(literals.front()));
     for (std::size_t i = 1; i < literals.size(); ++i) {
-      ret.append(", ");
+      ret.append(",");
       ret.append(element_type_.printValueToString(literals.at(i)));
     }
   }


[21/38] incubator-quickstep git commit: Some updates

Posted by ji...@apache.org.
Some updates


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/98a8e611
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/98a8e611
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/98a8e611

Branch: refs/heads/refactor-type
Commit: 98a8e611a33219c3e0619217e6e062f608d03fa4
Parents: 9b23a4d
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Wed Sep 27 21:12:59 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 parser/SqlLexer.lpp                             |    1 +
 parser/SqlParser.ypp                            |   26 +-
 parser/preprocessed/SqlLexer_gen.cpp            | 1143 +++---
 parser/preprocessed/SqlLexer_gen.hpp            |    2 +-
 parser/preprocessed/SqlParser_gen.cpp           | 3247 +++++++++---------
 parser/preprocessed/SqlParser_gen.hpp           |  167 +-
 query_optimizer/rules/CMakeLists.txt            |    4 +-
 query_optimizer/rules/Partition.cpp             |   16 +-
 types/CMakeLists.txt                            |    1 +
 types/NullLit.hpp                               |   38 +
 types/NullType.hpp                              |    2 +-
 types/TypeFactory.cpp                           |    2 +-
 types/TypeID.hpp                                |   10 +-
 types/TypeRegistrar.hpp                         |   38 +-
 types/TypeSynthesizer.hpp                       |   47 +-
 types/TypeUtil.hpp                              |    4 +-
 types/containers/ColumnVector.hpp               |   57 +-
 types/containers/ColumnVectorsValueAccessor.hpp |    3 +-
 types/operations/OperationUtil.hpp              |    6 +-
 .../BinaryOperationWrapper.hpp                  |    6 +-
 .../unary_operations/UnaryOperationWrapper.hpp  |    2 +-
 21 files changed, 2463 insertions(+), 2359 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/parser/SqlLexer.lpp
----------------------------------------------------------------------
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index 92268e8..020673c 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -301,6 +301,7 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   ">"                return TOKEN_GT;
   "<="               return TOKEN_LEQ;
   ">="               return TOKEN_GEQ;
+  "::"               return TOKEN_DOUBLECOLON;
 
   [-+*/%(),.;]       return yytext[0];
   [\[\]]             return yytext[0];

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/parser/SqlParser.ypp
----------------------------------------------------------------------
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index af79fe3..0d19a4c 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -272,6 +272,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_DESC;
 %token TOKEN_DISTINCT;
 %token TOKEN_DOUBLE;
+%token TOKEN_DOUBLECOLON;
 %token TOKEN_DROP;
 %token TOKEN_ELSE;
 %token TOKEN_END;
@@ -1776,7 +1777,30 @@ cast_function:
     auto *name = new quickstep::ParseString(@1.first_line, @1.first_column, "cast");
     $$ = new quickstep::ParseFunctionCall(
         @1.first_line, @1.first_column, false, name, arguments);
-  };
+  }
+  | expression_base TOKEN_DOUBLECOLON data_type {
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($1);
+    arguments->push_back(new quickstep::ParseScalarLiteral(
+        new quickstep::StringParseLiteralValue(
+            new quickstep::ParseString(@3.first_line,
+                                       @3.first_column,
+                                       $3->getType().getName()),
+            nullptr)));
+    delete $3;
+    auto *name = new quickstep::ParseString(@2.first_line, @2.first_column, "cast");
+    $$ = new quickstep::ParseFunctionCall(
+        @2.first_line, @2.first_column, false, name, arguments);
+  }
+  | expression_base TOKEN_DOUBLECOLON any_name {
+    auto *arguments = new quickstep::PtrList<quickstep::ParseExpression>();
+    arguments->push_back($1);
+    arguments->push_back(new quickstep::ParseScalarLiteral(
+        new quickstep::StringParseLiteralValue($3, nullptr)));
+    auto *name = new quickstep::ParseString(@2.first_line, @2.first_column, "cast");
+    $$ = new quickstep::ParseFunctionCall(
+        @2.first_line, @2.first_column, false, name, arguments);
+  }
 
 extract_function:
   TOKEN_EXTRACT '(' datetime_unit TOKEN_FROM add_expression ')' {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/parser/preprocessed/SqlLexer_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.cpp b/parser/preprocessed/SqlLexer_gen.cpp
index b1ea67f..0904d7c 100644
--- a/parser/preprocessed/SqlLexer_gen.cpp
+++ b/parser/preprocessed/SqlLexer_gen.cpp
@@ -592,8 +592,8 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 165
-#define YY_END_OF_BUFFER 166
+#define YY_NUM_RULES 166
+#define YY_END_OF_BUFFER 167
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -601,72 +601,74 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_accept[590] =
+static const flex_int16_t yy_accept[592] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  166,    2,    2,  164,  164,  163,  162,  164,
-      141,  137,  140,  137,  137,  160,  133,  130,  134,  159,
-      159,  159,  159,  159,  159,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,  159,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,  138,    4,    5,    5,    3,  156,
-      156,  153,  157,  157,  151,  158,  158,  155,    1,  163,
-      131,  161,  160,  160,  160,    0,  135,  132,  136,  159,
-      159,  159,  159,   10,  159,  159,  159,   23,  159,  159,
-      159,  159,  159,  159,  159,  159,  159,  159,  159,  139,
-
-      159,  159,  159,  159,  159,  159,  159,  159,  159,  159,
-      159,  159,   59,   68,  159,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,  159,   82,   83,  159,  159,  159,
-      159,  159,  159,  159,  159,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,  114,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,    4,    5,    3,  156,  152,  157,
-      150,  150,  142,  144,  145,  146,  147,  148,  149,  150,
-      158,  154,  161,  160,    0,  160,    6,    7,  159,    9,
-       11,  159,  159,   15,  159,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,  159,   34,  159,  159,  159,  159,
-
-      159,  159,  159,  159,   44,  159,  159,  159,  159,  159,
-      159,   51,  159,  159,  159,  159,  159,  159,  159,  159,
-      159,   63,  159,   70,  159,  159,  159,  159,  159,  159,
-      159,   78,  159,   81,  159,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,  159,  159,  159,   99,  159,  159,
-      104,  105,  159,  159,  159,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,  159,  159,  159,  159,  159,  142,
-      144,  143,  159,  159,  159,  159,  159,  159,  159,   20,
-       21,   24,  159,  159,  159,   29,  159,  159,  159,   32,
-      159,  159,  159,   38,  159,  159,   42,   43,  159,  159,
-
-      159,  159,  159,  159,  159,   53,   54,  159,   56,  159,
-       58,  159,  159,  159,  159,   67,   69,   71,   72,   73,
-      159,   75,  159,  159,   79,  159,  159,   86,  159,  159,
-      159,  159,  159,   93,  159,   95,  159,  159,  159,  101,
-      159,  159,  159,  159,  159,  159,  159,  159,  111,  112,
-      115,  159,  159,  159,  159,  159,  159,  159,  159,  124,
-      159,  159,  127,  128,  142,  143,    8,  159,  159,  159,
-      159,  159,  159,  159,   26,  159,  159,  159,  159,  159,
-      159,  159,  159,  159,  159,  159,  159,  159,  159,   47,
-       48,   49,  159,  159,   55,  159,   60,   61,  159,  159,
-
-      159,   74,  159,   77,   80,   84,   85,  159,  159,  159,
-      159,  159,   94,  159,  159,   98,  159,  159,  159,  159,
-      159,  159,  159,  110,  159,  159,  159,  118,  159,  159,
-      121,  159,  159,  125,  159,  159,  159,  159,   14,  159,
-      159,  159,  159,  159,   27,  159,   30,  159,  159,  159,
-      159,  159,   37,  159,  159,   41,   45,  159,  159,  159,
-       57,   62,  159,  159,  159,   76,  159,  159,  159,  159,
-      159,  159,   97,  159,  102,  103,  159,  107,  108,  159,
-      159,  159,  159,  119,  120,  122,  159,  126,  159,  159,
-       13,  159,  159,  159,  159,  159,  159,   22,   31,  159,
-
-       35,   36,  159,  159,   46,  159,   52,   64,  159,  159,
-      159,   89,  159,   91,  159,  159,  159,  159,  159,  159,
-      159,  159,  123,  159,  159,  159,  159,  159,  159,  159,
-      159,   33,  159,   40,  159,  159,   66,  159,  159,   92,
-      159,  159,  106,  159,  159,  159,  159,  159,   12,  159,
-      159,  159,  159,   25,  159,  159,   50,   65,   87,   90,
-      159,  159,  109,  113,  159,  117,  129,   16,  159,  159,
-      159,   28,   39,   88,   96,  159,  159,  159,   18,   19,
-      159,  116,  159,  159,  159,  100,  159,   17,    0
+        0,    0,  167,    2,    2,  165,  165,  164,  163,  165,
+      142,  138,  141,  138,  138,  161,  165,  133,  130,  134,
+      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
+      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
+      160,  160,  160,  160,  160,  139,    4,    5,    5,    3,
+      157,  157,  154,  158,  158,  152,  159,  159,  156,    1,
+      164,  131,  162,  161,  161,  161,    0,  137,  135,  132,
+      136,  160,  160,  160,  160,   10,  160,  160,  160,   23,
+      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
+
+      160,  140,  160,  160,  160,  160,  160,  160,  160,  160,
+      160,  160,  160,  160,   59,   68,  160,  160,  160,  160,
+      160,  160,  160,  160,  160,  160,  160,   82,   83,  160,
+      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
+      160,  160,  160,  160,  160,  160,  114,  160,  160,  160,
+      160,  160,  160,  160,  160,  160,    4,    5,    3,  157,
+      153,  158,  151,  151,  143,  145,  146,  147,  148,  149,
+      150,  151,  159,  155,  162,  161,    0,  161,    6,    7,
+      160,    9,   11,  160,  160,   15,  160,  160,  160,  160,
+      160,  160,  160,  160,  160,  160,  160,   34,  160,  160,
+
+      160,  160,  160,  160,  160,  160,   44,  160,  160,  160,
+      160,  160,  160,   51,  160,  160,  160,  160,  160,  160,
+      160,  160,  160,   63,  160,   70,  160,  160,  160,  160,
+      160,  160,  160,   78,  160,   81,  160,  160,  160,  160,
+      160,  160,  160,  160,  160,  160,  160,  160,  160,   99,
+      160,  160,  104,  105,  160,  160,  160,  160,  160,  160,
+      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
+      160,  143,  145,  144,  160,  160,  160,  160,  160,  160,
+      160,   20,   21,   24,  160,  160,  160,   29,  160,  160,
+      160,   32,  160,  160,  160,   38,  160,  160,   42,   43,
+
+      160,  160,  160,  160,  160,  160,  160,   53,   54,  160,
+       56,  160,   58,  160,  160,  160,  160,   67,   69,   71,
+       72,   73,  160,   75,  160,  160,   79,  160,  160,   86,
+      160,  160,  160,  160,  160,   93,  160,   95,  160,  160,
+      160,  101,  160,  160,  160,  160,  160,  160,  160,  160,
+      111,  112,  115,  160,  160,  160,  160,  160,  160,  160,
+      160,  124,  160,  160,  127,  128,  143,  144,    8,  160,
+      160,  160,  160,  160,  160,  160,   26,  160,  160,  160,
+      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
+      160,   47,   48,   49,  160,  160,   55,  160,   60,   61,
+
+      160,  160,  160,   74,  160,   77,   80,   84,   85,  160,
+      160,  160,  160,  160,   94,  160,  160,   98,  160,  160,
+      160,  160,  160,  160,  160,  110,  160,  160,  160,  118,
+      160,  160,  121,  160,  160,  125,  160,  160,  160,  160,
+       14,  160,  160,  160,  160,  160,   27,  160,   30,  160,
+      160,  160,  160,  160,   37,  160,  160,   41,   45,  160,
+      160,  160,   57,   62,  160,  160,  160,   76,  160,  160,
+      160,  160,  160,  160,   97,  160,  102,  103,  160,  107,
+      108,  160,  160,  160,  160,  119,  120,  122,  160,  126,
+      160,  160,   13,  160,  160,  160,  160,  160,  160,   22,
+
+       31,  160,   35,   36,  160,  160,   46,  160,   52,   64,
+      160,  160,  160,   89,  160,   91,  160,  160,  160,  160,
+      160,  160,  160,  160,  123,  160,  160,  160,  160,  160,
+      160,  160,  160,   33,  160,   40,  160,  160,   66,  160,
+      160,   92,  160,  160,  106,  160,  160,  160,  160,  160,
+       12,  160,  160,  160,  160,   25,  160,  160,   50,   65,
+       87,   90,  160,  160,  109,  113,  160,  117,  129,   16,
+      160,  160,  160,   28,   39,   88,   96,  160,  160,  160,
+       18,   19,  160,  116,  160,  160,  160,  100,  160,   17,
+        0
+
     } ;
 
 static const YY_CHAR yy_ec[256] =
@@ -713,311 +715,311 @@ static const YY_CHAR yy_meta[72] =
         8
     } ;
 
-static const flex_int16_t yy_base[605] =
+static const flex_int16_t yy_base[607] =
     {   0,
         0,    1,   46,    0,  117,  162,    2,    3,  127,  128,
-        6,   10,  147, 1317, 1317,    0, 1317,   13, 1317,  130,
-     1317, 1317, 1317,  129,    6,  129,    4, 1317,   28,  124,
-      159,  213,  165,  167,  263,   92,  158,  163,   96,  107,
-      214,  160,  186,  219,  221,  155,  281,  274,  325,  257,
-      186,  209,    0,  219, 1317,   27,    4,   19,    0,    0,
-        0,   17,    0,    0,  389,    0,    0,    8,    0,   22,
-     1317,    0,  293,  325,  343,   18, 1317, 1317, 1317,    0,
-      223,  265,  234,  242,  260,  292,  288,    0,  299,  330,
-      337,  324,  334,  324,  325,  380,  325,  331,  346, 1317,
-
-      348,  364,  378,  376,  371,  378,  382,  386,  390,  389,
-      386,  385,  435,    0,  402,  389,  400,  435,  433,  431,
-      433,  436,  431,  440,  447,    0,  452,  437,  453,  441,
-      442,  456,  453,  449,  465,  457,  444,  494,  468,  495,
-      500,  501,  499,  492,    0,  486,  492,  507,  506,  502,
-      500,  508,  501,  516,    0,   29,    0,    0, 1317,    0,
-     1317, 1317,   22,   24, 1317, 1317, 1317, 1317, 1317,    0,
-        0, 1317,    0,  524,   26,   28,    0,    0,  517,    0,
-      518,  501,  516,  504,  545,  544,  512,  552,  536,  542,
-      537,  562,  545,  548,  562,    0,  559,  568,  565,  568,
-
-      552,  571,  558,  570,    0,  557,  561,  561,  562,  581,
-      571,  580,  574,  576,  585,  599,  604,  597,  613,  614,
-      615,  616,  608,    0,  603,  604,  620,  617,  620,  607,
-      609,    0,  618,    0,  627,  628,  616,  617,  635,  636,
-      628,  620,  638,  634,  659,  660,  663,  654,  661,  672,
-        0,  666,  674,  661,  669,  668,  679,  680,  674,  672,
-      673,  690,  678,  674,  693,  683,  694,  691,  685,   30,
-      125,    0,  686,  698,  717,  709,  724,  720,  721,    0,
-        0,  734,  725,  724,  718,    0,  719,  722,  737,  723,
-      731,  724,  726,  742,  739,  737,    0,    0,  730,  752,
-
-      749,  735,  736,  742,  750,    0,    0,  745,    0,  748,
-        0,  746,  762,  763,  780,    0,    0,    0,    0,    0,
-      769,    0,  772,  785,  775,  777,  778,    0,  788,  795,
-      796,  801,  785,    0,  799,    0,  787,  782,  787,    0,
-      804,  797,  809,  801,  796,  794,  797,  814,    0,  801,
-        0,  823,  817,  825,  824,  827,  843,  846,  844,    0,
-      848,  839,    0,  842,  131, 1317,    0,  852,  853,  839,
-      859,  845,  856,  860,    0,  851,  848,  864,  865,  857,
-      863,  872,  863,  872,  864,  872,  891,  878,  900,    0,
-        0,    0,  882,  901,    0,  902,    0,    0,  890,  906,
-
-      894,    0,  907,    0,    0,    0,    0,  894,  903,  914,
-      901,  911,    0,  916,  906,    0,  918,  920,  907,  919,
-      911,  910,  913,    0,  913,  916,  922,    0,  939,  949,
-        0,  936,  960,    0,  940,  951,  958,  954,    0,  947,
-      952,  970,  963,  954,    0,  974,    0,  971,  957,  965,
-      967,  960,    0,  977,  979,    0,    0,  965,  977,  973,
-        0,    0,  970,  984,  990,    0,  984,  974,  993,  987,
-      993, 1005,    0, 1009,    0,    0, 1010,    0,    0, 1016,
-     1025, 1026, 1024,    0,    0,    0, 1011,    0, 1016, 1018,
-        0, 1024, 1019, 1022, 1024, 1032, 1029,    0,    0, 1034,
-
-        0,    0, 1031, 1023,    0, 1030,    0,    0, 1042, 1034,
-     1032,    0, 1035,    0, 1026, 1049, 1051, 1050, 1057, 1064,
-     1066, 1077,    0, 1063, 1077, 1071, 1070, 1071, 1068, 1072,
-     1077,    0, 1078,    0, 1086, 1074,    0, 1081, 1089,    0,
-     1092, 1085,    0, 1094, 1086, 1087, 1100, 1097,    0, 1100,
-     1104, 1098, 1113,    0, 1108, 1122,    0,    0, 1116,    0,
-     1118, 1131,    0,    0, 1129,    0,    0,    0, 1124, 1138,
-     1126,    0,    0,    0,    0, 1125, 1141, 1128,    0,    0,
-     1144,    0, 1141, 1133, 1147,    0, 1134,    0, 1317, 1199,
-     1209, 1219, 1229, 1239, 1243, 1246, 1252, 1262, 1272, 1282,
-
-     1292, 1302, 1307, 1309
+        6,   10,  148, 1317, 1317,    0, 1317,   13, 1317,  131,
+     1317, 1317, 1317,  136,    6,  129,  125,    4, 1317,   28,
+      124,  159,  213,  165,  167,  263,   92,  158,  163,   96,
+      107,  214,  160,  186,  219,  221,  155,  281,  274,  325,
+      257,  186,  209,    0,  219, 1317,   27,    4,   19,    0,
+        0,    0,   17,    0,    0,  389,    0,    0,    8,    0,
+       22, 1317,    0,  293,  325,  343,   18, 1317, 1317, 1317,
+     1317,    0,  223,  265,  234,  242,  260,  292,  288,    0,
+      299,  330,  337,  324,  334,  324,  325,  380,  325,  331,
+
+      346, 1317,  348,  364,  378,  376,  371,  378,  382,  386,
+      390,  389,  386,  385,  435,    0,  402,  389,  400,  435,
+      433,  431,  433,  436,  431,  440,  447,    0,  452,  437,
+      453,  441,  442,  456,  453,  449,  465,  457,  444,  494,
+      468,  495,  500,  501,  499,  492,    0,  486,  492,  507,
+      506,  502,  500,  508,  501,  516,    0,   29,    0,    0,
+     1317,    0, 1317, 1317,   22,   24, 1317, 1317, 1317, 1317,
+     1317,    0,    0, 1317,    0,  524,   26,   28,    0,    0,
+      517,    0,  518,  501,  516,  504,  545,  544,  512,  552,
+      536,  542,  537,  562,  545,  548,  562,    0,  559,  568,
+
+      565,  568,  552,  571,  558,  570,    0,  557,  561,  561,
+      562,  581,  571,  580,  574,  576,  585,  599,  604,  597,
+      613,  614,  615,  616,  608,    0,  603,  604,  620,  617,
+      620,  607,  609,    0,  618,    0,  627,  628,  616,  617,
+      635,  636,  628,  620,  638,  634,  659,  660,  663,  654,
+      661,  672,    0,  666,  674,  661,  669,  668,  679,  680,
+      674,  672,  673,  690,  678,  674,  693,  683,  694,  691,
+      685,   30,  125,    0,  686,  698,  717,  709,  724,  720,
+      721,    0,    0,  734,  725,  724,  718,    0,  719,  722,
+      737,  723,  731,  724,  726,  742,  739,  737,    0,    0,
+
+      730,  752,  749,  735,  736,  742,  750,    0,    0,  745,
+        0,  748,    0,  746,  762,  763,  780,    0,    0,    0,
+        0,    0,  769,    0,  772,  785,  775,  777,  778,    0,
+      788,  795,  796,  801,  785,    0,  799,    0,  787,  782,
+      787,    0,  804,  797,  809,  801,  796,  794,  797,  814,
+        0,  801,    0,  823,  817,  825,  824,  827,  843,  846,
+      844,    0,  848,  839,    0,  842,  131, 1317,    0,  852,
+      853,  839,  859,  845,  856,  860,    0,  851,  848,  864,
+      865,  857,  863,  872,  863,  872,  864,  872,  891,  878,
+      900,    0,    0,    0,  882,  901,    0,  902,    0,    0,
+
+      890,  906,  894,    0,  907,    0,    0,    0,    0,  894,
+      903,  914,  901,  911,    0,  916,  906,    0,  918,  920,
+      907,  919,  911,  910,  913,    0,  913,  916,  922,    0,
+      939,  949,    0,  936,  960,    0,  940,  951,  958,  954,
+        0,  947,  952,  970,  963,  954,    0,  974,    0,  971,
+      957,  965,  967,  960,    0,  977,  979,    0,    0,  965,
+      977,  973,    0,    0,  970,  984,  990,    0,  984,  974,
+      993,  987,  993, 1005,    0, 1009,    0,    0, 1010,    0,
+        0, 1016, 1025, 1026, 1024,    0,    0,    0, 1011,    0,
+     1016, 1018,    0, 1024, 1019, 1022, 1024, 1032, 1029,    0,
+
+        0, 1034,    0,    0, 1031, 1023,    0, 1030,    0,    0,
+     1042, 1034, 1032,    0, 1035,    0, 1026, 1049, 1051, 1050,
+     1057, 1064, 1066, 1077,    0, 1063, 1077, 1071, 1070, 1071,
+     1068, 1072, 1077,    0, 1078,    0, 1086, 1074,    0, 1081,
+     1089,    0, 1092, 1085,    0, 1094, 1086, 1087, 1100, 1097,
+        0, 1100, 1104, 1098, 1113,    0, 1108, 1122,    0,    0,
+     1116,    0, 1118, 1131,    0,    0, 1129,    0,    0,    0,
+     1124, 1138, 1126,    0,    0,    0,    0, 1125, 1141, 1128,
+        0,    0, 1144,    0, 1141, 1133, 1147,    0, 1134,    0,
+     1317, 1199, 1209, 1219, 1229, 1239, 1243, 1246, 1252, 1262,
+
+     1272, 1282, 1292, 1302, 1307, 1309
     } ;
 
-static const flex_int16_t yy_def[605] =
+static const flex_int16_t yy_def[607] =
     {   0,
-      590,  590,  589,    3,  591,  591,  592,  592,  593,  593,
-      594,  594,  589,  589,  589,  595,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  589,  589,  589,  589,  597,  598,
-      598,  589,  599,  599,  600,  601,  601,  589,  595,  589,
-      589,  602,  589,  589,  589,  589,  589,  589,  589,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  589,
-
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  589,  589,  597,  598,  589,  599,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  603,
-      601,  589,  602,  589,  589,  589,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  589,
-      589,  604,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  589,  589,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,    0,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-
-      589,  589,  589,  589
+      592,  592,  591,    3,  593,  593,  594,  594,  595,  595,
+      596,  596,  591,  591,  591,  597,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  591,  591,  591,  591,  599,
+      600,  600,  591,  601,  601,  602,  603,  603,  591,  597,
+      591,  591,  604,  591,  591,  591,  591,  591,  591,  591,
+      591,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+
+      598,  591,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  591,  591,  599,  600,
+      591,  601,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  605,  603,  591,  604,  591,  591,  591,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  591,  591,  606,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  591,  591,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+        0,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+
+      591,  591,  591,  591,  591,  591
     } ;
 
 static const flex_int16_t yy_nxt[1389] =
     {   0,
-      589,  155,   15,   15,   61,   61,  156,  156,   67,   62,
-       62,   68,   67,  172,   70,   68,   70,   73,   73,   77,
-       78,  156,  156,   70,  159,   70,  175,  175,  155,  176,
-      176,  156,  156,  270,  271,  271,  271,  176,  176,  176,
-      176,  365,  271,   79,   16,   16,   17,   18,   19,   18,
-       20,   21,   22,   23,   22,   24,   25,   26,   26,   17,
-       27,   28,   29,   30,   31,   32,   33,   34,   35,   36,
-       37,   38,   39,   40,   41,   42,   43,   44,   45,   46,
-       47,   48,   49,   50,   51,   52,   53,   54,   53,   55,
-       17,   17,   30,   31,   32,   33,   34,   35,   36,   37,
-
+      591,  157,   15,   15,   62,   62,  158,  158,   68,   63,
+       63,   69,   68,  174,   71,   69,   71,   74,   74,   79,
+       80,  158,  158,   71,  161,   71,  177,  177,  157,  178,
+      178,  158,  158,  272,  273,  273,  273,  178,  178,  178,
+      178,  367,  273,   81,   16,   16,   17,   18,   19,   18,
+       20,   21,   22,   23,   22,   24,   25,   26,   26,   27,
+       28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
        38,   39,   40,   41,   42,   43,   44,   45,   46,   47,
-       48,   49,   50,   51,   52,   53,   54,   17,   56,   57,
-       58,   17,   17,   17,   17,   17,  110,  115,  116,   64,
-       64,   17,   17,   17,   62,   62,  271,  271,   72,   74,
-       75,   75,  271,  271,   81,   71,  589,  589,  589,  589,
-       76,  589,   82,  589,   83,  110,  115,  116,  589,   84,
-       17,   17,   17,   56,   57,   58,   17,   17,   17,   17,
-       17,   65,   65,   81,  100,  111,   17,   17,   17,   76,
-       85,   82,   95,   83,   86,  121,   96,   87,   84,  112,
-       97,  122,  133,  113,  589,  101,   98,  102,  114,   99,
-
-       88,  589,  589,  151,  111,   17,   17,  103,  589,   85,
-      589,   95,  589,   86,  121,   96,   87,  123,  112,   97,
-      122,  133,  113,  124,  101,   98,  102,  114,   99,   88,
-       89,  117,  151,  152,  153,  118,  103,   90,  130,  119,
-      154,  125,  131,  177,   91,  120,  123,   92,   93,  126,
-       94,  589,  124,  127,  180,  132,  128,  129,  589,   89,
-      117,  181,  152,  153,  118,  589,   90,  130,  119,  154,
-      125,  131,  177,   91,  120,  589,   92,   93,  126,   94,
-      104,  589,  127,  180,  132,  128,  129,  148,  105,  149,
-      181,  106,  150,  178,  107,  138,  182,  108,  134,  589,
-
-      109,  179,  135,  139,   73,   73,  136,  589,  589,  104,
-      140,  141,  137,  589,   76,  183,  148,  105,  149,  185,
-      106,  150,  178,  107,  138,  182,  108,  134,  184,  109,
-      179,  135,  139,  589,  186,  136,  174,  174,  589,  140,
-      141,  137,  142,   76,  183,  192,   76,  187,  185,  143,
-      144,  188,  193,   74,   75,   75,  145,  184,  194,  146,
-      201,  195,  147,  186,   76,  189,  196,  190,  202,  191,
-      589,  142,  589,  589,  192,   76,  187,  203,  143,  144,
-      188,  193,  589,  204,  205,  145,  589,  194,  146,  201,
-      195,  147,  162,   76,  189,  196,  190,  202,  191,  197,
-
-      163,  164,  198,  206,  208,  209,  203,  165,  199,  210,
-      211,  166,  204,  205,  207,  200,  212,  213,  214,  167,
-      215,  216,  218,  168,  217,  169,  589,  223,  197,  170,
-      224,  198,  206,  208,  209,  225,  165,  199,  210,  211,
-      166,  589,  589,  207,  200,  212,  213,  214,  167,  215,
-      216,  218,  168,  217,  169,  219,  223,  226,  170,  224,
-      227,  229,  228,  230,  225,  220,  231,  232,  233,  234,
-      221,  222,  235,  236,  237,  238,  239,  240,  242,  243,
-      247,  241,  244,  248,  219,  252,  226,  245,  246,  227,
-      229,  228,  230,  589,  220,  231,  232,  233,  234,  221,
-
-      222,  235,  236,  237,  238,  239,  240,  242,  243,  247,
-      241,  244,  248,  249,  252,  253,  245,  246,  254,  255,
-      256,  257,  250,  258,  259,  260,  262,  263,  264,  266,
-      251,  267,  261,  269,  265,  174,  174,  268,  273,  274,
-      275,  276,  249,  277,  253,   76,  282,  254,  255,  256,
-      257,  250,  258,  259,  260,  262,  263,  264,  266,  251,
-      267,  261,  269,  265,  278,  280,  268,  273,  274,  275,
-      276,  283,  277,  284,   76,  282,  279,  285,  286,  287,
-      281,  288,  289,  290,  291,  292,  293,  294,  295,  296,
-      297,  298,  299,  278,  280,  300,  301,  302,  303,  304,
-
-      283,  305,  284,  306,  307,  279,  285,  286,  287,  281,
-      288,  289,  290,  291,  292,  293,  294,  295,  296,  297,
-      298,  299,  308,  309,  300,  301,  302,  303,  304,  310,
-      305,  311,  306,  307,  312,  313,  314,  315,  317,  318,
-      319,  320,  321,  322,  323,  324,  325,  316,  326,  327,
-      328,  308,  309,  329,  330,  331,  334,  332,  310,  333,
-      311,  335,  336,  312,  313,  314,  315,  317,  318,  319,
-      320,  321,  322,  323,  324,  325,  316,  326,  327,  328,
-      337,  338,  329,  330,  331,  334,  332,  339,  333,  340,
-      335,  336,  342,  343,  344,  345,  347,  348,  349,  341,
-
-      350,  351,  352,  353,  354,  346,  355,  356,  357,  337,
-      338,  358,  359,  360,  362,  363,  339,  361,  340,  364,
-      367,  342,  343,  344,  345,  347,  348,  349,  368,  350,
-      351,  352,  353,  354,  346,  355,  356,  357,  369,  370,
-      358,  359,  360,  362,  363,  371,  361,  372,  364,  367,
-      373,  374,  375,  376,  377,  378,  379,  368,  380,  381,
-      382,  383,  384,  385,  386,  387,  388,  369,  370,  389,
-      390,  391,  392,  393,  371,  394,  372,  395,  396,  373,
-      374,  375,  376,  377,  378,  379,  397,  380,  381,  382,
-      383,  384,  385,  386,  387,  388,  398,  399,  389,  390,
-
-      391,  392,  393,  400,  394,  402,  395,  396,  403,  404,
-      405,  406,  407,  408,  401,  397,  409,  410,  411,  412,
-      413,  414,  415,  416,  417,  398,  399,  418,  419,  420,
-      421,  422,  400,  423,  402,  424,  425,  403,  404,  405,
-      406,  407,  408,  401,  426,  409,  410,  411,  412,  413,
-      414,  415,  416,  417,  427,  428,  418,  419,  420,  421,
-      422,  429,  423,  430,  424,  425,  431,  432,  433,  434,
-      435,  436,  437,  426,  438,  439,  440,  441,  443,  444,
-      442,  445,  446,  427,  428,  447,  448,  449,  450,  451,
-      429,  452,  430,  453,  454,  431,  432,  433,  434,  435,
-
-      436,  437,  455,  438,  439,  440,  441,  443,  444,  442,
-      445,  446,  456,  457,  447,  448,  449,  450,  451,  458,
-      452,  459,  453,  454,  460,  461,  462,  463,  466,  464,
-      467,  455,  465,  468,  469,  470,  471,  472,  473,  474,
-      475,  456,  457,  476,  477,  478,  479,  480,  458,  481,
-      459,  482,  483,  460,  461,  462,  463,  466,  464,  467,
-      484,  465,  468,  469,  470,  471,  472,  473,  474,  475,
-      485,  486,  476,  477,  478,  479,  480,  487,  481,  488,
-      482,  483,  489,  490,  491,  492,  493,  494,  495,  484,
-      496,  497,  498,  499,  500,  501,  502,  503,  504,  485,
-
-      486,  505,  506,  507,  508,  509,  487,  510,  488,  511,
-      512,  489,  490,  491,  492,  493,  494,  495,  513,  496,
-      497,  498,  499,  500,  501,  502,  503,  504,  514,  515,
-      505,  506,  507,  508,  509,  516,  510,  517,  511,  512,
-      518,  519,  520,  521,  522,  523,  524,  513,  525,  526,
-      527,  528,  529,  530,  531,  532,  533,  514,  515,  534,
-      535,  536,  537,  538,  516,  539,  517,  540,  541,  518,
-      519,  520,  521,  522,  523,  524,  542,  525,  526,  527,
-      528,  529,  530,  531,  532,  533,  543,  544,  534,  535,
-      536,  537,  538,  545,  539,  546,  540,  541,  547,  548,
-
-      549,  550,  551,  552,  553,  542,  554,  555,  556,  557,
-      558,  559,  560,  561,  562,  543,  544,  563,  564,  565,
-      566,  567,  545,  568,  546,  569,  570,  547,  548,  549,
-      550,  551,  552,  553,  571,  554,  555,  556,  557,  558,
-      559,  560,  561,  562,  572,  573,  563,  564,  565,  566,
-      567,  574,  568,  575,  569,  570,  576,  577,  578,  579,
-      580,  581,  582,  571,  583,  584,  585,  586,  587,  588,
-      589,  589,  589,  572,  573,  589,  589,  589,  589,  589,
-      574,  589,  575,  589,  589,  576,  577,  578,  579,  580,
-      581,  582,  589,  583,  584,  585,  586,  587,  588,   14,
-
-       14,   14,   14,   14,   14,   14,   14,   14,   14,   59,
-       59,   59,   59,   59,   59,   59,   59,   59,   59,   60,
-       60,   60,   60,   60,   60,   60,   60,   60,   60,   63,
-       63,   63,   63,   63,   63,   63,   63,   63,   63,   66,
-       66,   66,   66,   66,   66,   66,   66,   66,   66,   69,
-       69,   80,   80,   80,  589,   80,  157,  157,  157,  157,
-      589,  157,  158,  158,  158,  589,  158,  158,  158,  158,
-      158,  158,  160,  160,  160,  589,  160,  160,  160,  160,
-      589,  160,  161,  161,  161,  161,  161,  161,  161,  161,
-      161,  161,  171,  171,  589,  171,  171,  171,  171,  171,
-
-      171,  171,  173,  589,  173,  173,  173,  173,  173,  173,
-      173,  173,  272,  272,  366,  366,   13,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589
+       48,   49,   50,   51,   52,   53,   54,   55,   54,   56,
+       17,   17,   31,   32,   33,   34,   35,   36,   37,   38,
+
+       39,   40,   41,   42,   43,   44,   45,   46,   47,   48,
+       49,   50,   51,   52,   53,   54,   55,   17,   57,   58,
+       59,   17,   17,   17,   17,   17,  112,  117,  118,   65,
+       65,   17,   17,   17,   63,   63,  273,  273,   78,   75,
+       76,   76,  273,  273,   83,   73,   72,  591,  591,  591,
+       77,  591,   84,  591,   85,  112,  117,  118,  591,   86,
+       17,   17,   17,   57,   58,   59,   17,   17,   17,   17,
+       17,   66,   66,   83,  102,  113,   17,   17,   17,   77,
+       87,   84,   97,   85,   88,  123,   98,   89,   86,  114,
+       99,  124,  135,  115,  591,  103,  100,  104,  116,  101,
+
+       90,  591,  591,  153,  113,   17,   17,  105,  591,   87,
+      591,   97,  591,   88,  123,   98,   89,  125,  114,   99,
+      124,  135,  115,  126,  103,  100,  104,  116,  101,   90,
+       91,  119,  153,  154,  155,  120,  105,   92,  132,  121,
+      156,  127,  133,  179,   93,  122,  125,   94,   95,  128,
+       96,  591,  126,  129,  182,  134,  130,  131,  591,   91,
+      119,  183,  154,  155,  120,  591,   92,  132,  121,  156,
+      127,  133,  179,   93,  122,  591,   94,   95,  128,   96,
+      106,  591,  129,  182,  134,  130,  131,  150,  107,  151,
+      183,  108,  152,  180,  109,  140,  184,  110,  136,  591,
+
+      111,  181,  137,  141,   74,   74,  138,  591,  591,  106,
+      142,  143,  139,  591,   77,  185,  150,  107,  151,  187,
+      108,  152,  180,  109,  140,  184,  110,  136,  186,  111,
+      181,  137,  141,  591,  188,  138,  176,  176,  591,  142,
+      143,  139,  144,   77,  185,  194,   77,  189,  187,  145,
+      146,  190,  195,   75,   76,   76,  147,  186,  196,  148,
+      203,  197,  149,  188,   77,  191,  198,  192,  204,  193,
+      591,  144,  591,  591,  194,   77,  189,  205,  145,  146,
+      190,  195,  591,  206,  207,  147,  591,  196,  148,  203,
+      197,  149,  164,   77,  191,  198,  192,  204,  193,  199,
+
+      165,  166,  200,  208,  210,  211,  205,  167,  201,  212,
+      213,  168,  206,  207,  209,  202,  214,  215,  216,  169,
+      217,  218,  220,  170,  219,  171,  591,  225,  199,  172,
+      226,  200,  208,  210,  211,  227,  167,  201,  212,  213,
+      168,  591,  591,  209,  202,  214,  215,  216,  169,  217,
+      218,  220,  170,  219,  171,  221,  225,  228,  172,  226,
+      229,  231,  230,  232,  227,  222,  233,  234,  235,  236,
+      223,  224,  237,  238,  239,  240,  241,  242,  244,  245,
+      249,  243,  246,  250,  221,  254,  228,  247,  248,  229,
+      231,  230,  232,  591,  222,  233,  234,  235,  236,  223,
+
+      224,  237,  238,  239,  240,  241,  242,  244,  245,  249,
+      243,  246,  250,  251,  254,  255,  247,  248,  256,  257,
+      258,  259,  252,  260,  261,  262,  264,  265,  266,  268,
+      253,  269,  263,  271,  267,  176,  176,  270,  275,  276,
+      277,  278,  251,  279,  255,   77,  284,  256,  257,  258,
+      259,  252,  260,  261,  262,  264,  265,  266,  268,  253,
+      269,  263,  271,  267,  280,  282,  270,  275,  276,  277,
+      278,  285,  279,  286,   77,  284,  281,  287,  288,  289,
+      283,  290,  291,  292,  293,  294,  295,  296,  297,  298,
+      299,  300,  301,  280,  282,  302,  303,  304,  305,  306,
+
+      285,  307,  286,  308,  309,  281,  287,  288,  289,  283,
+      290,  291,  292,  293,  294,  295,  296,  297,  298,  299,
+      300,  301,  310,  311,  302,  303,  304,  305,  306,  312,
+      307,  313,  308,  309,  314,  315,  316,  317,  319,  320,
+      321,  322,  323,  324,  325,  326,  327,  318,  328,  329,
+      330,  310,  311,  331,  332,  333,  336,  334,  312,  335,
+      313,  337,  338,  314,  315,  316,  317,  319,  320,  321,
+      322,  323,  324,  325,  326,  327,  318,  328,  329,  330,
+      339,  340,  331,  332,  333,  336,  334,  341,  335,  342,
+      337,  338,  344,  345,  346,  347,  349,  350,  351,  343,
+
+      352,  353,  354,  355,  356,  348,  357,  358,  359,  339,
+      340,  360,  361,  362,  364,  365,  341,  363,  342,  366,
+      369,  344,  345,  346,  347,  349,  350,  351,  370,  352,
+      353,  354,  355,  356,  348,  357,  358,  359,  371,  372,
+      360,  361,  362,  364,  365,  373,  363,  374,  366,  369,
+      375,  376,  377,  378,  379,  380,  381,  370,  382,  383,
+      384,  385,  386,  387,  388,  389,  390,  371,  372,  391,
+      392,  393,  394,  395,  373,  396,  374,  397,  398,  375,
+      376,  377,  378,  379,  380,  381,  399,  382,  383,  384,
+      385,  386,  387,  388,  389,  390,  400,  401,  391,  392,
+
+      393,  394,  395,  402,  396,  404,  397,  398,  405,  406,
+      407,  408,  409,  410,  403,  399,  411,  412,  413,  414,
+      415,  416,  417,  418,  419,  400,  401,  420,  421,  422,
+      423,  424,  402,  425,  404,  426,  427,  405,  406,  407,
+      408,  409,  410,  403,  428,  411,  412,  413,  414,  415,
+      416,  417,  418,  419,  429,  430,  420,  421,  422,  423,
+      424,  431,  425,  432,  426,  427,  433,  434,  435,  436,
+      437,  438,  439,  428,  440,  441,  442,  443,  445,  446,
+      444,  447,  448,  429,  430,  449,  450,  451,  452,  453,
+      431,  454,  432,  455,  456,  433,  434,  435,  436,  437,
+
+      438,  439,  457,  440,  441,  442,  443,  445,  446,  444,
+      447,  448,  458,  459,  449,  450,  451,  452,  453,  460,
+      454,  461,  455,  456,  462,  463,  464,  465,  468,  466,
+      469,  457,  467,  470,  471,  472,  473,  474,  475,  476,
+      477,  458,  459,  478,  479,  480,  481,  482,  460,  483,
+      461,  484,  485,  462,  463,  464,  465,  468,  466,  469,
+      486,  467,  470,  471,  472,  473,  474,  475,  476,  477,
+      487,  488,  478,  479,  480,  481,  482,  489,  483,  490,
+      484,  485,  491,  492,  493,  494,  495,  496,  497,  486,
+      498,  499,  500,  501,  502,  503,  504,  505,  506,  487,
+
+      488,  507,  508,  509,  510,  511,  489,  512,  490,  513,
+      514,  491,  492,  493,  494,  495,  496,  497,  515,  498,
+      499,  500,  501,  502,  503,  504,  505,  506,  516,  517,
+      507,  508,  509,  510,  511,  518,  512,  519,  513,  514,
+      520,  521,  522,  523,  524,  525,  526,  515,  527,  528,
+      529,  530,  531,  532,  533,  534,  535,  516,  517,  536,
+      537,  538,  539,  540,  518,  541,  519,  542,  543,  520,
+      521,  522,  523,  524,  525,  526,  544,  527,  528,  529,
+      530,  531,  532,  533,  534,  535,  545,  546,  536,  537,
+      538,  539,  540,  547,  541,  548,  542,  543,  549,  550,
+
+      551,  552,  553,  554,  555,  544,  556,  557,  558,  559,
+      560,  561,  562,  563,  564,  545,  546,  565,  566,  567,
+      568,  569,  547,  570,  548,  571,  572,  549,  550,  551,
+      552,  553,  554,  555,  573,  556,  557,  558,  559,  560,
+      561,  562,  563,  564,  574,  575,  565,  566,  567,  568,
+      569,  576,  570,  577,  571,  572,  578,  579,  580,  581,
+      582,  583,  584,  573,  585,  586,  587,  588,  589,  590,
+      591,  591,  591,  574,  575,  591,  591,  591,  591,  591,
+      576,  591,  577,  591,  591,  578,  579,  580,  581,  582,
+      583,  584,  591,  585,  586,  587,  588,  589,  590,   14,
+
+       14,   14,   14,   14,   14,   14,   14,   14,   14,   60,
+       60,   60,   60,   60,   60,   60,   60,   60,   60,   61,
+       61,   61,   61,   61,   61,   61,   61,   61,   61,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   67,
+       67,   67,   67,   67,   67,   67,   67,   67,   67,   70,
+       70,   82,   82,   82,  591,   82,  159,  159,  159,  159,
+      591,  159,  160,  160,  160,  591,  160,  160,  160,  160,
+      160,  160,  162,  162,  162,  591,  162,  162,  162,  162,
+      591,  162,  163,  163,  163,  163,  163,  163,  163,  163,
+      163,  163,  173,  173,  591,  173,  173,  173,  173,  173,
+
+      173,  173,  175,  591,  175,  175,  175,  175,  175,  175,
+      175,  175,  274,  274,  368,  368,   13,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591
     } ;
 
 static const flex_int16_t yy_chk[1389] =
     {   0,
-        0,  155,    1,    2,    7,    8,   57,   57,   11,    7,
-        8,   11,   12,   68,   18,   12,   18,   25,   25,   27,
-       27,   58,   58,   70,   62,   70,   76,   76,   56,   76,
-       76,  156,  156,  163,  163,  164,  164,  175,  175,  176,
-      176,  270,  270,   29,    1,    2,    3,    3,    3,    3,
+        0,  157,    1,    2,    7,    8,   58,   58,   11,    7,
+        8,   11,   12,   69,   18,   12,   18,   25,   25,   28,
+       28,   59,   59,   71,   63,   71,   77,   77,   57,   77,
+       77,  158,  158,  165,  165,  166,  166,  177,  177,  178,
+      178,  272,  272,   30,    1,    2,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
@@ -1026,149 +1028,149 @@ static const flex_int16_t yy_chk[1389] =
 
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,   36,   39,   40,    9,
-       10,    5,    5,    5,    9,   10,  271,  271,   24,   26,
-       26,   26,  365,  365,   30,   20,   13,    0,    0,    0,
-       26,    0,   30,    0,   30,   36,   39,   40,    0,   30,
+        5,    5,    5,    5,    5,    5,   37,   40,   41,    9,
+       10,    5,    5,    5,    9,   10,  273,  273,   27,   26,
+       26,   26,  367,  367,   31,   24,   20,   13,    0,    0,
+       26,    0,   31,    0,   31,   37,   40,   41,    0,   31,
         5,    5,    6,    6,    6,    6,    6,    6,    6,    6,
-        6,    9,   10,   30,   34,   37,    6,    6,    6,   26,
-       31,   30,   33,   30,   31,   42,   33,   31,   30,   37,
-       33,   42,   46,   38,    0,   34,   33,   34,   38,   33,
-
-       31,    0,    0,   51,   37,    6,    6,   34,    0,   31,
-        0,   33,    0,   31,   42,   33,   31,   43,   37,   33,
-       42,   46,   38,   43,   34,   33,   34,   38,   33,   31,
-       32,   41,   51,   52,   52,   41,   34,   32,   45,   41,
-       54,   44,   45,   81,   32,   41,   43,   32,   32,   44,
-       32,    0,   43,   44,   83,   45,   44,   44,    0,   32,
-       41,   84,   52,   52,   41,    0,   32,   45,   41,   54,
-       44,   45,   81,   32,   41,    0,   32,   32,   44,   32,
-       35,    0,   44,   83,   45,   44,   44,   50,   35,   50,
-       84,   35,   50,   82,   35,   48,   85,   35,   47,    0,
-
-       35,   82,   47,   48,   73,   73,   47,    0,    0,   35,
-       48,   48,   47,    0,   73,   86,   50,   35,   50,   87,
-       35,   50,   82,   35,   48,   85,   35,   47,   86,   35,
-       82,   47,   48,    0,   89,   47,   74,   74,    0,   48,
-       48,   47,   49,   73,   86,   92,   74,   90,   87,   49,
-       49,   90,   93,   75,   75,   75,   49,   86,   94,   49,
-       97,   95,   49,   89,   75,   91,   95,   91,   98,   91,
-        0,   49,    0,    0,   92,   74,   90,   99,   49,   49,
-       90,   93,    0,  101,  102,   49,    0,   94,   49,   97,
-       95,   49,   65,   75,   91,   95,   91,   98,   91,   96,
-
-       65,   65,   96,  103,  104,  105,   99,   65,   96,  106,
-      107,   65,  101,  102,  103,   96,  107,  108,  109,   65,
-      110,  111,  112,   65,  111,   65,    0,  115,   96,   65,
-      116,   96,  103,  104,  105,  117,   65,   96,  106,  107,
-       65,    0,    0,  103,   96,  107,  108,  109,   65,  110,
-      111,  112,   65,  111,   65,  113,  115,  118,   65,  116,
-      119,  120,  119,  121,  117,  113,  122,  123,  124,  125,
-      113,  113,  127,  128,  129,  130,  131,  132,  133,  134,
-      136,  132,  135,  137,  113,  139,  118,  135,  135,  119,
-      120,  119,  121,    0,  113,  122,  123,  124,  125,  113,
-
-      113,  127,  128,  129,  130,  131,  132,  133,  134,  136,
-      132,  135,  137,  138,  139,  140,  135,  135,  141,  142,
-      143,  144,  138,  146,  147,  148,  149,  150,  151,  152,
-      138,  153,  148,  154,  151,  174,  174,  153,  179,  181,
-      182,  183,  138,  184,  140,  174,  187,  141,  142,  143,
-      144,  138,  146,  147,  148,  149,  150,  151,  152,  138,
-      153,  148,  154,  151,  185,  186,  153,  179,  181,  182,
-      183,  188,  184,  189,  174,  187,  185,  190,  191,  192,
-      186,  193,  194,  195,  197,  198,  199,  200,  201,  202,
-      203,  204,  206,  185,  186,  207,  208,  209,  210,  211,
-
-      188,  212,  189,  213,  214,  185,  190,  191,  192,  186,
-      193,  194,  195,  197,  198,  199,  200,  201,  202,  203,
-      204,  206,  215,  216,  207,  208,  209,  210,  211,  217,
-      212,  218,  213,  214,  219,  220,  221,  222,  223,  225,
-      226,  227,  228,  229,  230,  231,  233,  222,  235,  236,
-      237,  215,  216,  238,  239,  240,  242,  241,  217,  241,
-      218,  243,  244,  219,  220,  221,  222,  223,  225,  226,
-      227,  228,  229,  230,  231,  233,  222,  235,  236,  237,
-      245,  246,  238,  239,  240,  242,  241,  247,  241,  248,
-      243,  244,  249,  250,  252,  253,  254,  255,  256,  248,
-
-      257,  258,  259,  260,  261,  253,  261,  262,  263,  245,
-      246,  264,  265,  266,  267,  268,  247,  266,  248,  269,
-      273,  249,  250,  252,  253,  254,  255,  256,  274,  257,
-      258,  259,  260,  261,  253,  261,  262,  263,  275,  276,
-      264,  265,  266,  267,  268,  277,  266,  278,  269,  273,
-      279,  282,  283,  284,  285,  287,  288,  274,  289,  290,
-      291,  292,  293,  294,  295,  296,  299,  275,  276,  300,
-      301,  302,  303,  304,  277,  305,  278,  308,  310,  279,
-      282,  283,  284,  285,  287,  288,  312,  289,  290,  291,
-      292,  293,  294,  295,  296,  299,  313,  314,  300,  301,
-
-      302,  303,  304,  315,  305,  321,  308,  310,  323,  324,
-      325,  326,  327,  329,  315,  312,  330,  331,  332,  333,
-      335,  337,  338,  339,  341,  313,  314,  342,  343,  344,
-      345,  346,  315,  347,  321,  348,  350,  323,  324,  325,
-      326,  327,  329,  315,  352,  330,  331,  332,  333,  335,
-      337,  338,  339,  341,  353,  354,  342,  343,  344,  345,
-      346,  355,  347,  356,  348,  350,  357,  358,  359,  361,
-      362,  364,  368,  352,  369,  370,  371,  372,  373,  374,
-      372,  376,  377,  353,  354,  378,  379,  380,  381,  382,
-      355,  383,  356,  384,  385,  357,  358,  359,  361,  362,
-
-      364,  368,  386,  369,  370,  371,  372,  373,  374,  372,
-      376,  377,  387,  388,  378,  379,  380,  381,  382,  389,
-      383,  393,  384,  385,  394,  396,  399,  400,  403,  401,
-      408,  386,  401,  409,  410,  411,  412,  414,  415,  417,
-      418,  387,  388,  419,  420,  421,  422,  423,  389,  425,
-      393,  426,  427,  394,  396,  399,  400,  403,  401,  408,
-      429,  401,  409,  410,  411,  412,  414,  415,  417,  418,
-      430,  432,  419,  420,  421,  422,  423,  433,  425,  435,
-      426,  427,  436,  437,  438,  440,  441,  442,  443,  429,
-      444,  446,  448,  449,  450,  451,  452,  454,  455,  430,
-
-      432,  458,  459,  460,  463,  464,  433,  465,  435,  467,
-      468,  436,  437,  438,  440,  441,  442,  443,  469,  444,
-      446,  448,  449,  450,  451,  452,  454,  455,  470,  471,
-      458,  459,  460,  463,  464,  472,  465,  474,  467,  468,
-      477,  480,  481,  482,  483,  487,  489,  469,  490,  492,
-      493,  494,  495,  496,  497,  500,  503,  470,  471,  504,
-      506,  509,  510,  511,  472,  513,  474,  515,  516,  477,
-      480,  481,  482,  483,  487,  489,  517,  490,  492,  493,
-      494,  495,  496,  497,  500,  503,  518,  519,  504,  506,
-      509,  510,  511,  520,  513,  521,  515,  516,  522,  524,
-
-      525,  526,  527,  528,  529,  517,  530,  531,  533,  535,
-      536,  538,  539,  541,  542,  518,  519,  544,  545,  546,
-      547,  548,  520,  550,  521,  551,  552,  522,  524,  525,
-      526,  527,  528,  529,  553,  530,  531,  533,  535,  536,
-      538,  539,  541,  542,  555,  556,  544,  545,  546,  547,
-      548,  559,  550,  561,  551,  552,  562,  565,  569,  570,
-      571,  576,  577,  553,  578,  581,  583,  584,  585,  587,
-        0,    0,    0,  555,  556,    0,    0,    0,    0,    0,
-      559,    0,  561,    0,    0,  562,  565,  569,  570,  571,
-      576,  577,    0,  578,  581,  583,  584,  585,  587,  590,
-
-      590,  590,  590,  590,  590,  590,  590,  590,  590,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  592,
+        6,    9,   10,   31,   35,   38,    6,    6,    6,   26,
+       32,   31,   34,   31,   32,   43,   34,   32,   31,   38,
+       34,   43,   47,   39,    0,   35,   34,   35,   39,   34,
+
+       32,    0,    0,   52,   38,    6,    6,   35,    0,   32,
+        0,   34,    0,   32,   43,   34,   32,   44,   38,   34,
+       43,   47,   39,   44,   35,   34,   35,   39,   34,   32,
+       33,   42,   52,   53,   53,   42,   35,   33,   46,   42,
+       55,   45,   46,   83,   33,   42,   44,   33,   33,   45,
+       33,    0,   44,   45,   85,   46,   45,   45,    0,   33,
+       42,   86,   53,   53,   42,    0,   33,   46,   42,   55,
+       45,   46,   83,   33,   42,    0,   33,   33,   45,   33,
+       36,    0,   45,   85,   46,   45,   45,   51,   36,   51,
+       86,   36,   51,   84,   36,   49,   87,   36,   48,    0,
+
+       36,   84,   48,   49,   74,   74,   48,    0,    0,   36,
+       49,   49,   48,    0,   74,   88,   51,   36,   51,   89,
+       36,   51,   84,   36,   49,   87,   36,   48,   88,   36,
+       84,   48,   49,    0,   91,   48,   75,   75,    0,   49,
+       49,   48,   50,   74,   88,   94,   75,   92,   89,   50,
+       50,   92,   95,   76,   76,   76,   50,   88,   96,   50,
+       99,   97,   50,   91,   76,   93,   97,   93,  100,   93,
+        0,   50,    0,    0,   94,   75,   92,  101,   50,   50,
+       92,   95,    0,  103,  104,   50,    0,   96,   50,   99,
+       97,   50,   66,   76,   93,   97,   93,  100,   93,   98,
+
+       66,   66,   98,  105,  106,  107,  101,   66,   98,  108,
+      109,   66,  103,  104,  105,   98,  109,  110,  111,   66,
+      112,  113,  114,   66,  113,   66,    0,  117,   98,   66,
+      118,   98,  105,  106,  107,  119,   66,   98,  108,  109,
+       66,    0,    0,  105,   98,  109,  110,  111,   66,  112,
+      113,  114,   66,  113,   66,  115,  117,  120,   66,  118,
+      121,  122,  121,  123,  119,  115,  124,  125,  126,  127,
+      115,  115,  129,  130,  131,  132,  133,  134,  135,  136,
+      138,  134,  137,  139,  115,  141,  120,  137,  137,  121,
+      122,  121,  123,    0,  115,  124,  125,  126,  127,  115,
+
+      115,  129,  130,  131,  132,  133,  134,  135,  136,  138,
+      134,  137,  139,  140,  141,  142,  137,  137,  143,  144,
+      145,  146,  140,  148,  149,  150,  151,  152,  153,  154,
+      140,  155,  150,  156,  153,  176,  176,  155,  181,  183,
+      184,  185,  140,  186,  142,  176,  189,  143,  144,  145,
+      146,  140,  148,  149,  150,  151,  152,  153,  154,  140,
+      155,  150,  156,  153,  187,  188,  155,  181,  183,  184,
+      185,  190,  186,  191,  176,  189,  187,  192,  193,  194,
+      188,  195,  196,  197,  199,  200,  201,  202,  203,  204,
+      205,  206,  208,  187,  188,  209,  210,  211,  212,  213,
+
+      190,  214,  191,  215,  216,  187,  192,  193,  194,  188,
+      195,  196,  197,  199,  200,  201,  202,  203,  204,  205,
+      206,  208,  217,  218,  209,  210,  211,  212,  213,  219,
+      214,  220,  215,  216,  221,  222,  223,  224,  225,  227,
+      228,  229,  230,  231,  232,  233,  235,  224,  237,  238,
+      239,  217,  218,  240,  241,  242,  244,  243,  219,  243,
+      220,  245,  246,  221,  222,  223,  224,  225,  227,  228,
+      229,  230,  231,  232,  233,  235,  224,  237,  238,  239,
+      247,  248,  240,  241,  242,  244,  243,  249,  243,  250,
+      245,  246,  251,  252,  254,  255,  256,  257,  258,  250,
+
+      259,  260,  261,  262,  263,  255,  263,  264,  265,  247,
+      248,  266,  267,  268,  269,  270,  249,  268,  250,  271,
+      275,  251,  252,  254,  255,  256,  257,  258,  276,  259,
+      260,  261,  262,  263,  255,  263,  264,  265,  277,  278,
+      266,  267,  268,  269,  270,  279,  268,  280,  271,  275,
+      281,  284,  285,  286,  287,  289,  290,  276,  291,  292,
+      293,  294,  295,  296,  297,  298,  301,  277,  278,  302,
+      303,  304,  305,  306,  279,  307,  280,  310,  312,  281,
+      284,  285,  286,  287,  289,  290,  314,  291,  292,  293,
+      294,  295,  296,  297,  298,  301,  315,  316,  302,  303,
+
+      304,  305,  306,  317,  307,  323,  310,  312,  325,  326,
+      327,  328,  329,  331,  317,  314,  332,  333,  334,  335,
+      337,  339,  340,  341,  343,  315,  316,  344,  345,  346,
+      347,  348,  317,  349,  323,  350,  352,  325,  326,  327,
+      328,  329,  331,  317,  354,  332,  333,  334,  335,  337,
+      339,  340,  341,  343,  355,  356,  344,  345,  346,  347,
+      348,  357,  349,  358,  350,  352,  359,  360,  361,  363,
+      364,  366,  370,  354,  371,  372,  373,  374,  375,  376,
+      374,  378,  379,  355,  356,  380,  381,  382,  383,  384,
+      357,  385,  358,  386,  387,  359,  360,  361,  363,  364,
+
+      366,  370,  388,  371,  372,  373,  374,  375,  376,  374,
+      378,  379,  389,  390,  380,  381,  382,  383,  384,  391,
+      385,  395,  386,  387,  396,  398,  401,  402,  405,  403,
+      410,  388,  403,  411,  412,  413,  414,  416,  417,  419,
+      420,  389,  390,  421,  422,  423,  424,  425,  391,  427,
+      395,  428,  429,  396,  398,  401,  402,  405,  403,  410,
+      431,  403,  411,  412,  413,  414,  416,  417,  419,  420,
+      432,  434,  421,  422,  423,  424,  425,  435,  427,  437,
+      428,  429,  438,  439,  440,  442,  443,  444,  445,  431,
+      446,  448,  450,  451,  452,  453,  454,  456,  457,  432,
+
+      434,  460,  461,  462,  465,  466,  435,  467,  437,  469,
+      470,  438,  439,  440,  442,  443,  444,  445,  471,  446,
+      448,  450,  451,  452,  453,  454,  456,  457,  472,  473,
+      460,  461,  462,  465,  466,  474,  467,  476,  469,  470,
+      479,  482,  483,  484,  485,  489,  491,  471,  492,  494,
+      495,  496,  497,  498,  499,  502,  505,  472,  473,  506,
+      508,  511,  512,  513,  474,  515,  476,  517,  518,  479,
+      482,  483,  484,  485,  489,  491,  519,  492,  494,  495,
+      496,  497,  498,  499,  502,  505,  520,  521,  506,  508,
+      511,  512,  513,  522,  515,  523,  517,  518,  524,  526,
+
+      527,  528,  529,  530,  531,  519,  532,  533,  535,  537,
+      538,  540,  541,  543,  544,  520,  521,  546,  547,  548,
+      549,  550,  522,  552,  523,  553,  554,  524,  526,  527,
+      528,  529,  530,  531,  555,  532,  533,  535,  537,  538,
+      540,  541,  543,  544,  557,  558,  546,  547,  548,  549,
+      550,  561,  552,  563,  553,  554,  564,  567,  571,  572,
+      573,  578,  579,  555,  580,  583,  585,  586,  587,  589,
+        0,    0,    0,  557,  558,    0,    0,    0,    0,    0,
+      561,    0,  563,    0,    0,  564,  567,  571,  572,  573,
+      578,  579,    0,  580,  583,  585,  586,  587,  589,  592,
+
       592,  592,  592,  592,  592,  592,  592,  592,  592,  593,
       593,  593,  593,  593,  593,  593,  593,  593,  593,  594,
       594,  594,  594,  594,  594,  594,  594,  594,  594,  595,
-      595,  596,  596,  596,    0,  596,  597,  597,  597,  597,
-        0,  597,  598,  598,  598,    0,  598,  598,  598,  598,
-      598,  598,  599,  599,  599,    0,  599,  599,  599,  599,
-        0,  599,  600,  600,  600,  600,  600,  600,  600,  600,
-      600,  600,  601,  601,    0,  601,  601,  601,  601,  601,
-
-      601,  601,  602,    0,  602,  602,  602,  602,  602,  602,
-      602,  602,  603,  603,  604,  604,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589,  589,  589,
-      589,  589,  589,  589,  589,  589,  589,  589
+      595,  595,  595,  595,  595,  595,  595,  595,  595,  596,
+      596,  596,  596,  596,  596,  596,  596,  596,  596,  597,
+      597,  598,  598,  598,    0,  598,  599,  599,  599,  599,
+        0,  599,  600,  600,  600,    0,  600,  600,  600,  600,
+      600,  600,  601,  601,  601,    0,  601,  601,  601,  601,
+        0,  601,  602,  602,  602,  602,  602,  602,  602,  602,
+      602,  602,  603,  603,    0,  603,  603,  603,  603,  603,
+
+      603,  603,  604,    0,  604,  604,  604,  604,  604,  604,
+      604,  604,  605,  605,  606,  606,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
+      591,  591,  591,  591,  591,  591,  591,  591
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static const flex_int32_t yy_rule_can_match_eol[166] =
+static const flex_int32_t yy_rule_can_match_eol[167] =
     {   0,
 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1177,8 +1179,8 @@ static const flex_int32_t yy_rule_can_match_eol[166] =
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 
-    0, 0, 1, 0, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 
+    0, 0, 0, 1, 0, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -1289,14 +1291,14 @@ class UnaryOperation;
     yycolumn += yyleng;                                   \
   }
 
-#line 1292 "SqlLexer_gen.cpp"
+#line 1294 "SqlLexer_gen.cpp"
 /* FIXME(chasseur, qzeng): Add support for hexadecimal literals. */
 /**
  * These patterns are based on the SQL-2011 standard for syntax of numeric
  * literals (Part 2, Section 5.3 of the standard).
  **/
 
-#line 1299 "SqlLexer_gen.cpp"
+#line 1301 "SqlLexer_gen.cpp"
 
 #define INITIAL 0
 #define CONDITION_SQL 1
@@ -1586,7 +1588,7 @@ YY_DECL
 #line 132 "../SqlLexer.lpp"
 
 
-#line 1589 "SqlLexer_gen.cpp"
+#line 1591 "SqlLexer_gen.cpp"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1613,13 +1615,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 590 )
+				if ( yy_current_state >= 592 )
 					yy_c = yy_meta[yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 589 );
+		while ( yy_current_state != 591 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -2362,37 +2364,42 @@ return TOKEN_GEQ;
 	YY_BREAK
 case 137:
 YY_RULE_SETUP
-#line 305 "../SqlLexer.lpp"
-return yytext[0];
+#line 304 "../SqlLexer.lpp"
+return TOKEN_DOUBLECOLON;
 	YY_BREAK
 case 138:
 YY_RULE_SETUP
 #line 306 "../SqlLexer.lpp"
 return yytext[0];
 	YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 307 "../SqlLexer.lpp"
+return yytext[0];
+	YY_BREAK
 /**
     * Quoted strings. Prefacing a string with an 'e' or 'E' causes escape
     * sequences to be processed (as in PostgreSQL).
     **/
-case 139:
+case 140:
 YY_RULE_SETUP
-#line 312 "../SqlLexer.lpp"
+#line 313 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED_ESCAPED);
   }
 	YY_BREAK
-case 140:
+case 141:
 YY_RULE_SETUP
-#line 317 "../SqlLexer.lpp"
+#line 318 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED);
   }
 	YY_BREAK
-case 141:
+case 142:
 YY_RULE_SETUP
-#line 322 "../SqlLexer.lpp"
+#line 323 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_DOUBLE_QUOTED);
@@ -2404,7 +2411,7 @@ YY_RULE_SETUP
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED):
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED_ESCAPED):
 case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
-#line 331 "../SqlLexer.lpp"
+#line 332 "../SqlLexer.lpp"
 {
     delete yylval->string_value_;
     BEGIN(INITIAL);
@@ -2415,9 +2422,9 @@ case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
 
 /* Process escape sequences. */
 
-case 142:
+case 143:
 YY_RULE_SETUP
-#line 341 "../SqlLexer.lpp"
+#line 342 "../SqlLexer.lpp"
 {
     /* Octal code */
     unsigned int code;
@@ -2431,9 +2438,9 @@ YY_RULE_SETUP
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 143:
+case 144:
 YY_RULE_SETUP
-#line 353 "../SqlLexer.lpp"
+#line 354 "../SqlLexer.lpp"
 {
     /* Hexadecimal code */
     unsigned int code;
@@ -2441,9 +2448,9 @@ YY_RULE_SETUP
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 144:
+case 145:
 YY_RULE_SETUP
-#line 359 "../SqlLexer.lpp"
+#line 360 "../SqlLexer.lpp"
 {
     /* A numeric escape sequence that isn't correctly specified. */
     delete yylval->string_value_;
@@ -2452,58 +2459,58 @@ YY_RULE_SETUP
     return TOKEN_LEX_ERROR;
   }
 	YY_BREAK
-case 145:
+case 146:
 YY_RULE_SETUP
-#line 366 "../SqlLexer.lpp"
+#line 367 "../SqlLexer.lpp"
 {
     /* Backspace */
     yylval->string_value_->push_back('\b');
   }
 	YY_BREAK
-case 146:
+case 147:
 YY_RULE_SETUP
-#line 370 "../SqlLexer.lpp"
+#line 371 "../SqlLexer.lpp"
 {
     /* Form-feed */
     yylval->string_value_->push_back('\f');
   }
 	YY_BREAK
-case 147:
+case 148:
 YY_RULE_SETUP
-#line 374 "../SqlLexer.lpp"
+#line 375 "../SqlLexer.lpp"
 {
     /* Newline */
     yylval->string_value_->push_back('\n');
   }
 	YY_BREAK
-case 148:
+case 149:
 YY_RULE_SETUP
-#line 378 "../SqlLexer.lpp"
+#line 379 "../SqlLexer.lpp"
 {
     /* Carriage-return */
     yylval->string_value_->push_back('\r');
   }
 	YY_BREAK
-case 149:
+case 150:
 YY_RULE_SETUP
-#line 382 "../SqlLexer.lpp"
+#line 383 "../SqlLexer.lpp"
 {
     /* Horizontal Tab */
     yylval->string_value_->push_back('\t');
   }
 	YY_BREAK
-case 150:
-/* rule 150 can match eol */
+case 151:
+/* rule 151 can match eol */
 YY_RULE_SETUP
-#line 386 "../SqlLexer.lpp"
+#line 387 "../SqlLexer.lpp"
 {
     /* Any other character (including actual newline or carriage return) */
     yylval->string_value_->push_back(yytext[1]);
   }
 	YY_BREAK
-case 151:
+case 152:
 YY_RULE_SETUP
-#line 390 "../SqlLexer.lpp"
+#line 391 "../SqlLexer.lpp"
 {
     /* This should only be encountered right before an EOF. */
     delete yylval->string_value_;
@@ -2514,17 +2521,17 @@ YY_RULE_SETUP
 	YY_BREAK
 
 
-case 152:
+case 153:
 YY_RULE_SETUP
-#line 400 "../SqlLexer.lpp"
+#line 401 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('\'');
   }
 	YY_BREAK
-case 153:
+case 154:
 YY_RULE_SETUP
-#line 404 "../SqlLexer.lpp"
+#line 405 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2533,17 +2540,17 @@ YY_RULE_SETUP
 	YY_BREAK
 
 
-case 154:
+case 155:
 YY_RULE_SETUP
-#line 412 "../SqlLexer.lpp"
+#line 413 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('"');
   }
 	YY_BREAK
-case 155:
+case 156:
 YY_RULE_SETUP
-#line 416 "../SqlLexer.lpp"
+#line 417 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2551,94 +2558,94 @@ YY_RULE_SETUP
   }
 	YY_BREAK
 
-case 156:
-/* rule 156 can match eol */
+case 157:
+/* rule 157 can match eol */
 YY_RULE_SETUP
-#line 423 "../SqlLexer.lpp"
+#line 424 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 157:
-/* rule 157 can match eol */
+case 158:
+/* rule 158 can match eol */
 YY_RULE_SETUP
-#line 428 "../SqlLexer.lpp"
+#line 429 "../SqlLexer.lpp"
 {
   /* Scan up to a quote or escape sequence. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 158:
-/* rule 158 can match eol */
+case 159:
+/* rule 159 can match eol */
 YY_RULE_SETUP
-#line 433 "../SqlLexer.lpp"
+#line 434 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
 
-case 159:
+case 160:
 YY_RULE_SETUP
-#line 439 "../SqlLexer.lpp"
+#line 440 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(
         yylloc->first_line, yylloc->first_column, std::string(yytext, yyleng));
     return TOKEN_NAME;
   }
 	YY_BREAK
-case 160:
+case 161:
 YY_RULE_SETUP
-#line 445 "../SqlLexer.lpp"
+#line 446 "../SqlLexer.lpp"
 {
     yylval->numeric_literal_value_ = new quickstep::NumericParseLiteralValue(
         yylloc->first_line, yylloc->first_column, yytext);
     return TOKEN_UNSIGNED_NUMVAL;
   }
 	YY_BREAK
-case 161:
+case 162:
 YY_RULE_SETUP
-#line 451 "../SqlLexer.lpp"
+#line 452 "../SqlLexer.lpp"
 /* comment */
 	YY_BREAK
-case 162:
-/* rule 162 can match eol */
+case 163:
+/* rule 163 can match eol */
 YY_RULE_SETUP
-#line 453 "../SqlLexer.lpp"
+#line 454 "../SqlLexer.lpp"
 { yycolumn = 0; }
 	YY_BREAK
-case 163:
+case 164:
 YY_RULE_SETUP
-#line 455 "../SqlLexer.lpp"
+#line 456 "../SqlLexer.lpp"
 ; /* ignore white space */
 	YY_BREAK
 /* CONDITION_SQL */
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(CONDITION_COMMAND):
 case YY_STATE_EOF(CONDITION_SQL):
-#line 459 "../SqlLexer.lpp"
+#line 460 "../SqlLexer.lpp"
 {
   /* All conditions except for mutli-state string extracting conditions. */
   BEGIN(INITIAL);
   return TOKEN_EOF;
 }
 	YY_BREAK
-case 164:
+case 165:
 YY_RULE_SETUP
-#line 465 "../SqlLexer.lpp"
+#line 466 "../SqlLexer.lpp"
 {
   BEGIN(INITIAL);
   quickstep_yyerror(NULL, yyscanner, NULL, "illegal character");
   return TOKEN_LEX_ERROR;
 }
 	YY_BREAK
-case 165:
+case 166:
 YY_RULE_SETUP
-#line 471 "../SqlLexer.lpp"
+#line 472 "../SqlLexer.lpp"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 2641 "SqlLexer_gen.cpp"
+#line 2648 "SqlLexer_gen.cpp"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2936,7 +2943,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 590 )
+			if ( yy_current_state >= 592 )
 				yy_c = yy_meta[yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -2965,11 +2972,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 590 )
+		if ( yy_current_state >= 592 )
 			yy_c = yy_meta[yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-	yy_is_jam = (yy_current_state == 589);
+	yy_is_jam = (yy_current_state == 591);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -3799,6 +3806,6 @@ void yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 471 "../SqlLexer.lpp"
+#line 472 "../SqlLexer.lpp"
 
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/parser/preprocessed/SqlLexer_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.hpp b/parser/preprocessed/SqlLexer_gen.hpp
index 479b72d..9990de6 100644
--- a/parser/preprocessed/SqlLexer_gen.hpp
+++ b/parser/preprocessed/SqlLexer_gen.hpp
@@ -733,7 +733,7 @@ extern int yylex \
 #undef yyTABLES_NAME
 #endif
 
-#line 471 "../SqlLexer.lpp"
+#line 472 "../SqlLexer.lpp"
 
 
 #line 739 "SqlLexer_gen.hpp"


[28/38] incubator-quickstep git commit: Updates to meta type

Posted by ji...@apache.org.
Updates to meta type


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/eb156fdf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/eb156fdf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/eb156fdf

Branch: refs/heads/refactor-type
Commit: eb156fdfa286a6a40644421ddecb6101914fab4a
Parents: 0780fa2
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Tue Oct 3 01:52:29 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 types/ArrayType.cpp           | 29 +++++++++++++++
 types/ArrayType.hpp           |  7 +++-
 types/CMakeLists.txt          | 22 ++++++++++--
 types/MetaType.cpp            | 36 -------------------
 types/MetaType.hpp            | 44 +----------------------
 types/MetaTypeLite.cpp        | 52 +++++++++++++++++++++++++++
 types/MetaTypeLite.hpp        | 72 ++++++++++++++++++++++++++++++++++++++
 types/ParameterizedPodLit.hpp |  0
 types/Type.proto              |  4 +++
 types/TypeSynthesizer.hpp     |  8 ++---
 types/TypedValue.cpp          | 15 ++++++--
 11 files changed, 200 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
index c0f3a87..df2b9de 100644
--- a/types/ArrayType.cpp
+++ b/types/ArrayType.cpp
@@ -19,14 +19,43 @@
 
 #include "types/ArrayType.hpp"
 
+#include <cstdlib>
 #include <string>
 
+#include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 
 #include "glog/logging.h"
 
 namespace quickstep {
 
+TypedValue ArrayType::marshallValue(const UntypedLiteral *value) const {
+  const ArrayLiteral &array = *static_cast<const ArrayLiteral*>(value);
+  serialization::ArrayLiteral proto;
+  for (const auto &element : array) {
+    // TODO(refactor-type): Improve performance.
+    TypedValue value = element_type_.marshallValue(element);
+    proto.add_data(value.getDataPtr(), value.getDataSize());
+  }
+  const std::size_t data_size = proto.ByteSize();
+  void *data = std::malloc(data_size);
+  proto.SerializeToArray(data, data_size);
+  return TypedValue::CreateWithOwnedData(kArray, data, data_size);
+}
+
+UntypedLiteral* ArrayType::unmarshallValue(const void *data,
+                                           const std::size_t data_size) const {
+  std::unique_ptr<ArrayLiteral> array = std::make_unique<ArrayLiteral>();
+  serialization::ArrayLiteral proto;
+  proto.ParseFromArray(data, data_size);
+  for (int i = 0; i < proto.data_size(); ++i) {
+    const std::string &element_data = proto.data(i);
+    array->emplace_back(
+        element_type_.unmarshallValue(element_data.c_str(), element_data.size()));
+  }
+  return array.release();
+}
+
 std::string ArrayType::printValueToString(const UntypedLiteral *value) const {
   DCHECK(value != nullptr);
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
index fe81c3e..a48cfa3 100644
--- a/types/ArrayType.hpp
+++ b/types/ArrayType.hpp
@@ -44,6 +44,11 @@ class ArrayType : public TypeSynthesizer<kArray> {
     return 16;
   }
 
+  TypedValue marshallValue(const UntypedLiteral *value) const override;
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override;
+
   std::string printValueToString(const UntypedLiteral *value) const override;
 
   bool parseTypedValueFromString(const std::string &value_string,
@@ -63,7 +68,7 @@ class ArrayType : public TypeSynthesizer<kArray> {
     DCHECK_EQ(1u, parameters.size());
     const GenericValue &value = parameters.front();
     DCHECK(value.getType().getTypeID() == kMetaType);
-    return *static_cast<const Type*>(value.getValue());
+    return **static_cast<const MetaTypeLiteral*>(value.getValue());
   }
 
   const Type &element_type_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 07f9d97..69ac906 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -49,13 +49,13 @@ add_library(quickstep_types_IntervalLit ../empty_src.cpp IntervalLit.hpp)
 add_library(quickstep_types_IntervalParser IntervalParser.cpp IntervalParser.hpp)
 add_library(quickstep_types_LongType LongType.cpp LongType.hpp)
 add_library(quickstep_types_MetaType MetaType.cpp MetaType.hpp)
+add_library(quickstep_types_MetaTypeLite MetaTypeLite.cpp MetaTypeLite.hpp)
 add_library(quickstep_types_NullCoercibilityCheckMacro ../empty_src.cpp NullCoercibilityCheckMacro.hpp)
 add_library(quickstep_types_NullLit ../empty_src.cpp NullLit.hpp)
 add_library(quickstep_types_NullType ../empty_src.cpp NullType.hpp)
 add_library(quickstep_types_NumericSuperType ../empty_src.cpp NumericSuperType.hpp)
 add_library(quickstep_types_NumericTypeSafeCoercibility ../empty_src.cpp NumericTypeSafeCoercibility.hpp)
 add_library(quickstep_types_NumericTypeUnifier ../empty_src.cpp NumericTypeUnifier.hpp)
-add_library(quickstep_types_ParameterizedPodLit ../empty_src.cpp ParameterizedPodLit.hpp)
 add_library(quickstep_types_Type Type.cpp Type.hpp)
 add_library(quickstep_types_TypeErrors ../empty_src.cpp TypeErrors.hpp)
 add_library(quickstep_types_TypeFactory TypeFactory.cpp TypeFactory.hpp)
@@ -71,6 +71,12 @@ add_library(quickstep_types_VarCharType VarCharType.cpp VarCharType.hpp)
 add_library(quickstep_types_YearMonthIntervalType YearMonthIntervalType.cpp YearMonthIntervalType.hpp)
 
 # Link dependencies:
+target_link_libraries(quickstep_types_ArrayType
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
+                      quickstep_types_Type_proto
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_types_AsciiStringSuperType
                       quickstep_types_Type
                       quickstep_types_TypeID
@@ -158,6 +164,13 @@ target_link_libraries(quickstep_types_LongType
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_types_MetaType
+                      quickstep_types_MetaTypeLite)
+target_link_libraries(quickstep_types_MetaTypeLite
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_types_NullType
                       glog
                       quickstep_types_Type
@@ -205,12 +218,16 @@ target_link_libraries(quickstep_types_TypeRegistrar
                       quickstep_types_TypeIDSelectors
                       quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_TypeSynthesizer
+                      quickstep_types_GenericValue
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeRegistrar
+                      quickstep_types_TypedValue
                       quickstep_types_Type_proto
+                      quickstep_utility_HashPair
                       quickstep_utility_Macros
-                      quickstep_utility_PtrMap)
+                      quickstep_utility_PtrMap
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_TypeUtil
                       quickstep_types_BoolType
                       quickstep_types_CharType
@@ -221,6 +238,7 @@ target_link_libraries(quickstep_types_TypeUtil
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
+                      quickstep_types_MetaTypeLite
                       quickstep_types_NullType
                       quickstep_types_Type
                       quickstep_types_TypeID

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/MetaType.cpp
----------------------------------------------------------------------
diff --git a/types/MetaType.cpp b/types/MetaType.cpp
index 01fc3a0..e69de29 100644
--- a/types/MetaType.cpp
+++ b/types/MetaType.cpp
@@ -1,36 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/MetaType.hpp"
-
-#include <string>
-
-#include "types/TypeID.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-std::string MetaType::printValueToString(const UntypedLiteral *value) const {
-  DCHECK(value != nullptr);
-
-  return castValueToLiteral(value)->getName();
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/MetaType.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType.hpp b/types/MetaType.hpp
index c046771..6edd270 100644
--- a/types/MetaType.hpp
+++ b/types/MetaType.hpp
@@ -20,48 +20,6 @@
 #ifndef QUICKSTEP_TYPES_META_TYPE_HPP_
 #define QUICKSTEP_TYPES_META_TYPE_HPP_
 
-#include <cstddef>
-#include <string>
-
-#include "types/Type.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypeSynthesizer.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-class TypedValue;
-
-/** \addtogroup Types
- *  @{
- */
-
-class MetaType : public TypeSynthesizer<kMetaType> {
- public:
-  int getPrintWidth() const override {
-    return 16;
-  }
-
-  std::string printValueToString(const UntypedLiteral *value) const override;
-
-  bool parseTypedValueFromString(const std::string &value_string,
-                                 TypedValue *value) const override {
-    return false;
-  }
-
- private:
-  MetaType(const bool nullable)
-      : TypeSynthesizer<kMetaType>(nullable, sizeof(TypeID), 0x100) {
-    // TODO(refactor-type): Possibly infinite maximum size.
-  }
-
-  QUICKSTEP_SYNTHESIZE_TYPE(MetaType);
-};
-
-/** @} */
-
-}  // namespace quickstep
+#include "types/MetaTypeLite.hpp"
 
 #endif  // QUICKSTEP_TYPES_META_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/MetaTypeLite.cpp
----------------------------------------------------------------------
diff --git a/types/MetaTypeLite.cpp b/types/MetaTypeLite.cpp
new file mode 100644
index 0000000..8022534
--- /dev/null
+++ b/types/MetaTypeLite.cpp
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/MetaType.hpp"
+
+#include <string>
+
+#include "types/TypeID.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+TypedValue MetaType::marshallValue(const UntypedLiteral *value) const {
+  const Type *type = castValueToLiteral(value);
+  serialization::Type proto = type->getProto();
+  const std::size_t data_size = proto.ByteSize();
+  void *data = std::malloc(data_size);
+  proto.SerializeToArray(data, data_size);
+  return TypedValue::CreateWithOwnedData(kMetaType, data, data_size);
+}
+
+//UntypedLiteral* MetaType::unmarshallValue(const void *data,
+//                                          const std::size_t data_size) const {
+//  serialization::Type proto;
+//  proto.ParseFromArray(data, data_size);
+//  return
+//}
+
+std::string MetaType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
+
+  return castValueToLiteral(value)->getName();
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/MetaTypeLite.hpp
----------------------------------------------------------------------
diff --git a/types/MetaTypeLite.hpp b/types/MetaTypeLite.hpp
new file mode 100644
index 0000000..776fe03
--- /dev/null
+++ b/types/MetaTypeLite.hpp
@@ -0,0 +1,72 @@
+/**
+ * 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_META_TYPE_LITE_HPP_
+#define QUICKSTEP_TYPES_META_TYPE_LITE_HPP_
+
+#include <cstddef>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class TypedValue;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class MetaType : public TypeSynthesizer<kMetaType> {
+ public:
+  int getPrintWidth() const override {
+    return 16;
+  }
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override;
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override;
+
+  std::string printValueToString(const UntypedLiteral *value) const override;
+
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
+    return false;
+  }
+
+ private:
+  MetaType(const bool nullable)
+      : TypeSynthesizer<kMetaType>(nullable, sizeof(TypeID), 0x100) {
+    // TODO(refactor-type): Possibly infinite maximum size.
+  }
+
+  QUICKSTEP_SYNTHESIZE_TYPE(MetaType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_META_TYPE_LITE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/ParameterizedPodLit.hpp
----------------------------------------------------------------------
diff --git a/types/ParameterizedPodLit.hpp b/types/ParameterizedPodLit.hpp
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index e449ee6..8092953 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -34,3 +34,7 @@ message GenericValue {
   required Type type = 1;
   optional bytes data = 2;
 }
+
+message ArrayLiteral {
+  repeated bytes data = 1;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index cebbd6b..29267f8 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -114,9 +114,7 @@ class TypeSynthesizePolicy<
   }
 
   TypedValue marshallValue(const UntypedLiteral *value) const override {
-    TypedValue ret = makeValue(value, sizeof(cpptype));
-    ret.ensureNotReference();
-    return ret;
+    return makeValue(value, sizeof(cpptype)).ensureNotReference();
   }
 
   UntypedLiteral* unmarshallValue(const void *data,
@@ -340,7 +338,9 @@ class TypeSynthesizePolicy<
   bool checkValuesEqual(const UntypedLiteral *lhs,
                         const UntypedLiteral *rhs,
                         const Type &rhs_type) const override {
-    LOG(FATAL) << "Not implemented";
+    // LOG(FATAL) << "Not implemented";
+    // TODO.
+    return false;
   }
 
   UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/eb156fdf/types/TypedValue.cpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.cpp b/types/TypedValue.cpp
index ad1eb0f..79e80a3 100644
--- a/types/TypedValue.cpp
+++ b/types/TypedValue.cpp
@@ -147,8 +147,12 @@ serialization::TypedValue TypedValue::getProto() const {
       DCHECK(isNull());
       break;
     default:
-      FATAL_ERROR("Unrecognized TypeID in TypedValue::getProto");
-  }
+//      FATAL_ERROR("Unrecognized TypeID in TypedValue::getProto");
+      if (!isNull()) {
+        proto.set_out_of_line_data(static_cast<const char*>(getOutOfLineData()), getDataSize());
+      }
+      break;
+}
 
   return proto;
 }
@@ -231,7 +235,12 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
     case kNullType:
       return TypedValue(kNullType);
     default:
-      FATAL_ERROR("Unrecognized TypeID in TypedValue::ReconstructFromProto");
+//      FATAL_ERROR("Unrecognized TypeID in TypedValue::ReconstructFromProto");
+      return proto.has_out_of_line_data() ?
+          TypedValue(type_id,
+                     static_cast<const void*>(proto.out_of_line_data().c_str()),
+                     proto.out_of_line_data().size()).ensureNotReference() :
+          TypedValue(type_id);
   }
 }
 


[05/38] incubator-quickstep git commit: Updates for array type

Posted by ji...@apache.org.
Updates for array type


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/0780fa2e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/0780fa2e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/0780fa2e

Branch: refs/heads/refactor-type
Commit: 0780fa2e29fa70fb8ad8c8fc03f4ee3913bc5d7b
Parents: a7ccb46
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Mon Oct 2 23:46:48 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 query_optimizer/expressions/CMakeLists.txt    |   1 +
 query_optimizer/expressions/ScalarLiteral.hpp |   3 +-
 query_optimizer/resolver/CMakeLists.txt       |   4 +
 query_optimizer/resolver/Resolver.cpp         |  70 ++-
 types/GenericValue.hpp                        |  18 +-
 types/Type.cpp                                |  18 +
 types/Type.hpp                                |  23 +-
 types/Type.proto                              |   2 +-
 types/TypeSynthesizer.hpp                     | 479 ++++++++++++---------
 utility/CharStream.hpp                        |  34 +-
 utility/meta/Common.hpp                       |  58 ++-
 validate_cmakelists.py                        |   8 +-
 12 files changed, 450 insertions(+), 268 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index dc722e7..cf2727f 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -97,6 +97,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions_BinaryExpression
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
                       quickstep_queryoptimizer_expressions_ScalarLiteral
+                      quickstep_types_GenericValue
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_utility_HashPair

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/query_optimizer/expressions/ScalarLiteral.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ScalarLiteral.hpp b/query_optimizer/expressions/ScalarLiteral.hpp
index 180ae39..f6a14f4 100644
--- a/query_optimizer/expressions/ScalarLiteral.hpp
+++ b/query_optimizer/expressions/ScalarLiteral.hpp
@@ -108,7 +108,8 @@ class ScalarLiteral : public Scalar {
   ScalarLiteral(const GenericValue &literal_value)
       : value_(literal_value) {}
 
-  const GenericValue &value_;
+  const GenericValue value_;
+
   DISALLOW_COPY_AND_ASSIGN(ScalarLiteral);
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/query_optimizer/resolver/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index a759ce3..8a1116a 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -120,7 +120,11 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
                       quickstep_queryoptimizer_resolver_NameResolver
                       quickstep_storage_StorageBlockLayout_proto
                       quickstep_storage_StorageConstants
+                      quickstep_types_ArrayType
+                      quickstep_types_GenericValue
                       quickstep_types_IntType
+                      quickstep_types_MetaType
+                      quickstep_types_NullType
                       quickstep_types_Type
                       quickstep_types_TypeUtil
                       quickstep_types_TypedValue

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 1ed6b2e..d97bf63 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -115,8 +115,11 @@
 #include "query_optimizer/resolver/NameResolver.hpp"
 #include "storage/StorageBlockLayout.pb.h"
 #include "storage/StorageConstants.hpp"
+#include "types/ArrayType.hpp"
 #include "types/GenericValue.hpp"
 #include "types/IntType.hpp"
+#include "types/MetaType.hpp"
+#include "types/NullType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeUtil.hpp"
@@ -2489,21 +2492,58 @@ E::ScalarPtr Resolver::resolveArray(
     const ParseArray &parse_array,
     const Type *type_hint,
     ExpressionResolutionInfo *expression_resolution_info) {
-//  std::vector<E::ScalarPtr> elements;
-//  const auto &parse_elements = parse_array.elements();
-//  if (parse_elements.empty()) {
-//    // TODO(jianqiao): Figure out how to handle empty array.
-//
-//  } else {
-//    elements.reserve(parse_elements.size());
-//    for (const auto &parse_element : parse_elements) {
-//      elements.emplace_back(
-//          resolveExpression(*parse_element, nullptr, expression_resolution_info));
-//    }
-//
-//    // Currently we only support homogeneous array with literal values.
-//  }
-  LOG(FATAL) << "Not supported";
+  const auto &parse_elements = parse_array.elements();
+  if (parse_elements.empty()) {
+    // TODO(jianqiao): Figure out how to handle empty array.
+    const GenericValue meta_null_type_value(
+        MetaType::InstanceNonNullable(), &NullType::InstanceNullable());
+    return E::ScalarLiteral::Create(
+        GenericValue(ArrayType::InstanceNonNullable({meta_null_type_value}),
+                     ArrayLiteral()));
+  } else {
+    // Currently we only support homogeneous array with literal values.
+    std::vector<E::ScalarLiteralPtr> literals;
+    const Type *element_type = nullptr;
+    for (const auto &parse_element : parse_elements) {
+      const E::ScalarPtr scalar =
+          resolveExpression(*parse_element, nullptr, expression_resolution_info);
+      E::ScalarLiteralPtr literal;
+      if (E::SomeScalarLiteral::MatchesWithConditionalCast(scalar, &literal)) {
+        const GenericValue &value = literal->value();
+        if (element_type == nullptr) {
+          element_type = &value.getType();
+        } else {
+          if (!element_type->equals(value.getType())) {
+            THROW_SQL_ERROR_AT(parse_element)
+                << "Heterogeneous array is not supported: "
+                << "array contains elements of at least two types "
+                << element_type->getName() << " and "
+                << value.getType().getName();
+          }
+        }
+        literals.emplace_back(literal);
+      } else {
+        THROW_SQL_ERROR_AT(parse_element)
+            << "Non-static array element is not supported yet";
+      }
+    }
+    DCHECK(element_type != nullptr);
+
+    const GenericValue meta_element_type_value(
+        MetaType::InstanceNonNullable(), element_type);
+    const Type &array_type =
+        ArrayType::InstanceNonNullable({meta_element_type_value});
+
+    // NOTE(refactor-type): Possibly memory leak region, noexcept.
+    std::unique_ptr<ArrayLiteral> array_literal = std::make_unique<ArrayLiteral>();
+    for (const auto &literal : literals) {
+      array_literal->emplace_back(
+          element_type->cloneValue(literal->value().getValue()));
+    }
+    return E::ScalarLiteral::Create(GenericValue(array_type,
+                                                 array_literal.release(),
+                                                 true /* take_ownership */));
+  }
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
index 1fcdcd6..62dd9a3 100644
--- a/types/GenericValue.hpp
+++ b/types/GenericValue.hpp
@@ -46,8 +46,10 @@ class GenericValue {
   GenericValue(const Type &type)
       : type_(type), value_(nullptr), owns_(true) {}
 
-  GenericValue(const Type &type, const UntypedLiteral *value, const bool owns)
-      : type_(type), value_(value), owns_(owns) {}
+  GenericValue(const Type &type,
+               const UntypedLiteral *value,
+               const bool take_ownership)
+      : type_(type), value_(value), owns_(take_ownership) {}
 
   GenericValue(const Type &type, const TypedValue &value)
       : type_(type), value_(type.unmarshallTypedValue(value)), owns_(true) {}
@@ -76,7 +78,13 @@ class GenericValue {
   }
 
   serialization::GenericValue getProto() const {
-    LOG(FATAL) << "Not implemented";
+    serialization::GenericValue proto;
+    proto.mutable_type()->MergeFrom(type_.getProto());
+    if (!isNull()) {
+      TypedValue tv = type_.marshallValue(value_);
+      proto.set_data(tv.getDataPtr(), tv.getDataSize());
+    }
+    return proto;
   }
 
   inline bool isNull() const {
@@ -131,7 +139,9 @@ class GenericValue {
   }
 
   inline GenericValue coerce(const Type &other_type) const {
-    LOG(FATAL) << "Not implemented";
+    return GenericValue(other_type,
+                        other_type.coerceValue(value_, type_),
+                        true /* take_ownership */);
   }
 
   inline TypedValue toTypedValue() const {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index b0b781a..41780f8 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -77,4 +77,22 @@ TypedValue Type::coerceTypedValue(const TypedValue &original_value,
   return original_value;
 }
 
+UntypedLiteral* Type::coerceValue(const UntypedLiteral *original_value,
+                                  const Type &original_type) const {
+  DCHECK(isCoercibleFrom(original_type))
+      << "Can't coerce value of Type " << original_type.getName()
+      << " to Type " << getName();
+
+  if (original_type.getTypeID() == kNullType) {
+    return nullptr;
+  }
+
+  DCHECK(equals(original_type) || equals(original_type.getNullableVersion()))
+      << "Base version of Type::coerceValue() called for a non-trivial "
+      << "coercion from Type " << original_type.getName()
+      << " to Type " << getName();
+
+  return cloneValue(original_value);
+}
+
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index d4ed993..e5d5528 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -401,42 +401,33 @@ class Type {
   virtual TypedValue coerceTypedValue(const TypedValue &original_value,
                                       const Type &original_type) const;
 
-
   virtual std::size_t getHash() const = 0;
 
   virtual bool checkValuesEqual(const UntypedLiteral *lhs,
                                 const UntypedLiteral *rhs,
-                                const Type &rhs_type) const {
-    LOG(FATAL) << "Not implemented";
-  }
+                                const Type &rhs_type) const = 0;
 
   inline bool checkValuesEqual(const UntypedLiteral *lhs,
                                const UntypedLiteral *rhs) const {
     return checkValuesEqual(lhs, rhs, *this);
   }
 
+  virtual UntypedLiteral* coerceValue(const UntypedLiteral *original_value,
+                                      const Type &original_type) const;
+
   virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const = 0;
 
   virtual void destroyValue(UntypedLiteral *value) const = 0;
 
-  virtual std::size_t hashValue(const UntypedLiteral *value) const {
-    LOG(FATAL) << "Not implemented";
-  }
+  virtual std::size_t hashValue(const UntypedLiteral *value) const = 0;
 
-  virtual TypedValue marshallValue(const UntypedLiteral *value) const {
-    LOG(FATAL) << "Not implemented";
-  }
+  virtual TypedValue marshallValue(const UntypedLiteral *value) const = 0;
 
   virtual UntypedLiteral* unmarshallValue(const void *data,
-                                          const std::size_t length) const {
-    LOG(FATAL) << "Not implemented";
-
-  }
+                                          const std::size_t length) const = 0;
 
   virtual UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const = 0;
 
-  virtual UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const = 0;
-
  protected:
   Type(const SuperTypeID super_type_id,
        const TypeID type_id,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index b93f894..e449ee6 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -32,5 +32,5 @@ message Type {
 
 message GenericValue {
   required Type type = 1;
-  required bytes data = 2;
+  optional bytes data = 2;
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index 08ab67a..cebbd6b 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -38,6 +38,9 @@
 #include "types/TypedValue.hpp"
 #include "utility/HashPair.hpp"
 #include "utility/Macros.hpp"
+#include "utility/meta/Common.hpp"
+
+#include "third_party/src/farmhash/farmhash.h"
 
 #include "glog/logging.h"
 
@@ -51,142 +54,13 @@ template <TypeID type_id, typename Enable = void>
 class TypeSynthesizePolicy;
 
 
-template <TypeID type_id>
-class TypeSynthesizer
-    : public Type,
-      public TypeSynthesizePolicy<type_id> {
- private:
-  using Trait = TypeIDTrait<type_id>;
-  using SynthesizePolicy = TypeSynthesizePolicy<type_id>;
-
- public:
-  static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
-  static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID;
-  static constexpr bool kIsParPod = Trait::kIsParPod;
-  static constexpr MemoryLayout kMemoryLayout = Trait::kMemoryLayout;
-
-  using TypeClass = typename Trait::TypeClass;
-  using cpptype = typename Trait::cpptype;
-
-  serialization::Type getProto() const override {
-    serialization::Type proto;
-
-    proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
-    proto.set_nullable(nullable_);
-    SynthesizePolicy::mergeIntoProto(&proto);
-
-    return proto;
-  }
-
-  const Type& getNullableVersion() const override {
-    return SynthesizePolicy::getInstance(true);
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return SynthesizePolicy::getInstance(false);
-  }
-
-  std::size_t getHash() const override {
-    return SynthesizePolicy::getHash();
-  }
-
-  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
-    return SynthesizePolicy::cloneValue(value);
-  }
-
-  void destroyValue(UntypedLiteral *value) const override {
-    return SynthesizePolicy::destroyValue(value);
-  }
-
-  UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override {
-    return SynthesizePolicy::unmarshallTypedValue(value);
-  }
-
-  UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const override {
-    return SynthesizePolicy::unmarshallTypedValue(std::move(value));
-  }
-
-  std::string printTypedValueToString(const TypedValue &value) const override {
-    return SynthesizePolicy::invokeOnUnmarshalledTypedValue(
-        value,
-        [&](const UntypedLiteral *value) -> std::string {
-      return this->printValueToString(value);
-    });
-  }
-
-  void printTypedValueToFile(const TypedValue &value,
-                             FILE *file,
-                             const int padding = 0) const override {
-    SynthesizePolicy::invokeOnUnmarshalledTypedValue(
-        value,
-        [&](const UntypedLiteral *value) -> void {
-      this->printValueToFile(value, file, padding);
-    });
-  }
-
-  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
-    return *static_cast<const cpptype*>(value);
-  }
-
-  cpptype& castValueToLiteral(UntypedLiteral *value) const {
-    return *static_cast<cpptype*>(value);
-  }
-
- protected:
-  template <MemoryLayout layout = kMemoryLayout>
-  explicit TypeSynthesizer(const bool nullable,
-                           std::enable_if_t<layout == kCxxInlinePod>* = 0)
-      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
-             sizeof(cpptype), sizeof(cpptype)),
-        TypeSynthesizePolicy<type_id>(this) {
-  }
-
-  template <MemoryLayout layout = kMemoryLayout>
-  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<layout == kParInlinePod ||
-                                   layout == kParOutOfLinePod>* = 0)
-      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
-             minimum_byte_length, maximum_byte_length),
-        TypeSynthesizePolicy<type_id>(this, parameter) {
-  }
-
-  template <MemoryLayout layout = kMemoryLayout>
-  TypeSynthesizer(const bool nullable,
-                  const std::size_t minimum_byte_length,
-                  const std::size_t maximum_byte_length,
-                  const std::vector<GenericValue> &parameters = {},
-                  std::enable_if_t<layout == kCxxGeneric>* = 0)
-      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
-             minimum_byte_length, maximum_byte_length),
-        TypeSynthesizePolicy<type_id>(this, parameters) {
-  }
-
- private:
-  template <TypeID, typename> friend class TypeSynthesizePolicy;
-
-  DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
-};
-
-template <TypeID type_id>
-constexpr SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
-
-template <TypeID type_id>
-constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
-
-template <TypeID type_id>
-constexpr bool TypeSynthesizer<type_id>::kIsParPod;
-
-template <TypeID type_id>
-constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
-
-
+////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////  CxxInlinePod  ///////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 template <TypeID type_id>
 class TypeSynthesizePolicy<
     type_id,
-    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> {
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> : public Type {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
@@ -209,34 +83,63 @@ class TypeSynthesizePolicy<
     }
   }
 
- protected:
-  explicit TypeSynthesizePolicy(const Type *base)
-      : base_(*base) {}
-
-  inline const Type& getInstance(const bool nullable) const {
-    return nullable ? InstanceNullable() : InstanceNonNullable();
+  std::size_t getHash() const override {
+    return static_cast<std::size_t>(getTypeID());
   }
 
-  inline void mergeIntoProto(serialization::Type *proto) const {}
-
-  inline std::size_t getHash() const {
-    return static_cast<std::size_t>(base_.getTypeID());
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override {
+    // TODO(refactor-type): Operator == overloading.
+    if (type_id_ != rhs_type.getTypeID()) {
+      return false;
+    }
+    return !std::memcmp(lhs, rhs, sizeof(cpptype));
   }
 
-  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
     DCHECK(value != nullptr);
     UntypedLiteral* clone = std::malloc(sizeof(cpptype));
     std::memcpy(clone, value, sizeof(cpptype));
     return clone;
   }
 
-  inline void destroyValue(UntypedLiteral *value) const {
+  void destroyValue(UntypedLiteral *value) const override {
     DCHECK(value != nullptr);
     std::free(value);
   }
 
-  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
-    return base_.cloneValue(value.getDataPtr());
+  std::size_t hashValue(const UntypedLiteral *value) const override {
+    return hashValueInl<sizeof(cpptype)>(value);
+  }
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override {
+    TypedValue ret = makeValue(value, sizeof(cpptype));
+    ret.ensureNotReference();
+    return ret;
+  }
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override {
+    DCHECK_EQ(sizeof(cpptype), length);
+    UntypedLiteral *value = std::malloc(sizeof(cpptype));
+    std::memcpy(value, data, sizeof(cpptype));
+    return value;
+  }
+
+ protected:
+  explicit TypeSynthesizePolicy(const bool nullable)
+      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+             sizeof(cpptype), sizeof(cpptype)) {}
+
+  inline const Type& getInstance(const bool nullable) const {
+    return nullable ? InstanceNullable() : InstanceNonNullable();
+  }
+
+  inline void mergeIntoProto(serialization::Type *proto) const {}
+
+  inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const {
+    return cloneValue(value.getDataPtr());
   }
 
   template <typename Functor>
@@ -252,14 +155,35 @@ class TypeSynthesizePolicy<
     return instance;
   }
 
-  const Type &base_;
+  template <std::size_t size>
+  inline std::size_t hashValueInl(
+      const UntypedLiteral *value,
+      std::enable_if_t<meta::CxxSupportedIntegerSizes
+                           ::template contains<size>::value> * = 0) const {
+    using CxxUIntType = typename meta::UnsignedInteger<size>::type;
+    CxxUIntType buffer;
+    std::memcpy(&buffer, value, size);
+    return buffer;
+  }
+
+  template <std::size_t size>
+  inline std::size_t hashValueInl(
+      const UntypedLiteral *value,
+      std::enable_if_t<!meta::CxxSupportedIntegerSizes
+                            ::template contains<size>::value> * = 0) const {
+    return util::Hash(static_cast<const char*>(value), size);
+  }
 };
 
+
+////////////////////////////////////////////////////////////////////////////////
+///////////////////////  ParInlinePod & ParOutOfLinePod  ///////////////////////
+////////////////////////////////////////////////////////////////////////////////
 template <TypeID type_id>
 class TypeSynthesizePolicy<
     type_id,
     std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod ||
-                     TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> {
+                     TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> : public Type {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
@@ -285,45 +209,70 @@ class TypeSynthesizePolicy<
     }
   }
 
-  inline std::size_t length() const {
+  std::size_t length() const {
     return length_;
   }
 
- protected:
-  TypeSynthesizePolicy(const Type *base, const std::size_t length)
-      : length_(length),
-        base_(*base) {}
-
-  const std::size_t length_;
-
-  inline const Type& getInstance(const bool nullable) const {
-    return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_);
+  std::size_t getHash() const override {
+    return CombineHashes(static_cast<std::size_t>(type_id), length_);
   }
 
-  inline void mergeIntoProto(serialization::Type *proto) const {
-    proto->set_length(length_);
+  std::size_t hashValue(const UntypedLiteral *value) const override {
+    // TODO(refactor-type): Better implementation.
+    return static_cast<const TypedValue*>(value)->getHash();
   }
 
-  inline std::size_t getHash() const {
-    return CombineHashes(static_cast<std::size_t>(base_.getTypeID()), length_);
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override {
+    // TODO(refactor-type): Better implementation.
+    const TypedValue *lhs_value = static_cast<const TypedValue*>(lhs);
+    const TypedValue *rhs_value = static_cast<const TypedValue*>(rhs);
+    return lhs_value->fastEqualCheck(*rhs_value);
   }
 
-  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
     DCHECK(value != nullptr);
     return new TypedValue(*static_cast<const TypedValue*>(value));
   }
 
-  inline void destroyValue(UntypedLiteral *value) const {
+  void destroyValue(UntypedLiteral *value) const override {
     DCHECK(value != nullptr);
     delete static_cast<TypedValue*>(value);
   }
 
-  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
-    return base_.cloneValue(&value);
+  TypedValue marshallValue(const UntypedLiteral *value) const override {
+    return *static_cast<const TypedValue*>(value);
   }
 
-  inline UntypedLiteral* unmarshallTypedValue(TypedValue &&value) const {
-    return new TypedValue(std::move(value));
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override {
+    TypedValue *value = new TypedValue(makeValue(data, length));
+    value->ensureNotReference();
+    return value;
+  }
+
+ protected:
+  TypeSynthesizePolicy(const bool nullable,
+                       const std::size_t minimum_byte_length,
+                       const std::size_t maximum_byte_length,
+                       const std::size_t length)
+      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+             minimum_byte_length, maximum_byte_length),
+        length_(length) {}
+
+  const std::size_t length_;
+
+  inline const Type& getInstance(const bool nullable) const {
+    return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_);
+  }
+
+  inline void mergeIntoProto(serialization::Type *proto) const {
+    proto->set_length(length_);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const {
+    return new TypedValue(value);
   }
 
   template <typename Functor>
@@ -343,14 +292,16 @@ class TypeSynthesizePolicy<
     }
     return *(imit->second);
   }
-
-  const Type &base_;
 };
 
+
+////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////  CxxGeneric  ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 template <TypeID type_id>
 class TypeSynthesizePolicy<
     type_id,
-    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> {
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> : public Type {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
@@ -377,15 +328,53 @@ class TypeSynthesizePolicy<
     }
   }
 
-  inline const std::vector<GenericValue>& parameters() const {
+  const std::vector<GenericValue>& parameters() const {
     return parameters_;
   }
 
+  std::size_t getHash() const override {
+    return CombineHashes(static_cast<std::size_t>(type_id_),
+                         ParametersHasher::ComputeHash(parameters_));
+  }
+
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
+    return new cpptype(*static_cast<const cpptype*>(value));
+  }
+
+  void destroyValue(UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
+    delete static_cast<cpptype*>(value);
+  }
+
+  std::size_t hashValue(const UntypedLiteral *value) const override {
+    // TODO(refactor-type): Add note that it is a shallow hash.
+    return util::Hash(static_cast<const char*>(value), sizeof(cpptype));
+  }
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override {
+    LOG(FATAL) << "Not implemented";
+  }
+
  protected:
-  TypeSynthesizePolicy(const Type *base,
+  TypeSynthesizePolicy(const bool nullable,
+                       const std::size_t minimum_byte_length,
+                       const std::size_t maximum_byte_length,
                        const std::vector<GenericValue> &parameters)
-      : parameters_(parameters),
-        base_(*base) {}
+      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+             minimum_byte_length, maximum_byte_length),
+        parameters_(parameters) {}
 
   inline const Type& getInstance(const bool nullable) const {
     return nullable ? InstanceNullable(parameters_)
@@ -398,32 +387,16 @@ class TypeSynthesizePolicy<
     }
   }
 
-  inline std::size_t getHash() const {
-    return CombineHashes(static_cast<std::size_t>(base_.getTypeID()),
-                         ParametersHasher::ComputeHash(parameters_));
-  }
-
-  inline UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
-    DCHECK(value != nullptr);
-    return new cpptype(*static_cast<const cpptype*>(value));
-  }
-
-  inline void destroyValue(UntypedLiteral *value) const {
-    DCHECK(value != nullptr);
-    delete static_cast<cpptype*>(value);
-  }
-
-  inline UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const {
-    return base_.unmarshallValue(value.getOutOfLineData(), value.getDataSize());
+  inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const {
+    return unmarshallValue(value.getOutOfLineData(), value.getDataSize());
   }
 
   template <typename Functor>
   inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
                                              const Functor &functor) const {
-    std::unique_ptr<typename Trait::cpptype> literal(
-        static_cast<typename Trait::cpptype*>(
-            base_.unmarshallValue(value.getOutOfLineData(),
-                                  value.getDataSize())));
+    std::unique_ptr<cpptype> literal(
+        static_cast<cpptype*>(unmarshallValue(value.getOutOfLineData(),
+                                              value.getDataSize())));
     return functor(literal.get());
   }
 
@@ -477,10 +450,120 @@ class TypeSynthesizePolicy<
     }
     return *(imit->second);
   }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////  TypeSynthesizer  //////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+template <TypeID type_id>
+class TypeSynthesizer : public TypeSynthesizePolicy<type_id> {
+ private:
+  using Trait = TypeIDTrait<type_id>;
+  using SynthesizePolicy = TypeSynthesizePolicy<type_id>;
+
+ public:
+  static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
+  static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID;
+  static constexpr bool kIsParPod = Trait::kIsParPod;
+  static constexpr MemoryLayout kMemoryLayout = Trait::kMemoryLayout;
+
+  using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
+
+  serialization::Type getProto() const override {
+    serialization::Type proto;
+    proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(Type::type_id_));
+    proto.set_nullable(Type::nullable_);
+    SynthesizePolicy::mergeIntoProto(&proto);
+    return proto;
+  }
+
+  const Type& getNullableVersion() const override {
+    return SynthesizePolicy::getInstance(true);
+  }
+
+  const Type& getNonNullableVersion() const override {
+    return SynthesizePolicy::getInstance(false);
+  }
+
+  UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override {
+    return SynthesizePolicy::unmarshallTypedValueInl(value);
+  }
+
+  std::string printTypedValueToString(const TypedValue &value) const override {
+    return SynthesizePolicy::invokeOnUnmarshalledTypedValue(
+        value,
+        [&](const UntypedLiteral *value) -> std::string {
+      return this->printValueToString(value);
+    });
+  }
+
+  void printTypedValueToFile(const TypedValue &value,
+                             FILE *file,
+                             const int padding = 0) const override {
+    SynthesizePolicy::invokeOnUnmarshalledTypedValue(
+        value,
+        [&](const UntypedLiteral *value) -> void {
+      this->printValueToFile(value, file, padding);
+    });
+  }
+
+  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
+    return *static_cast<const cpptype*>(value);
+  }
+
+  cpptype& castValueToLiteral(UntypedLiteral *value) const {
+    return *static_cast<cpptype*>(value);
+  }
+
+ protected:
+  template <MemoryLayout layout = kMemoryLayout>
+  explicit TypeSynthesizer(const bool nullable,
+                           std::enable_if_t<layout == kCxxInlinePod>* = 0)
+      : TypeSynthesizePolicy<type_id>(nullable) {
+  }
+
+  template <MemoryLayout layout = kMemoryLayout>
+  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<layout == kParInlinePod ||
+                                   layout == kParOutOfLinePod>* = 0)
+      : TypeSynthesizePolicy<type_id>(nullable, minimum_byte_length,
+                                      maximum_byte_length, parameter) {
+  }
+
+  template <MemoryLayout layout = kMemoryLayout>
+  TypeSynthesizer(const bool nullable,
+                  const std::size_t minimum_byte_length,
+                  const std::size_t maximum_byte_length,
+                  const std::vector<GenericValue> &parameters = {},
+                  std::enable_if_t<layout == kCxxGeneric>* = 0)
+      : TypeSynthesizePolicy<type_id>(nullable, minimum_byte_length,
+                                      maximum_byte_length, parameters) {
+  }
+
+ private:
+  template <TypeID, typename> friend class TypeSynthesizePolicy;
 
-  const Type &base_;
+  DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
 
+template <TypeID type_id>
+constexpr SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
+
+template <TypeID type_id>
+constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
+
+template <TypeID type_id>
+constexpr bool TypeSynthesizer<type_id>::kIsParPod;
+
+template <TypeID type_id>
+constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
+
+
 #define QUICKSTEP_SYNTHESIZE_TYPE(type) \
   template <TypeID, typename> friend class TypeSynthesizePolicy; \
   DISALLOW_COPY_AND_ASSIGN(type)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/utility/CharStream.hpp
----------------------------------------------------------------------
diff --git a/utility/CharStream.hpp b/utility/CharStream.hpp
index 060b1a6..5d6ed0b 100644
--- a/utility/CharStream.hpp
+++ b/utility/CharStream.hpp
@@ -40,32 +40,45 @@ class CharStream {
   template <typename T>
   CharStream(const T &value,
              std::enable_if_t<std::is_pod<T>::value && sizeof(T) <= sizeof(std::uint64_t)> * = 0)
-      : length_(sizeof(T)),
+      : object_(nullptr),
+        length_(sizeof(T)),
         delete_function_(nullptr) {
     std::memcpy(&value_union_.inline_data, &value, sizeof(T));
   }
 
-  CharStream(std::vector<char> &&value)
-      : length_(value.size()),
+  CharStream(const std::vector<char> *value)
+      : object_(const_cast<std::vector<char>*>(value)),
+        length_(value->size()),
         delete_function_(&DeleteObject<std::vector<char>>) {
-    value_union_.out_of_line_data = new std::vector<char>(std::move(value));
+    value_union_.out_of_line_data = value->data();
   }
 
-  CharStream(const void *value, const std::size_t length, const bool take_ownership)
+  CharStream(const void *value,
+             const std::size_t length,
+             const bool take_ownership)
       : length_(length),
         delete_function_(std::free) {
     if (take_ownership) {
-      value_union_.out_of_line_data = value;
+      object_ = const_cast<void*>(value);
     } else {
-      void *copy_of_value = std::malloc(length);
-      std::memcpy(copy_of_value, value, length);
-      value_union_.out_of_line_data = copy_of_value;
+      object_ = std::malloc(length);
+      std::memcpy(object_, value, length);
     }
+    value_union_.out_of_line_data = object_;
+  }
+
+  CharStream(CharStream &&other)
+      : object_(other.object_),
+        length_(other.length_),
+        value_union_(other.value_union_),
+        delete_function_(other.delete_function_) {
+    other.delete_function_ = nullptr;
   }
 
   ~CharStream() {
     if (delete_function_ != nullptr) {
-      delete_function_(const_cast<void*>(value_union_.out_of_line_data));
+      DCHECK(object_ != nullptr);
+      delete_function_(object_);
     }
   }
 
@@ -91,6 +104,7 @@ class CharStream {
     delete static_cast<T*>(object);
   }
 
+  void *object_;
   std::size_t length_;
   ValueUnion value_union_;
   DeleterFunction delete_function_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/utility/meta/Common.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp
index 39c513e..901b65c 100644
--- a/utility/meta/Common.hpp
+++ b/utility/meta/Common.hpp
@@ -27,6 +27,22 @@ namespace meta {
  *  @{
  */
 
+template <typename ...> struct Conjunction : std::true_type {};
+template <typename B> struct Conjunction<B> : B {};
+template <typename B, typename ...Bs>
+struct Conjunction<B, Bs...>
+    : std::conditional_t<B::value, Conjunction<Bs...>, B> {};
+
+template <typename ...> struct Disjunction : std::false_type {};
+template <typename B> struct Disjunction<B> : B {};
+template <typename B, typename ...Bs>
+struct Disjunction<B, Bs...>
+    : std::conditional_t<B::value, B, Disjunction<Bs...>> {};
+
+template <typename check, typename ...cases>
+struct EqualsAny : Disjunction<std::is_same<check, cases>...> {};
+
+
 template <typename T, T ...s>
 struct Sequence {
   template <template <typename ...> class Host>
@@ -38,6 +54,10 @@ struct Sequence {
   template <typename U>
   using cast_to = Sequence<U, static_cast<U>(s)...>;
 
+  template <T v>
+  using contains = EqualsAny<std::integral_constant<T, v>,
+                             std::integral_constant<T, s>...>;
+
   template <typename CollectionT>
   inline static CollectionT Instantiate() {
     return { s... };
@@ -57,25 +77,6 @@ struct MakeSequence<0, s...> {
 };
 
 
-template <typename ...> struct Conjunction : std::true_type {};
-template <typename B> struct Conjunction<B> : B {};
-template <typename B, typename ...Bs>
-struct Conjunction<B, Bs...>
-    : std::conditional_t<B::value, Conjunction<Bs...>, B> {};
-
-template <typename ...> struct Disjunction : std::false_type {};
-template <typename B> struct Disjunction<B> : B {};
-template <typename B, typename ...Bs>
-struct Disjunction<B, Bs...>
-    : std::conditional_t<B::value, B, Disjunction<Bs...>> {};
-
-template <typename check, typename ...cases>
-struct EqualsAny {
-  static constexpr bool value =
-     Disjunction<std::is_same<check, cases>...>::value;
-};
-
-
 template <typename T, typename Enable = void>
 struct IsTrait {
   static constexpr bool value = false;
@@ -135,6 +136,25 @@ struct TraitUnwrapper {
   using type = typename Op<ArgTypes...>::type;
 };
 
+
+using CxxSupportedIntegerSizes = meta::IntegerSequence<1u, 2u, 4u, 8u>;
+
+template <std::size_t size>
+struct UnsignedInteger;
+
+template <> struct UnsignedInteger<1u> {
+  using type = std::uint8_t;
+};
+template <> struct UnsignedInteger<2u> {
+  using type = std::uint16_t;
+};
+template <> struct UnsignedInteger<4u> {
+  using type = std::uint32_t;
+};
+template <> struct UnsignedInteger<8u> {
+  using type = std::uint64_t;
+};
+
 /** @} */
 
 }  // namespace meta

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0780fa2e/validate_cmakelists.py
----------------------------------------------------------------------
diff --git a/validate_cmakelists.py b/validate_cmakelists.py
index f5f2f89..4de44c9 100755
--- a/validate_cmakelists.py
+++ b/validate_cmakelists.py
@@ -415,7 +415,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs):
                     validation_failed_targets.add(target)
                     print("Missing target_link_libraries() for " + target + ":")
                     for dep in sorted(include_deps):
-                        print("\t" + dep)
+                        print("                      " + dep)
             else:
                 missing_deps = (include_deps
                                 - deps_in_cmake[target]
@@ -424,7 +424,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs):
                     validation_failed_targets.add(target)
                     print("Missing target_link_libraries() for " + target + ":")
                     for dep in sorted(missing_deps):
-                        print("\t" + dep)
+                        print("                      " + dep)
         elif target == module_targetname:
             # Special case hack for module all-in-one library
             missing_deps = (frozenset(deps_from_includes.keys())
@@ -438,7 +438,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs):
                 validation_failed_targets.add(target)
                 print("Missing target_link_libraries() for " + target + ":")
                 for dep in sorted(true_missing_deps):
-                    print("\t" + dep)
+                    print("                      " + dep)
     # Also report possibly superfluous extra dependencies.
     for target, cmake_deps in iter(deps_in_cmake.items()):
         if (target not in skipped_targets) and (target in deps_from_includes):
@@ -450,7 +450,7 @@ def process_cmakelists_file(cmakelists_filename, qs_module_dirs):
                 print("Possibly superfluous target_link_libraries() for "
                        + target + ":")
                 for dep in sorted(extra_deps):
-                    print("\t" + dep)
+                    print("                      " + dep)
     return (validation_failed_targets, skipped_targets, generated_targets)
 
 def main(cmakelists_to_process):



[35/38] incubator-quickstep git commit: Type as first class citizen

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index 69b78e7..037f697 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -72,117 +72,103 @@ extern int quickstep_yydebug;
     TOKEN_ALTER = 282,
     TOKEN_AS = 283,
     TOKEN_ASC = 284,
-    TOKEN_BIGINT = 285,
-    TOKEN_BIT = 286,
-    TOKEN_BITWEAVING = 287,
-    TOKEN_BLOCKPROPERTIES = 288,
-    TOKEN_BLOCKSAMPLE = 289,
-    TOKEN_BLOOM_FILTER = 290,
-    TOKEN_CSB_TREE = 291,
-    TOKEN_BY = 292,
-    TOKEN_CASE = 293,
-    TOKEN_CAST = 294,
-    TOKEN_CHARACTER = 295,
-    TOKEN_CHECK = 296,
-    TOKEN_COLUMN = 297,
-    TOKEN_CONSTRAINT = 298,
-    TOKEN_COPY = 299,
-    TOKEN_CREATE = 300,
-    TOKEN_CURRENT = 301,
-    TOKEN_DATE = 302,
-    TOKEN_DATETIME = 303,
-    TOKEN_DAY = 304,
-    TOKEN_DECIMAL = 305,
-    TOKEN_DEFAULT = 306,
-    TOKEN_DELETE = 307,
-    TOKEN_DESC = 308,
-    TOKEN_DISTINCT = 309,
-    TOKEN_DOUBLE = 310,
-    TOKEN_DOUBLECOLON = 311,
-    TOKEN_DROP = 312,
-    TOKEN_ELSE = 313,
-    TOKEN_END = 314,
-    TOKEN_EXISTS = 315,
-    TOKEN_EXTRACT = 316,
-    TOKEN_FALSE = 317,
-    TOKEN_FIRST = 318,
-    TOKEN_FLOAT = 319,
-    TOKEN_FOLLOWING = 320,
-    TOKEN_FOR = 321,
-    TOKEN_FOREIGN = 322,
-    TOKEN_FROM = 323,
-    TOKEN_FULL = 324,
-    TOKEN_GROUP = 325,
-    TOKEN_HASH = 326,
-    TOKEN_HAVING = 327,
-    TOKEN_HOUR = 328,
-    TOKEN_IN = 329,
-    TOKEN_INDEX = 330,
-    TOKEN_INNER = 331,
-    TOKEN_INSERT = 332,
-    TOKEN_INTEGER = 333,
-    TOKEN_INTERVAL = 334,
-    TOKEN_INTO = 335,
-    TOKEN_JOIN = 336,
-    TOKEN_KEY = 337,
-    TOKEN_LAST = 338,
-    TOKEN_LBRACE = 339,
-    TOKEN_LEFT = 340,
-    TOKEN_LIMIT = 341,
-    TOKEN_LONG = 342,
-    TOKEN_MINUTE = 343,
-    TOKEN_MONTH = 344,
-    TOKEN_NULL = 345,
-    TOKEN_NULLS = 346,
-    TOKEN_OFF = 347,
-    TOKEN_ON = 348,
-    TOKEN_ORDER = 349,
-    TOKEN_OUTER = 350,
-    TOKEN_OVER = 351,
-    TOKEN_PARTITION = 352,
-    TOKEN_PARTITIONS = 353,
-    TOKEN_PERCENT = 354,
-    TOKEN_PRECEDING = 355,
-    TOKEN_PRIMARY = 356,
-    TOKEN_PRIORITY = 357,
-    TOKEN_QUIT = 358,
-    TOKEN_RANGE = 359,
-    TOKEN_RBRACE = 360,
-    TOKEN_REAL = 361,
-    TOKEN_REFERENCES = 362,
-    TOKEN_RIGHT = 363,
-    TOKEN_ROW = 364,
-    TOKEN_ROW_DELIMITER = 365,
-    TOKEN_ROWS = 366,
-    TOKEN_SECOND = 367,
-    TOKEN_SELECT = 368,
-    TOKEN_SET = 369,
-    TOKEN_SMA = 370,
-    TOKEN_SMALLINT = 371,
-    TOKEN_STDERR = 372,
-    TOKEN_STDOUT = 373,
-    TOKEN_SUBSTRING = 374,
-    TOKEN_TABLE = 375,
-    TOKEN_THEN = 376,
-    TOKEN_TIME = 377,
-    TOKEN_TIMESTAMP = 378,
-    TOKEN_TO = 379,
-    TOKEN_TRUE = 380,
-    TOKEN_TUPLESAMPLE = 381,
-    TOKEN_UNBOUNDED = 382,
-    TOKEN_UNIQUE = 383,
-    TOKEN_UPDATE = 384,
-    TOKEN_USING = 385,
-    TOKEN_VALUES = 386,
-    TOKEN_VARCHAR = 387,
-    TOKEN_WHEN = 388,
-    TOKEN_WHERE = 389,
-    TOKEN_WINDOW = 390,
-    TOKEN_WITH = 391,
-    TOKEN_YEAR = 392,
-    TOKEN_YEARMONTH = 393,
-    TOKEN_EOF = 394,
-    TOKEN_LEX_ERROR = 395
+    TOKEN_BIT = 285,
+    TOKEN_BITWEAVING = 286,
+    TOKEN_BLOCKPROPERTIES = 287,
+    TOKEN_BLOCKSAMPLE = 288,
+    TOKEN_BLOOM_FILTER = 289,
+    TOKEN_CSB_TREE = 290,
+    TOKEN_BY = 291,
+    TOKEN_CASE = 292,
+    TOKEN_CAST = 293,
+    TOKEN_CHECK = 294,
+    TOKEN_COLUMN = 295,
+    TOKEN_CONSTRAINT = 296,
+    TOKEN_COPY = 297,
+    TOKEN_CREATE = 298,
+    TOKEN_CURRENT = 299,
+    TOKEN_DAY = 300,
+    TOKEN_DEFAULT = 301,
+    TOKEN_DELETE = 302,
+    TOKEN_DESC = 303,
+    TOKEN_DISTINCT = 304,
+    TOKEN_DOUBLECOLON = 305,
+    TOKEN_DROP = 306,
+    TOKEN_ELSE = 307,
+    TOKEN_END = 308,
+    TOKEN_EXISTS = 309,
+    TOKEN_EXTRACT = 310,
+    TOKEN_FALSE = 311,
+    TOKEN_FIRST = 312,
+    TOKEN_FOLLOWING = 313,
+    TOKEN_FOR = 314,
+    TOKEN_FOREIGN = 315,
+    TOKEN_FROM = 316,
+    TOKEN_FULL = 317,
+    TOKEN_GROUP = 318,
+    TOKEN_HASH = 319,
+    TOKEN_HAVING = 320,
+    TOKEN_HOUR = 321,
+    TOKEN_IN = 322,
+    TOKEN_INDEX = 323,
+    TOKEN_INNER = 324,
+    TOKEN_INSERT = 325,
+    TOKEN_INTERVAL = 326,
+    TOKEN_INTO = 327,
+    TOKEN_JOIN = 328,
+    TOKEN_KEY = 329,
+    TOKEN_LAST = 330,
+    TOKEN_LBRACE = 331,
+    TOKEN_LEFT = 332,
+    TOKEN_LIMIT = 333,
+    TOKEN_MINUTE = 334,
+    TOKEN_MONTH = 335,
+    TOKEN_NULL = 336,
+    TOKEN_NULLS = 337,
+    TOKEN_OFF = 338,
+    TOKEN_ON = 339,
+    TOKEN_ORDER = 340,
+    TOKEN_OUTER = 341,
+    TOKEN_OVER = 342,
+    TOKEN_PARTITION = 343,
+    TOKEN_PARTITIONS = 344,
+    TOKEN_PERCENT = 345,
+    TOKEN_PRECEDING = 346,
+    TOKEN_PRIMARY = 347,
+    TOKEN_PRIORITY = 348,
+    TOKEN_QUIT = 349,
+    TOKEN_RANGE = 350,
+    TOKEN_RBRACE = 351,
+    TOKEN_REAL = 352,
+    TOKEN_REFERENCES = 353,
+    TOKEN_RIGHT = 354,
+    TOKEN_ROW = 355,
+    TOKEN_ROW_DELIMITER = 356,
+    TOKEN_ROWS = 357,
+    TOKEN_SECOND = 358,
+    TOKEN_SELECT = 359,
+    TOKEN_SET = 360,
+    TOKEN_SMA = 361,
+    TOKEN_STDERR = 362,
+    TOKEN_STDOUT = 363,
+    TOKEN_SUBSTRING = 364,
+    TOKEN_TABLE = 365,
+    TOKEN_THEN = 366,
+    TOKEN_TO = 367,
+    TOKEN_TRUE = 368,
+    TOKEN_TUPLESAMPLE = 369,
+    TOKEN_UNBOUNDED = 370,
+    TOKEN_UNIQUE = 371,
+    TOKEN_UPDATE = 372,
+    TOKEN_USING = 373,
+    TOKEN_VALUES = 374,
+    TOKEN_WHEN = 375,
+    TOKEN_WHERE = 376,
+    TOKEN_WINDOW = 377,
+    TOKEN_WITH = 378,
+    TOKEN_YEAR = 379,
+    TOKEN_EOF = 380,
+    TOKEN_LEX_ERROR = 381
   };
 #endif
 
@@ -191,7 +177,7 @@ extern int quickstep_yydebug;
 
 union YYSTYPE
 {
-#line 115 "../SqlParser.ypp" /* yacc.c:1915  */
+#line 116 "../SqlParser.ypp" /* yacc.c:1915  */
 
   quickstep::ParseString *string_value_;
 
@@ -293,7 +279,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 297 "SqlParser_gen.hpp" /* yacc.c:1915  */
+#line 283 "SqlParser_gen.hpp" /* yacc.c:1915  */
 };
 
 typedef union YYSTYPE YYSTYPE;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index d97bf63..37a93fb 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -639,13 +639,14 @@ L::LogicalPtr Resolver::resolveCreateTable(
           << "Column " << attribute_definition.name()->value()
           << " is specified more than once";
     }
-    attributes.emplace_back(
-        E::AttributeReference::Create(context_->nextExprId(),
-                                      attribute_definition.name()->value(),
-                                      attribute_definition.name()->value(),
-                                      relation_name,
-                                      attribute_definition.data_type().getType(),
-                                      E::AttributeReferenceScope::kLocal));
+    LOG(FATAL) << "TODO(refactor-type): To implement";
+//    attributes.emplace_back(
+//        E::AttributeReference::Create(context_->nextExprId(),
+//                                      attribute_definition.name()->value(),
+//                                      attribute_definition.name()->value(),
+//                                      relation_name,
+//                                      attribute_definition.data_type().getType(),
+//                                      E::AttributeReferenceScope::kLocal));
     attribute_name_set.insert(lower_attribute_name);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index d4bc26e..0ee4f26 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -49,7 +49,7 @@ add_library(quickstep_types_IntervalLit ../empty_src.cpp IntervalLit.hpp)
 add_library(quickstep_types_IntervalParser IntervalParser.cpp IntervalParser.hpp)
 add_library(quickstep_types_LongType LongType.cpp LongType.hpp)
 add_library(quickstep_types_MetaType MetaType.cpp MetaType.hpp)
-add_library(quickstep_types_MetaTypeLite MetaTypeLite.cpp MetaTypeLite.hpp)
+add_library(quickstep_types_MetaType-decl ../empty_src.cpp MetaType-decl.hpp)
 add_library(quickstep_types_NullCoercibilityCheckMacro ../empty_src.cpp NullCoercibilityCheckMacro.hpp)
 add_library(quickstep_types_NullLit ../empty_src.cpp NullLit.hpp)
 add_library(quickstep_types_NullType ../empty_src.cpp NullType.hpp)
@@ -59,8 +59,8 @@ add_library(quickstep_types_NumericTypeUnifier ../empty_src.cpp NumericTypeUnifi
 add_library(quickstep_types_TextType TextType.cpp TextType.hpp)
 add_library(quickstep_types_Type Type.cpp Type.hpp)
 add_library(quickstep_types_TypeErrors ../empty_src.cpp TypeErrors.hpp)
-add_library(quickstep_types_TypeFactory ../empty_src.cpp TypeFactory.hpp)
-add_library(quickstep_types_TypeFactoryLite TypeFactoryLite.cpp TypeFactoryLite.hpp)
+add_library(quickstep_types_TypeFactory TypeFactory.cpp TypeFactory.hpp)
+add_library(quickstep_types_TypeFactory-decl ../empty_src.cpp TypeFactory-decl.hpp)
 add_library(quickstep_types_TypeID TypeID.cpp TypeID.hpp)
 add_library(quickstep_types_TypeIDSelectors ../empty_src.cpp TypeIDSelectors.hpp)
 add_library(quickstep_types_TypeRegistrar ../empty_src.cpp TypeRegistrar.hpp)
@@ -76,6 +76,7 @@ add_library(quickstep_types_YearMonthIntervalType YearMonthIntervalType.cpp Year
 target_link_libraries(quickstep_types_ArrayType
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeRegistrar
                       quickstep_types_TypeSynthesizer
                       quickstep_types_Type_proto
                       quickstep_utility_Macros)
@@ -175,10 +176,12 @@ target_link_libraries(quickstep_types_LongType
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_MetaType
-                      quickstep_types_MetaTypeLite
-                      quickstep_types_TypeFactoryLite
+                      quickstep_types_MetaType-decl
+                      quickstep_types_TypeFactory-decl
+                      quickstep_types_TypeID
+                      quickstep_types_TypedValue
                       quickstep_types_Type_proto)
-target_link_libraries(quickstep_types_MetaTypeLite
+target_link_libraries(quickstep_types_MetaType-decl
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeSynthesizer
@@ -204,7 +207,6 @@ target_link_libraries(quickstep_types_NumericTypeSafeCoercibility
 target_link_libraries(quickstep_types_NumericTypeUnifier
                       quickstep_types_NumericTypeSafeCoercibility)
 target_link_libraries(quickstep_types_TextType
-                      quickstep_types_TextType
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeSynthesizer
@@ -214,19 +216,24 @@ target_link_libraries(quickstep_types_Type
                       glog
                       quickstep_types_Type_proto
                       quickstep_types_TypeID
+                      quickstep_types_TypeRegistrar
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_TypeFactoryLite
-                      glog
+target_link_libraries(quickstep_types_TypeFactory
                       quickstep_types_GenericValue
+                      quickstep_types_MetaType
                       quickstep_types_Type
+                      quickstep_types_TypeFactory-decl
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypeUtil
                       quickstep_types_Type_proto
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_TypeFactory
-                      quickstep_types_MetaType
-                      quickstep_types_TypeFactoryLite)
+target_link_libraries(quickstep_types_TypeFactory-decl
+                      glog
+                      quickstep_types_GenericValue
+                      quickstep_types_TypeID
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_types_TypeID
                       quickstep_types_Type_proto
                       quickstep_utility_Macros)
@@ -237,7 +244,6 @@ target_link_libraries(quickstep_types_TypeRegistrar
                       quickstep_types_DatetimeLit
                       quickstep_types_IntervalLit
                       quickstep_types_NullLit
-                      quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeIDSelectors
                       quickstep_utility_meta_Common)
@@ -250,7 +256,6 @@ target_link_libraries(quickstep_types_TypeSynthesizer
                       quickstep_types_Type_proto
                       quickstep_utility_HashPair
                       quickstep_utility_Macros
-                      quickstep_utility_PtrMap
                       quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_TypeUtil
                       quickstep_types_ArrayType
@@ -263,7 +268,7 @@ target_link_libraries(quickstep_types_TypeUtil
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
-                      quickstep_types_MetaTypeLite
+                      quickstep_types_MetaType-decl
                       quickstep_types_NullType
                       quickstep_types_TextType
                       quickstep_types_Type
@@ -329,7 +334,7 @@ target_link_libraries(quickstep_types
                       quickstep_types_IntervalParser
                       quickstep_types_LongType
                       quickstep_types_MetaType
-                      quickstep_types_MetaTypeLite
+                      quickstep_types_MetaType-decl
                       quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_NullLit
                       quickstep_types_NullType
@@ -342,7 +347,7 @@ target_link_libraries(quickstep_types
                       quickstep_types_Type_proto
                       quickstep_types_TypeErrors
                       quickstep_types_TypeFactory
-                      quickstep_types_TypeFactoryLite
+                      quickstep_types_TypeFactory-decl
                       quickstep_types_TypeID
                       quickstep_types_TypeIDSelectors
                       quickstep_types_TypeRegistrar

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/MetaType-decl.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType-decl.hpp b/types/MetaType-decl.hpp
new file mode 100644
index 0000000..6942338
--- /dev/null
+++ b/types/MetaType-decl.hpp
@@ -0,0 +1,76 @@
+/**
+ * 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_META_TYPE_DECL_HPP_
+#define QUICKSTEP_TYPES_META_TYPE_DECL_HPP_
+
+#include <cstddef>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class TypedValue;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class MetaType : public TypeSynthesizer<kMetaType> {
+ public:
+  int getPrintWidth() const override {
+    return 16;
+  }
+
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override;
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override;
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override;
+
+  std::string printValueToString(const UntypedLiteral *value) const override;
+
+  bool parseTypedValueFromString(const std::string &value_string,
+                                 TypedValue *value) const override {
+    return false;
+  }
+
+ private:
+  MetaType(const bool nullable)
+      : TypeSynthesizer<kMetaType>(nullable, sizeof(TypeID), 0x100) {
+    // TODO(refactor-type): Possibly infinite maximum size.
+  }
+
+  QUICKSTEP_SYNTHESIZE_TYPE(MetaType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_META_TYPE_DECL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/MetaType.cpp
----------------------------------------------------------------------
diff --git a/types/MetaType.cpp b/types/MetaType.cpp
index f6e44ba..16a86c2 100644
--- a/types/MetaType.cpp
+++ b/types/MetaType.cpp
@@ -23,7 +23,9 @@
 #include <string>
 
 #include "types/Type.pb.h"
-#include "types/TypeFactoryLite.hpp"
+#include "types/TypeFactory-decl.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
 
 namespace quickstep {
 
@@ -36,6 +38,15 @@ bool MetaType::checkValuesEqual(const UntypedLiteral *lhs,
   return castValueToLiteral(lhs)->equals(*castValueToLiteral(rhs));
 }
 
+TypedValue MetaType::marshallValue(const UntypedLiteral *value) const {
+  const Type *type = castValueToLiteral(value);
+  serialization::Type proto = type->getProto();
+  const std::size_t data_size = proto.ByteSize();
+  void *data = std::malloc(data_size);
+  proto.SerializeToArray(data, data_size);
+  return TypedValue::CreateWithOwnedData(kMetaType, data, data_size);
+}
+
 UntypedLiteral* MetaType::unmarshallValue(const void *data,
                                           const std::size_t data_size) const {
   serialization::Type proto;
@@ -43,4 +54,10 @@ UntypedLiteral* MetaType::unmarshallValue(const void *data,
   return new MetaTypeLiteral(&TypeFactory::ReconstructFromProto(proto));
 }
 
+std::string MetaType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
+
+  return castValueToLiteral(value)->getName();
+}
+
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/MetaType.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType.hpp b/types/MetaType.hpp
index 6edd270..7ccf9f5 100644
--- a/types/MetaType.hpp
+++ b/types/MetaType.hpp
@@ -20,6 +20,6 @@
 #ifndef QUICKSTEP_TYPES_META_TYPE_HPP_
 #define QUICKSTEP_TYPES_META_TYPE_HPP_
 
-#include "types/MetaTypeLite.hpp"
+#include "types/MetaType-decl.hpp"
 
 #endif  // QUICKSTEP_TYPES_META_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/MetaTypeLite.cpp
----------------------------------------------------------------------
diff --git a/types/MetaTypeLite.cpp b/types/MetaTypeLite.cpp
deleted file mode 100644
index 830f364..0000000
--- a/types/MetaTypeLite.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/MetaTypeLite.hpp"
-
-#include <cstddef>
-#include <string>
-
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-TypedValue MetaType::marshallValue(const UntypedLiteral *value) const {
-  const Type *type = castValueToLiteral(value);
-  serialization::Type proto = type->getProto();
-  const std::size_t data_size = proto.ByteSize();
-  void *data = std::malloc(data_size);
-  proto.SerializeToArray(data, data_size);
-  return TypedValue::CreateWithOwnedData(kMetaType, data, data_size);
-}
-
-std::string MetaType::printValueToString(const UntypedLiteral *value) const {
-  DCHECK(value != nullptr);
-
-  return castValueToLiteral(value)->getName();
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/MetaTypeLite.hpp
----------------------------------------------------------------------
diff --git a/types/MetaTypeLite.hpp b/types/MetaTypeLite.hpp
deleted file mode 100644
index 09f879f..0000000
--- a/types/MetaTypeLite.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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_META_TYPE_LITE_HPP_
-#define QUICKSTEP_TYPES_META_TYPE_LITE_HPP_
-
-#include <cstddef>
-#include <string>
-
-#include "types/Type.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypeSynthesizer.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-class TypedValue;
-
-/** \addtogroup Types
- *  @{
- */
-
-class MetaType : public TypeSynthesizer<kMetaType> {
- public:
-  int getPrintWidth() const override {
-    return 16;
-  }
-
-  bool checkValuesEqual(const UntypedLiteral *lhs,
-                        const UntypedLiteral *rhs,
-                        const Type &rhs_type) const override;
-
-  TypedValue marshallValue(const UntypedLiteral *value) const override;
-
-  UntypedLiteral* unmarshallValue(const void *data,
-                                  const std::size_t length) const override;
-
-  std::string printValueToString(const UntypedLiteral *value) const override;
-
-  bool parseTypedValueFromString(const std::string &value_string,
-                                 TypedValue *value) const override {
-    return false;
-  }
-
- private:
-  MetaType(const bool nullable)
-      : TypeSynthesizer<kMetaType>(nullable, sizeof(TypeID), 0x100) {
-    // TODO(refactor-type): Possibly infinite maximum size.
-  }
-
-  QUICKSTEP_SYNTHESIZE_TYPE(MetaType);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_META_TYPE_LITE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/TypeFactory-decl.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory-decl.hpp b/types/TypeFactory-decl.hpp
new file mode 100644
index 0000000..6edc05b
--- /dev/null
+++ b/types/TypeFactory-decl.hpp
@@ -0,0 +1,141 @@
+/**
+ * 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_FACTORY_DECL_HPP_
+#define QUICKSTEP_TYPES_TYPE_FACTORY_DECL_HPP_
+
+#include <cstddef>
+
+#include "types/GenericValue.hpp"
+#include "types/TypeID.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+class Type;
+
+namespace serialization { class Type; }
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief All-static factory object that provides access to Types, as well as
+ *        methods for determining coercibility of Types.
+ **/
+class TypeFactory {
+ public:
+  /**
+   * @brief Determine if a length parameter is required when getting a Type of
+   *        the specified TypeID.
+   *
+   * @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);
+
+  /**
+   * @brief Factory method to get a Type by its TypeID.
+   * @note This version is for Types without a length parameter (currently
+   *       IntType, LongType, FloatType, and DoubleType). It is an error to
+   *       call this with a Type which requires a length parameter.
+   *
+   * @param id The id of the desired Type.
+   * @param nullable Whether to get the nullable version of the Type.
+   * @return The Type corresponding to id.
+   **/
+  static const Type& GetType(const TypeID id, const bool nullable = false);
+
+  /**
+   * @brief Factory method to get a Type by its TypeID and length.
+   * @note This version is for Types with a length parameter (currently
+   *       CharType and VarCharType). It is an error to call this with a Type
+   *       which does not require a length parameter.
+   *
+   * @param id The id of the desired Type.
+   * @param length The length parameter of the desired Type.
+   * @param nullable Whether to get the nullable version of the Type.
+   * @return The Type corresponding to id and length.
+   **/
+  static const Type& GetType(const TypeID id,
+                             const std::size_t length,
+                             const bool nullable = false);
+
+  static const Type& GetType(const TypeID id,
+                             const std::vector<GenericValue> &parameters,
+                             const bool nullable = false);
+
+  /**
+   * @brief Get a reference to a Type from that Type's serialized Protocol Buffer
+   *        representation.
+   *
+   * @param proto A serialized Protocol Buffer representation of a Type,
+   *        originally generated by getProto().
+   * @return The Type described by proto.
+   **/
+  static const Type& ReconstructFromProto(const serialization::Type &proto);
+
+  static GenericValue ReconstructValueFromProto(const serialization::GenericValue &proto);
+
+  /**
+   * @brief Check whether a serialization::Type is fully-formed and
+   *        all parts are valid.
+   *
+   * @param proto A serialized Protocol Buffer representation of a Type,
+   *        originally generated by getProto().
+   * @return Whether proto is fully-formed and valid.
+   **/
+  static bool ProtoIsValid(const serialization::Type &proto);
+
+  /**
+   * @brief Determine which of two types is most specific, i.e. which
+   *        isSafelyCoercibleFrom() the other.
+   *
+   * @param first The first type to check.
+   * @param second The second type to check.
+   * @return The most precise type, or NULL if neither Type
+   *         isSafelyCoercibleFrom() the other.
+   **/
+  static const Type* GetMostSpecificType(const Type &first, const Type &second);
+
+  /**
+   * @brief Determine a type, if any exists, which both arguments can be safely
+   *        coerced to. It is possible that the resulting type may not be
+   *        either argument.
+   *
+   * @param first The first type to check.
+   * @param second The second type to check.
+   * @return The unifying type, or NULL if none exists.
+   **/
+  static const Type* GetUnifyingType(const Type &first, const Type &second);
+
+ private:
+  // Undefined default constructor. Class is all-static and should not be
+  // instantiated.
+  TypeFactory();
+
+  DISALLOW_COPY_AND_ASSIGN(TypeFactory);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_TYPE_FACTORY_DECL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index e69de29..45202f1 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -0,0 +1,171 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/TypeFactory.hpp"
+
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "types/GenericValue.hpp"
+#include "types/Type.hpp"
+#include "types/Type.pb.h"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+#include "types/TypeUtil.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
+  return TypeUtil::IsParameterizedPod(id);
+}
+
+const Type& TypeFactory::GetType(const TypeID id,
+                                 const bool nullable) {
+  DCHECK(TypeUtil::GetMemoryLayout(id) == kCxxInlinePod)
+      << "Called TypeFactory::GetType() with incorrect parameters.";
+
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxInlinePod>>(
+      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) {
+  DCHECK(TypeRequiresLengthParameter(id))
+      << "Called TypeFactory::GetType() with incorrect parameters.";
+
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kParInlinePod, kParOutOfLinePod>>(
+      id,
+      [&](auto id) -> const Type* {  // NOLINT(build/c++11)
+    return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, length);
+  });
+}
+
+const Type& TypeFactory::GetType(const TypeID id,
+                                 const std::vector<GenericValue> &parameters,
+                                 const bool nullable) {
+  DCHECK(TypeUtil::GetMemoryLayout(id) == kCxxGeneric)
+      << "Called TypeFactory::GetType() with incorrect parameters.";
+
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxGeneric>>(
+      id,
+      [&](auto id) -> const Type* {  // NOLINT(build/c++11)
+    return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, parameters);
+  });
+}
+
+bool TypeFactory::ProtoIsValid(const serialization::Type &proto) {
+  // Check that proto is fully initialized.
+  if (!proto.IsInitialized()) {
+    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) {
+  DCHECK(ProtoIsValid(proto))
+      << "Attempted to create Type from an invalid proto description:\n"
+      << proto.DebugString();
+
+  const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
+
+  switch (TypeUtil::GetMemoryLayout(type_id)) {
+    case kCxxInlinePod:
+      return GetType(type_id, proto.nullable());
+    case kParInlinePod:  // Fall through
+    case kParOutOfLinePod:
+      return GetType(type_id, proto.length(), proto.nullable());
+    case kCxxGeneric: {
+      std::vector<GenericValue> parameters;
+      for (int i = 0; i < proto.parameters_size(); ++i) {
+        parameters.emplace_back(ReconstructValueFromProto(proto.parameters(i)));
+      }
+      return GetType(type_id, parameters, proto.nullable());
+    }
+  }
+}
+
+GenericValue TypeFactory::ReconstructValueFromProto(
+    const serialization::GenericValue &proto) {
+  const Type &type = ReconstructFromProto(proto.type());
+  if (proto.has_data()) {
+    return GenericValue(type,
+                        type.unmarshallValue(proto.data().c_str(),
+                                             proto.data().size()),
+                        true /* take_ownership */);
+  } else {
+    return GenericValue(type);
+  }
+}
+
+const Type* TypeFactory::GetMostSpecificType(const Type &first, const Type &second) {
+  if (first.isSafelyCoercibleFrom(second)) {
+    return &first;
+  } else if (second.isSafelyCoercibleFrom(first)) {
+    return &second;
+  } else {
+    return nullptr;
+  }
+}
+
+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());
+    if (unifier == nullptr) {
+      if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
+            || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
+        unifier = &(DoubleType::Instance(true));
+      }
+    }
+  } else {
+    unifier = GetMostSpecificType(first, second);
+    if (unifier == nullptr) {
+      if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
+            || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
+        unifier = &(DoubleType::Instance(false));
+      }
+    }
+  }
+
+  return unifier;
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/TypeFactory.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.hpp b/types/TypeFactory.hpp
index 3992b6c..1b997f6 100644
--- a/types/TypeFactory.hpp
+++ b/types/TypeFactory.hpp
@@ -20,7 +20,6 @@
 #ifndef QUICKSTEP_TYPES_TYPE_FACTORY_HPP_
 #define QUICKSTEP_TYPES_TYPE_FACTORY_HPP_
 
-#include "types/MetaType.hpp"
-#include "types/TypeFactoryLite.hpp"
+#include "types/TypeFactory-decl.hpp"
 
 #endif  // QUICKSTEP_TYPES_TYPE_FACTORY_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/TypeFactoryLite.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactoryLite.cpp b/types/TypeFactoryLite.cpp
deleted file mode 100644
index c7c6b3b..0000000
--- a/types/TypeFactoryLite.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/TypeFactoryLite.hpp"
-
-#include <cstddef>
-#include <string>
-#include <vector>
-
-#include "types/GenericValue.hpp"
-#include "types/Type.hpp"
-#include "types/Type.pb.h"
-#include "types/TypeID.hpp"
-#include "types/TypeUtil.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
-  return TypeUtil::IsParameterizedPod(id);
-}
-
-const Type& TypeFactory::GetType(const TypeID id,
-                                 const bool nullable) {
-  DCHECK(TypeUtil::GetMemoryLayout(id) == kCxxInlinePod)
-      << "Called TypeFactory::GetType() with incorrect parameters.";
-
-  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxInlinePod>>(
-      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) {
-  DCHECK(TypeRequiresLengthParameter(id))
-      << "Called TypeFactory::GetType() with incorrect parameters.";
-
-  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kParInlinePod, kParOutOfLinePod>>(
-      id,
-      [&](auto id) -> const Type* {  // NOLINT(build/c++11)
-    return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, length);
-  });
-}
-
-const Type& TypeFactory::GetType(const TypeID id,
-                                 const std::vector<GenericValue> &parameters,
-                                 const bool nullable) {
-  DCHECK(TypeUtil::GetMemoryLayout(id) == kCxxGeneric)
-      << "Called TypeFactory::GetType() with incorrect parameters.";
-
-  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxGeneric>>(
-      id,
-      [&](auto id) -> const Type* {  // NOLINT(build/c++11)
-    return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, parameters);
-  });
-}
-
-bool TypeFactory::ProtoIsValid(const serialization::Type &proto) {
-  // Check that proto is fully initialized.
-  if (!proto.IsInitialized()) {
-    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) {
-  DCHECK(ProtoIsValid(proto))
-      << "Attempted to create Type from an invalid proto description:\n"
-      << proto.DebugString();
-
-  const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
-
-  switch (TypeUtil::GetMemoryLayout(type_id)) {
-    case kCxxInlinePod:
-      return GetType(type_id, proto.nullable());
-    case kParInlinePod:  // Fall through
-    case kParOutOfLinePod:
-      return GetType(type_id, proto.length(), proto.nullable());
-    case kCxxGeneric: {
-      std::vector<GenericValue> parameters;
-      for (int i = 0; i < proto.parameters_size(); ++i) {
-        parameters.emplace_back(ReconstructValueFromProto(proto.parameters(i)));
-      }
-      return GetType(type_id, parameters, proto.nullable());
-    }
-  }
-}
-
-GenericValue TypeFactory::ReconstructValueFromProto(
-    const serialization::GenericValue &proto) {
-  const Type &type = ReconstructFromProto(proto.type());
-  if (proto.has_data()) {
-    return GenericValue(type,
-                        type.unmarshallValue(proto.data().c_str(),
-                                             proto.data().size()),
-                        true /* take_ownership */);
-  } else {
-    return GenericValue(type);
-  }
-}
-
-const Type* TypeFactory::GetMostSpecificType(const Type &first, const Type &second) {
-  if (first.isSafelyCoercibleFrom(second)) {
-    return &first;
-  } else if (second.isSafelyCoercibleFrom(first)) {
-    return &second;
-  } else {
-    return nullptr;
-  }
-}
-
-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());
-    if (unifier == nullptr) {
-      if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
-            || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
-        unifier = &(DoubleType::Instance(true));
-      }
-    }
-  } else {
-    unifier = GetMostSpecificType(first, second);
-    if (unifier == nullptr) {
-      if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
-            || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
-        unifier = &(DoubleType::Instance(false));
-      }
-    }
-  }
-
-  return unifier;
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/TypeFactoryLite.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactoryLite.hpp b/types/TypeFactoryLite.hpp
deleted file mode 100644
index eeafbf2..0000000
--- a/types/TypeFactoryLite.hpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * 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_FACTORY_LITE_HPP_
-#define QUICKSTEP_TYPES_TYPE_FACTORY_LITE_HPP_
-
-#include <cstddef>
-
-#include "types/GenericValue.hpp"
-#include "types/TypeID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-
-namespace serialization { class Type; }
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief All-static factory object that provides access to Types, as well as
- *        methods for determining coercibility of Types.
- **/
-class TypeFactory {
- public:
-  /**
-   * @brief Determine if a length parameter is required when getting a Type of
-   *        the specified TypeID.
-   *
-   * @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);
-
-  /**
-   * @brief Factory method to get a Type by its TypeID.
-   * @note This version is for Types without a length parameter (currently
-   *       IntType, LongType, FloatType, and DoubleType). It is an error to
-   *       call this with a Type which requires a length parameter.
-   *
-   * @param id The id of the desired Type.
-   * @param nullable Whether to get the nullable version of the Type.
-   * @return The Type corresponding to id.
-   **/
-  static const Type& GetType(const TypeID id, const bool nullable = false);
-
-  /**
-   * @brief Factory method to get a Type by its TypeID and length.
-   * @note This version is for Types with a length parameter (currently
-   *       CharType and VarCharType). It is an error to call this with a Type
-   *       which does not require a length parameter.
-   *
-   * @param id The id of the desired Type.
-   * @param length The length parameter of the desired Type.
-   * @param nullable Whether to get the nullable version of the Type.
-   * @return The Type corresponding to id and length.
-   **/
-  static const Type& GetType(const TypeID id,
-                             const std::size_t length,
-                             const bool nullable = false);
-
-  static const Type& GetType(const TypeID id,
-                             const std::vector<GenericValue> &parameters,
-                             const bool nullable = false);
-
-  /**
-   * @brief Get a reference to a Type from that Type's serialized Protocol Buffer
-   *        representation.
-   *
-   * @param proto A serialized Protocol Buffer representation of a Type,
-   *        originally generated by getProto().
-   * @return The Type described by proto.
-   **/
-  static const Type& ReconstructFromProto(const serialization::Type &proto);
-
-  static GenericValue ReconstructValueFromProto(const serialization::GenericValue &proto);
-
-  /**
-   * @brief Check whether a serialization::Type is fully-formed and
-   *        all parts are valid.
-   *
-   * @param proto A serialized Protocol Buffer representation of a Type,
-   *        originally generated by getProto().
-   * @return Whether proto is fully-formed and valid.
-   **/
-  static bool ProtoIsValid(const serialization::Type &proto);
-
-  /**
-   * @brief Determine which of two types is most specific, i.e. which
-   *        isSafelyCoercibleFrom() the other.
-   *
-   * @param first The first type to check.
-   * @param second The second type to check.
-   * @return The most precise type, or NULL if neither Type
-   *         isSafelyCoercibleFrom() the other.
-   **/
-  static const Type* GetMostSpecificType(const Type &first, const Type &second);
-
-  /**
-   * @brief Determine a type, if any exists, which both arguments can be safely
-   *        coerced to. It is possible that the resulting type may not be
-   *        either argument.
-   *
-   * @param first The first type to check.
-   * @param second The second type to check.
-   * @return The unifying type, or NULL if none exists.
-   **/
-  static const Type* GetUnifyingType(const Type &first, const Type &second);
-
- private:
-  // Undefined default constructor. Class is all-static and should not be
-  // instantiated.
-  TypeFactory();
-
-  DISALLOW_COPY_AND_ASSIGN(TypeFactory);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_TYPE_FACTORY_LITE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/TypeIDSelectors.hpp
----------------------------------------------------------------------
diff --git a/types/TypeIDSelectors.hpp b/types/TypeIDSelectors.hpp
index 6e4a2b0..bb1cf80 100644
--- a/types/TypeIDSelectors.hpp
+++ b/types/TypeIDSelectors.hpp
@@ -23,7 +23,6 @@
 #include <type_traits>
 
 #include "types/TypeID.hpp"
-#include "types/TypeRegistrar.hpp"
 #include "utility/meta/Common.hpp"
 
 #include "glog/logging.h"
@@ -139,36 +138,6 @@ struct TypeIDSelectorMemoryLayout<candidates...>::Implementation<
   }
 };
 
-//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>::kIsParPod
-//                         ^ require_non_parameterized>> {
-//  inline static auto Invoke(const FunctorT &functor) {
-//    return functor(TypeIDConstant());
-//  }
-//};
-//
-//}  // namespace internal
-
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
index 52fe9ae..ca88456 100644
--- a/types/TypeUtil.hpp
+++ b/types/TypeUtil.hpp
@@ -32,7 +32,7 @@
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
-#include "types/MetaTypeLite.hpp"
+#include "types/MetaType-decl.hpp"
 #include "types/NullType.hpp"
 #include "types/TextType.hpp"
 #include "types/Type.hpp"


[14/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 769187b..df4462f 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -32,6 +32,8 @@ QS_PROTOBUF_GENERATE_CPP(types_TypedValue_proto_srcs types_TypedValue_proto_hdrs
 QS_PROTOBUF_GENERATE_CPP(types_Type_proto_srcs types_Type_proto_hdrs Type.proto)
 
 # Declare micro-libs:
+add_library(quickstep_types_AsciiStringSuperType ../empty_src.cpp AsciiStringSuperType.hpp)
+add_library(quickstep_types_BoolType BoolType.cpp BoolType.hpp)
 add_library(quickstep_types_CharType CharType.cpp CharType.hpp)
 add_library(quickstep_types_DateOperatorOverloads ../empty_src.cpp DateOperatorOverloads.hpp)
 add_library(quickstep_types_DateType DateType.cpp DateType.hpp)
@@ -47,11 +49,16 @@ add_library(quickstep_types_LongType LongType.cpp LongType.hpp)
 add_library(quickstep_types_NullCoercibilityCheckMacro ../empty_src.cpp NullCoercibilityCheckMacro.hpp)
 add_library(quickstep_types_NullType ../empty_src.cpp NullType.hpp)
 add_library(quickstep_types_NumericSuperType ../empty_src.cpp NumericSuperType.hpp)
+add_library(quickstep_types_NumericTypeSafeCoercibility ../empty_src.cpp NumericTypeSafeCoercibility.hpp)
 add_library(quickstep_types_NumericTypeUnifier ../empty_src.cpp NumericTypeUnifier.hpp)
 add_library(quickstep_types_Type Type.cpp Type.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_TypeIDSelectors ../empty_src.cpp TypeIDSelectors.hpp)
+add_library(quickstep_types_TypeRegistrar ../empty_src.cpp TypeRegistrar.hpp)
+add_library(quickstep_types_TypeSynthesizer ../empty_src.cpp TypeSynthesizer.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})
@@ -59,8 +66,20 @@ add_library(quickstep_types_VarCharType VarCharType.cpp VarCharType.hpp)
 add_library(quickstep_types_YearMonthIntervalType YearMonthIntervalType.cpp YearMonthIntervalType.hpp)
 
 # Link dependencies:
+target_link_libraries(quickstep_types_AsciiStringSuperType
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer)
+target_link_libraries(quickstep_types_BoolType
+                      glog
+                      quickstep_types_NumericSuperType
+                      quickstep_types_TypeID
+                      quickstep_types_TypedValue
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_CharType
                       glog
+                      quickstep_types_AsciiStringSuperType
                       quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
@@ -77,9 +96,9 @@ target_link_libraries(quickstep_types_DateOperatorOverloads
 target_link_libraries(quickstep_types_DateType
                       glog
                       quickstep_types_DatetimeLit
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_utility_CheckSnprintf
                       quickstep_utility_Macros)
@@ -87,9 +106,9 @@ target_link_libraries(quickstep_types_DatetimeIntervalType
                       glog
                       quickstep_types_IntervalLit
                       quickstep_types_IntervalParser
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_utility_CheckSnprintf
                       quickstep_utility_Macros)
@@ -98,35 +117,27 @@ target_link_libraries(quickstep_types_DatetimeLit
 target_link_libraries(quickstep_types_DatetimeType
                       glog
                       quickstep_types_DatetimeLit
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_types_port_gmtime_r
                       quickstep_types_port_timegm
                       quickstep_utility_CheckSnprintf
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_DoubleType
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_NumericSuperType
-                      quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_FloatType
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_NumericSuperType
-                      quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_IntType
                       glog
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_NumericSuperType
-                      quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
@@ -138,27 +149,30 @@ target_link_libraries(quickstep_types_IntervalParser
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_LongType
                       glog
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_NumericSuperType
-                      quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_NullCoercibilityCheckMacro
-                      quickstep_types_Type
-                      quickstep_types_TypeID)
 target_link_libraries(quickstep_types_NullType
                       glog
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_NumericSuperType
                       quickstep_types_NullCoercibilityCheckMacro
+                      quickstep_types_NumericTypeSafeCoercibility
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_TMP)
+target_link_libraries(quickstep_types_NumericTypeSafeCoercibility
+                      quickstep_utility_meta_TMP)
+target_link_libraries(quickstep_types_NumericTypeUnifier
+                      quickstep_types_NumericTypeSafeCoercibility)
 target_link_libraries(quickstep_types_Type
                       glog
                       quickstep_types_Type_proto
@@ -167,6 +181,33 @@ target_link_libraries(quickstep_types_Type
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_TypeFactory
                       glog
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeUtil
+                      quickstep_types_Type_proto
+                      quickstep_utility_Macros)
+target_link_libraries(quickstep_types_TypeID
+                      quickstep_types_Type_proto
+                      quickstep_utility_Macros)
+target_link_libraries(quickstep_types_TypeIDSelectors
+                      quickstep_types_TypeID
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_TypeRegistrar
+                      quickstep_types_DatetimeLit
+                      quickstep_types_IntervalLit
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeIDSelectors
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_TypeSynthesizer
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_Type_proto
+                      quickstep_utility_Macros
+                      quickstep_utility_PtrMap)
+target_link_libraries(quickstep_types_TypeUtil
+                      quickstep_types_BoolType
                       quickstep_types_CharType
                       quickstep_types_DateType
                       quickstep_types_DatetimeIntervalType
@@ -178,7 +219,7 @@ target_link_libraries(quickstep_types_TypeFactory
                       quickstep_types_NullType
                       quickstep_types_Type
                       quickstep_types_TypeID
-                      quickstep_types_Type_proto
+                      quickstep_types_TypeRegistrar
                       quickstep_types_VarCharType
                       quickstep_types_YearMonthIntervalType
                       quickstep_utility_Macros)
@@ -200,6 +241,7 @@ target_link_libraries(quickstep_types_Type_proto
                       ${PROTOBUF_LIBRARY})
 target_link_libraries(quickstep_types_VarCharType
                       glog
+                      quickstep_types_AsciiStringSuperType
                       quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
@@ -211,9 +253,9 @@ target_link_libraries(quickstep_types_VarCharType
 target_link_libraries(quickstep_types_YearMonthIntervalType
                       quickstep_types_IntervalLit
                       quickstep_types_IntervalParser
-                      quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_utility_CheckSnprintf
                       quickstep_utility_Macros)
@@ -221,6 +263,8 @@ target_link_libraries(quickstep_types_YearMonthIntervalType
 # Module all-in-one library:
 add_library(quickstep_types ../empty_src.cpp TypesModule.hpp)
 target_link_libraries(quickstep_types
+                      quickstep_types_AsciiStringSuperType
+                      quickstep_types_BoolType
                       quickstep_types_CharType
                       quickstep_types_DateOperatorOverloads
                       quickstep_types_DateType
@@ -236,12 +280,17 @@ target_link_libraries(quickstep_types
                       quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_NullType
                       quickstep_types_NumericSuperType
+                      quickstep_types_NumericTypeSafeCoercibility
                       quickstep_types_NumericTypeUnifier
                       quickstep_types_Type
+                      quickstep_types_TypeUtil
                       quickstep_types_Type_proto
                       quickstep_types_TypeErrors
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
+                      quickstep_types_TypeIDSelectors
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_types_TypedValue_proto
                       quickstep_types_VarCharType

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/CharType.cpp
----------------------------------------------------------------------
diff --git a/types/CharType.cpp b/types/CharType.cpp
index 591c038..2ed469b 100644
--- a/types/CharType.cpp
+++ b/types/CharType.cpp
@@ -42,38 +42,6 @@ using std::string;
 
 namespace quickstep {
 
-template <bool nullable_internal>
-const CharType& CharType::InstanceInternal(const std::size_t length) {
-  static PtrMap<size_t, CharType> instance_map;
-  PtrMap<size_t, CharType>::iterator imit = instance_map.find(length);
-  if (imit == instance_map.end()) {
-    imit = instance_map.insert(length, new CharType(length, nullable_internal)).first;
-  }
-  return *(imit->second);
-}
-
-const CharType& CharType::InstanceNonNullable(const std::size_t length) {
-  return InstanceInternal<false>(length);
-}
-
-const CharType& CharType::InstanceNullable(const std::size_t length) {
-  return InstanceInternal<true>(length);
-}
-
-const CharType& CharType::InstanceFromProto(const serialization::Type &proto) {
-  return Instance(proto.GetExtension(serialization::CharType::length), proto.nullable());
-}
-
-serialization::Type CharType::getProto() const {
-  serialization::Type proto;
-  proto.set_type_id(serialization::Type::CHAR);
-
-  proto.set_nullable(nullable_);
-
-  proto.SetExtension(serialization::CharType::length, length_);
-  return proto;
-}
-
 bool CharType::isSafelyCoercibleFrom(const Type &original_type) const {
   QUICKSTEP_NULL_COERCIBILITY_CHECK();
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index c7321f4..c90a8da 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -24,8 +24,8 @@
 #include <cstdio>
 #include <string>
 
+#include "types/AsciiStringSuperType.hpp"
 #include "types/Type.hpp"
-#include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
@@ -43,75 +43,8 @@ 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> {
  public:
-  /**
-   * @brief Get a reference to the non-nullable singleton instance of this Type
-   *        for the specified length.
-   *
-   * @param length The length parameter of the CharType.
-   * @return A reference to the non-nullable singleton instance of this Type
-   *         for the specified length.
-   **/
-  static const CharType& InstanceNonNullable(const std::size_t length);
-
-  /**
-   * @brief Get a reference to the nullable singleton instance of this Type for
-   *        the specified length.
-   *
-   * @param length The length parameter of the CharType.
-   * @return A reference to the nullable singleton instance of this Type for
-   *         the specified length.
-   **/
-  static const CharType& InstanceNullable(const std::size_t length);
-
-  /**
-   * @brief Get a reference to the singleton instance of this Type for the
-   *        specified length and nullability.
-   *
-   * @param length The length parameter of the CharType.
-   * @param nullable Whether to get the nullable version of this Type.
-   * @return A reference to the singleton instance of this Type for the
-   *         specified length.
-   **/
-  static const CharType& Instance(const std::size_t length, const bool nullable) {
-    if (nullable) {
-      return InstanceNullable(length);
-    } else {
-      return InstanceNonNullable(length);
-    }
-  }
-
-  /**
-   * @brief Get a reference to the singleton instance of this Type described
-   *        by the given Protocol Buffer serialization.
-   *
-   * @param proto The serialized Protocol Buffer representation of the desired
-   *        CharType.
-   * @return A reference to the singleton instance of this Type for the given
-   *         Protocol Buffer.
-   **/
-  static const CharType& InstanceFromProto(const serialization::Type &proto);
-
-  /**
-   * @brief Generate a serialized Protocol Buffer representation of this Type.
-   *
-   * @return The serialized Protocol Buffer representation of this Type.
-   **/
-  serialization::Type getProto() const override;
-
-  const Type& getNullableVersion() const override {
-    return InstanceNullable(length_);
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable(length_);
-  }
-
-  std::size_t estimateAverageByteLength() const override {
-    return length_;
-  }
-
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
   std::string getName() const override;
@@ -134,11 +67,9 @@ class CharType : public AsciiStringSuperType {
 
  private:
   CharType(const std::size_t length, const bool nullable)
-      : AsciiStringSuperType(kChar, nullable, length, length, length) {
-  }
+      : AsciiStringSuperType<kChar>(nullable, length, length, length) {}
 
-  template <bool nullable_internal>
-  static const CharType& InstanceInternal(const std::size_t length);
+  template <typename, bool> friend class TypeInstance;
 
   DISALLOW_COPY_AND_ASSIGN(CharType);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/DateType.cpp
----------------------------------------------------------------------
diff --git a/types/DateType.cpp b/types/DateType.cpp
index 5bb982c..de1e554 100644
--- a/types/DateType.cpp
+++ b/types/DateType.cpp
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "types/DatetimeLit.hpp"
-#include "types/NullCoercibilityCheckMacro.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
@@ -46,16 +45,6 @@ using std::snprintf;
 
 namespace quickstep {
 
-bool DateType::isCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kDate);
-}
-
-bool DateType::isSafelyCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kDate);
-}
-
 std::string DateType::printValueToString(const TypedValue &value) const {
   DCHECK(!value.isNull());
 
@@ -86,14 +75,6 @@ std::string DateType::printValueToString(const TypedValue &value) const {
   return std::string(datebuf);
 }
 
-void DateType::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 DateType::parseValueFromString(const std::string &value_string,
                                     TypedValue *value) const {
   std::int32_t year;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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_


[22/38] incubator-quickstep git commit: Updates for adding generic types

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
index ffe2b7e..9e6c50b 100644
--- a/types/TypeRegistrar.hpp
+++ b/types/TypeRegistrar.hpp
@@ -20,13 +20,14 @@
 #ifndef QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
 #define QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
 
+#include <cstddef>
 #include <cstdint>
 #include <type_traits>
+#include <vector>
 
 #include "types/DatetimeLit.hpp"
 #include "types/IntervalLit.hpp"
 #include "types/NullLit.hpp"
-#include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypeIDSelectors.hpp"
 #include "utility/meta/Common.hpp"
@@ -39,6 +40,14 @@ namespace quickstep {
  *  @{
  */
 
+class Type;
+class TypedValue;
+
+using UntypedLiteral = void;
+
+using ArrayLiteral = std::vector<UntypedLiteral*>;
+using MetaTypeLiteral = const Type*;
+
 template <TypeID type_id>
 struct TypeIDTrait;
 
@@ -48,36 +57,40 @@ struct TypeIDTrait;
     typedef type_class TypeClass; \
     typedef cpp_type cpptype; \
     static constexpr TypeID kStaticTypeID = type_id; \
-    static constexpr Type::SuperTypeID kStaticSuperTypeID = super_type_id; \
+    static constexpr SuperTypeID kStaticSuperTypeID = super_type_id; \
     static constexpr MemoryLayout kMemoryLayout = memory_layout; \
-    static constexpr bool kIsParameterizedPod = \
-        (memory_layout == kParNativePod || memory_layout == kParIndirectPod); \
+    static constexpr bool kIsParPod = \
+        (memory_layout == kParInlinePod || memory_layout == kParOutOfLinePod); \
   };
 
-REGISTER_TYPE(BoolType, kBool, \
-              Type::kNumeric, kCxxNativePod, bool);
-REGISTER_TYPE(IntType, kInt, \
-              Type::kNumeric, kCxxNativePod, int);
-REGISTER_TYPE(LongType, kLong, \
-              Type::kNumeric, kCxxNativePod, std::int64_t);
-REGISTER_TYPE(FloatType, kFloat, \
-              Type::kNumeric, kCxxNativePod, float);
-REGISTER_TYPE(DoubleType, kDouble, \
-              Type::kNumeric, kCxxNativePod, double);
-REGISTER_TYPE(DateType, kDate, \
-              Type::kOther, kCxxNativePod, DateLit);
-REGISTER_TYPE(DatetimeType, kDatetime, \
-              Type::kOther, kCxxNativePod, DatetimeLit);
-REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval, \
-              Type::kOther, kCxxNativePod, DatetimeIntervalLit);
-REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval, \
-              Type::kOther, kCxxNativePod, YearMonthIntervalLit);
-REGISTER_TYPE(CharType, kChar, \
-              Type::kAsciiString, kParNativePod, void);
-REGISTER_TYPE(VarCharType, kVarChar, \
-              Type::kAsciiString, kParIndirectPod, void);
-REGISTER_TYPE(NullType, kNullType, \
-              Type::kOther, kCxxNativePod, NullLit);
+REGISTER_TYPE(BoolType, kBool,
+              SuperTypeID::kNumeric, kCxxInlinePod, bool);
+REGISTER_TYPE(IntType, kInt,
+              SuperTypeID::kNumeric, kCxxInlinePod, int);
+REGISTER_TYPE(LongType, kLong,
+              SuperTypeID::kNumeric, kCxxInlinePod, std::int64_t);
+REGISTER_TYPE(FloatType, kFloat,
+              SuperTypeID::kNumeric, kCxxInlinePod, float);
+REGISTER_TYPE(DoubleType, kDouble,
+              SuperTypeID::kNumeric, kCxxInlinePod, double);
+REGISTER_TYPE(DateType, kDate,
+              SuperTypeID::kOther, kCxxInlinePod, DateLit);
+REGISTER_TYPE(DatetimeType, kDatetime,
+              SuperTypeID::kOther, kCxxInlinePod, DatetimeLit);
+REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval,
+              SuperTypeID::kOther, kCxxInlinePod, DatetimeIntervalLit);
+REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval,
+              SuperTypeID::kOther, kCxxInlinePod, YearMonthIntervalLit);
+REGISTER_TYPE(CharType, kChar,
+              SuperTypeID::kAsciiString, kParInlinePod, TypedValue);
+REGISTER_TYPE(VarCharType, kVarChar,
+              SuperTypeID::kAsciiString, kParOutOfLinePod, TypedValue);
+REGISTER_TYPE(ArrayType, kArray,
+              SuperTypeID::kOther, kCxxGeneric, ArrayLiteral);
+REGISTER_TYPE(MetaType, kMetaType,
+              SuperTypeID::kOther, kCxxGeneric, MetaTypeLiteral);
+REGISTER_TYPE(NullType, kNullType,
+              SuperTypeID::kOther, kCxxInlinePod, NullLit);
 
 #undef REGISTER_TYPE
 
@@ -91,8 +104,8 @@ 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) {
+inline auto InvokeOnTypeIDInternal(const int value,
+                                   const FunctorT &functor) {
   DCHECK_LE(l, r);
   if (l == r) {
     constexpr TypeID type_id = static_cast<TypeID>(r);
@@ -101,9 +114,9 @@ inline auto InvokeOnTypeIDInner(const int value,
   }
   constexpr int m = (l + r) >> 1;
   if (value <= m) {
-    return InvokeOnTypeIDInner<l, m, Selector, FunctorT>(value, functor);
+    return InvokeOnTypeIDInternal<l, m, Selector, FunctorT>(value, functor);
   } else {
-    return InvokeOnTypeIDInner<m+1, r, Selector, FunctorT>(value, functor);
+    return InvokeOnTypeIDInternal<m+1, r, Selector, FunctorT>(value, functor);
   }
 }
 
@@ -112,8 +125,8 @@ inline auto InvokeOnTypeIDInner(const int value,
 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>(
+  return internal::InvokeOnTypeIDInternal<0, static_cast<int>(kNumTypeIDs)-1,
+                                          Selector, FunctorT>(
       static_cast<int>(type_id), functor);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index 16d59c9..7c39e47 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -21,14 +21,21 @@
 #define QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_
 
 #include <cstddef>
+#include <cstdio>
+#include <memory>
+#include <string>
 #include <type_traits>
+#include <unordered_map>
+#include <vector>
 
+#include "types/GenericValue.hpp"
 #include "types/Type.hpp"
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypeRegistrar.hpp"
+#include "types/TypedValue.hpp"
+#include "utility/HashPair.hpp"
 #include "utility/Macros.hpp"
-#include "utility/PtrMap.hpp"
 
 #include "glog/logging.h"
 
@@ -38,25 +45,26 @@ namespace quickstep {
  *  @{
  */
 
-template <typename TypeClass, bool parameterized>
-class TypeInstance;
+template <TypeID type_id, typename Enable = void>
+class TypeInstancePolicy;
 
 
 template <TypeID type_id>
 class TypeSynthesizer
     : public Type,
-      public TypeInstance<typename TypeIDTrait<type_id>::TypeClass,
-                          TypeIDTrait<type_id>::kIsParameterizedPod> {
- public:
+      public TypeInstancePolicy<type_id> {
+ private:
   using Trait = TypeIDTrait<type_id>;
-  using TypeClass = typename Trait::TypeClass;
+  using InstancePolicy = TypeInstancePolicy<type_id>;
 
-  static constexpr Type::SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
+ public:
+  static constexpr SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
   static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID;
-  static constexpr bool kIsParameterizedPod = Trait::kIsParameterizedPod;
+  static constexpr bool kIsParPod = Trait::kIsParPod;
   static constexpr MemoryLayout kMemoryLayout = Trait::kMemoryLayout;
 
-  typedef typename Trait::cpptype cpptype;
+  using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
 
   serialization::Type getProto() const override {
     serialization::Type proto;
@@ -64,72 +72,170 @@ class TypeSynthesizer
     proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
     proto.set_nullable(nullable_);
 
-    if (kIsParameterizedPod) {
-      proto.set_length(parameter_);
-    }
+    InstancePolicy::fillProto(&proto);
 
     return proto;
   }
 
   const Type& getNullableVersion() const override {
-    return getInstance<kIsParameterizedPod>(true);
+    return InstancePolicy::getInstance(true);
   }
 
   const Type& getNonNullableVersion() const override {
-    return getInstance<kIsParameterizedPod>(false);
+    return InstancePolicy::getInstance(false);
+  }
+
+  const cpptype& castValueToLiteral(const UntypedLiteral *value) const {
+    return *static_cast<const cpptype*>(value);
+  }
+
+  cpptype& castValueToLiteral(UntypedLiteral *value) const {
+    return *static_cast<cpptype*>(value);
+  }
+
+  UntypedLiteral* unmarshallValue(const TypedValue &value) const override {
+    return unmarshallInternal<kMemoryLayout>(value);
+  }
+
+  UntypedLiteral* unmarshallValue(TypedValue &&value) const override {
+    return unmarshallInternal<kMemoryLayout>(std::move(value));
+  }
+
+  std::string printTypedValueToString(const TypedValue &value) const override {
+    return invokeOnUnmarshalledValue<kMemoryLayout>(
+        value,
+        [&](const UntypedLiteral *value) -> std::string {
+      return this->printValueToString(value);
+    });
+  }
+
+  void printTypedValueToFile(const TypedValue &value,
+                             FILE *file,
+                             const int padding = 0) const override {
+    invokeOnUnmarshalledValue<kMemoryLayout>(
+        value,
+        [&](const UntypedLiteral *value) -> void {
+      this->printValueToFile(value, file, padding);
+    });
   }
 
  protected:
-  template <MemoryLayout layout = kMemoryLayout, bool par = kIsParameterizedPod>
+  template <MemoryLayout layout = kMemoryLayout>
   explicit TypeSynthesizer(const bool nullable,
-                           std::enable_if_t<layout == kCxxNativePod>* = 0)
+                           std::enable_if_t<layout == kCxxInlinePod>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
-             sizeof(cpptype), sizeof(cpptype)) {
+             sizeof(cpptype), sizeof(cpptype)),
+        TypeInstancePolicy<type_id>() {
   }
 
-  template <MemoryLayout layout = kMemoryLayout, bool par = kIsParameterizedPod>
+  template <MemoryLayout layout = kMemoryLayout>
   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<par>* = 0)
+                  std::enable_if_t<layout == kParInlinePod || layout == kParOutOfLinePod>* = 0)
+      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+             minimum_byte_length, maximum_byte_length),
+        TypeInstancePolicy<type_id>(parameter) {
+  }
+
+  template <MemoryLayout layout = kMemoryLayout>
+  TypeSynthesizer(const bool nullable,
+                  const std::size_t minimum_byte_length,
+                  const std::size_t maximum_byte_length,
+                  const std::vector<GenericValue> &parameters = {},
+                  std::enable_if_t<layout == kCxxGeneric>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
-             minimum_byte_length, maximum_byte_length, parameter) {
+             minimum_byte_length, maximum_byte_length),
+        TypeInstancePolicy<type_id>(parameters) {
   }
 
  private:
-  template <bool has_param>
-  inline const Type& getInstance(const bool nullable,
-                                 std::enable_if_t<has_param>* = 0) const {
-    return TypeInstance<TypeClass, kIsParameterizedPod>::Instance(parameter_, nullable);
+  template <MemoryLayout layout>
+  inline UntypedLiteral* unmarshallInternal(
+      const TypedValue &value,
+      std::enable_if_t<layout == kCxxInlinePod> * = 0) const {
+    return cloneValue(value.getDataPtr());
   }
 
-  template <bool has_param>
-  inline const Type& getInstance(const bool nullable,
-                                 std::enable_if_t<!has_param>* = 0) const {
-    return TypeInstance<TypeClass, kIsParameterizedPod>::Instance(nullable);
+  template <MemoryLayout layout>
+  inline UntypedLiteral* unmarshallInternal(
+      const TypedValue &value,
+      std::enable_if_t<layout == kParInlinePod ||
+                       layout == kParOutOfLinePod> * = 0) const {
+    return cloneValue(&value);
   }
 
-  friend class TypeInstance<TypeClass, kIsParameterizedPod>;
+  template <MemoryLayout layout>
+  inline UntypedLiteral* unmarshallInternal(
+      TypedValue &&value,
+      std::enable_if_t<layout == kParInlinePod ||
+                       layout == kParOutOfLinePod> * = 0) const {
+    return new TypedValue(std::move(value));
+  }
+
+  template <MemoryLayout layout>
+  inline UntypedLiteral* unmarshallInternal(
+      const TypedValue &value,
+      std::enable_if_t<layout == kCxxGeneric> * = 0) const {
+    return Type::unmarshallValue(value.getOutOfLineData(), value.getDataSize());
+  }
+
+
+  template <MemoryLayout layout, typename Functor>
+  inline auto invokeOnUnmarshalledValue(
+      const TypedValue &value,
+      const Functor &functor,
+      std::enable_if_t<layout == kCxxInlinePod> * = 0) const {
+    return functor(value.getDataPtr());
+  }
+
+  template <MemoryLayout layout, typename Functor>
+  inline auto invokeOnUnmarshalledValue(
+      const TypedValue &value,
+      const Functor &functor,
+      std::enable_if_t<layout == kParInlinePod ||
+                       layout == kParOutOfLinePod> * = 0) const {
+    return functor(&value);
+  }
+
+  template <MemoryLayout layout, typename Functor>
+  inline auto invokeOnUnmarshalledValue(
+      const TypedValue &value,
+      const Functor &functor,
+      std::enable_if_t<layout == kCxxGeneric> * = 0) const {
+    std::unique_ptr<cpptype> literal(
+        static_cast<cpptype*>(Type::unmarshallValue(value.getOutOfLineData(),
+                                                    value.getDataSize())));
+    return functor(literal.get());
+  }
+
+  template <TypeID, typename> friend class TypeInstancePolicy;
 
   DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
 
 template <TypeID type_id>
-constexpr Type::SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
+constexpr SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
 
 template <TypeID type_id>
 constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
 
 template <TypeID type_id>
-constexpr bool TypeSynthesizer<type_id>::kIsParameterizedPod;
+constexpr bool TypeSynthesizer<type_id>::kIsParPod;
 
 template <TypeID type_id>
 constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
 
 
-template <typename TypeClass>
-class TypeInstance<TypeClass, false> {
+template <TypeID type_id>
+class TypeInstancePolicy<
+    type_id,
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxInlinePod>> {
+ private:
+  using Trait = TypeIDTrait<type_id>;
+  using TypeClass = typename Trait::TypeClass;
+
  public:
   static const TypeClass& InstanceNonNullable() {
     return InstanceInternal<false>();
@@ -147,6 +253,15 @@ class TypeInstance<TypeClass, false> {
     }
   }
 
+ protected:
+  TypeInstancePolicy() {}
+
+  inline const Type& getInstance(const bool nullable) const {
+    return nullable ? InstanceNullable() : InstanceNonNullable();
+  }
+
+  inline void fillProto(serialization::Type *proto) const {}
+
  private:
   template <bool nullable>
   inline static const TypeClass& InstanceInternal() {
@@ -155,8 +270,15 @@ class TypeInstance<TypeClass, false> {
   }
 };
 
-template <typename TypeClass>
-class TypeInstance<TypeClass, true> {
+template <TypeID type_id>
+class TypeInstancePolicy<
+    type_id,
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod ||
+                     TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> {
+ private:
+  using Trait = TypeIDTrait<type_id>;
+  using TypeClass = typename Trait::TypeClass;
+
  public:
   static const TypeClass& InstanceNonNullable(const std::size_t length) {
     return InstanceInternal<false>(length);
@@ -174,18 +296,134 @@ class TypeInstance<TypeClass, true> {
     }
   }
 
+  inline std::size_t length() const {
+    return length_;
+  }
+
+ protected:
+  TypeInstancePolicy(const std::size_t length)
+      : length_(length) {}
+
+  const std::size_t length_;
+
+  inline const Type& getInstance(const bool nullable) const {
+    return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_);
+  }
+
+  inline void fillProto(serialization::Type *proto) const {
+    proto->set_length(length_);
+  }
+
  private:
   template <bool nullable>
   inline static const TypeClass& InstanceInternal(const std::size_t length) {
-    static PtrMap<size_t, TypeClass> instance_map;
+    static std::unordered_map<size_t, std::unique_ptr<TypeClass>> instance_map;
     auto imit = instance_map.find(length);
     if (imit == instance_map.end()) {
-      imit = instance_map.insert(length, new TypeClass(length, nullable)).first;
+      std::unique_ptr<TypeClass> instance(new TypeClass(nullable, length));
+      imit = instance_map.emplace(length, std::move(instance)).first;
+    }
+    return *(imit->second);
+  }
+};
+
+template <TypeID type_id>
+class TypeInstancePolicy<
+    type_id,
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kCxxGeneric>> {
+ private:
+  using Trait = TypeIDTrait<type_id>;
+  using TypeClass = typename Trait::TypeClass;
+
+ public:
+  static const TypeClass& InstanceNonNullable(
+      const std::vector<GenericValue> &parameters = {}) {
+    return InstanceInternal<false>(parameters);
+  }
+
+  static const TypeClass& InstanceNullable(
+      const std::vector<GenericValue> &parameters = {}) {
+    return InstanceInternal<true>(parameters);
+  }
+
+  static const TypeClass& Instance(
+      const bool nullable,
+      const std::vector<GenericValue> &parameters = {}) {
+    if (nullable) {
+      return InstanceNullable(parameters);
+    } else {
+      return InstanceNonNullable(parameters);
+    }
+  }
+
+  inline const std::vector<GenericValue>& parameters() const {
+    return parameters_;
+  }
+
+ protected:
+  TypeInstancePolicy(const std::vector<GenericValue> &parameters)
+      : parameters_(parameters) {}
+
+  const std::vector<GenericValue> parameters_;
+
+  inline const Type& getInstance(const bool nullable) const {
+    return nullable ? InstanceNullable(parameters_)
+                    : InstanceNonNullable(parameters_);
+  }
+
+  inline void fillProto(serialization::Type *proto) const {
+    LOG(FATAL) << "TODO";
+  }
+
+ private:
+  struct ParametersHasher {
+    inline std::size_t operator()(const std::vector<GenericValue> &parameters) const {
+      std::size_t hash_code = 0;
+      for (const GenericValue &value : parameters) {
+        hash_code = CombineHashes(hash_code, value.getHash());
+      }
+      return hash_code;
+    }
+  };
+
+  template <typename T>
+  inline static TypeClass* CreateInstance(
+      const bool nullable,
+      const std::vector<GenericValue> &parameters,
+      decltype(new T(nullable)) * = 0) {
+    DCHECK(parameters.empty());
+    return new T(nullable);
+  }
+
+  template <typename T>
+  inline static TypeClass* CreateInstance(
+      const bool nullable,
+      const std::vector<GenericValue> &parameters,
+      decltype(new T(nullable, parameters)) * = 0) {
+    return new T(nullable, parameters);
+  }
+
+  template <bool nullable>
+  inline static const TypeClass& InstanceInternal(
+      const std::vector<GenericValue> &parameters) {
+    static std::unordered_map<std::vector<GenericValue>,
+                              std::unique_ptr<TypeClass>,
+                              ParametersHasher> instance_map;
+    auto imit = instance_map.find(parameters);
+    if (imit == instance_map.end()) {
+      std::unique_ptr<TypeClass> instance(
+          TypeInstancePolicy<type_id>::template CreateInstance<TypeClass>(
+              nullable, parameters));
+      imit = instance_map.emplace(parameters, std::move(instance)).first;
     }
     return *(imit->second);
   }
 };
 
+#define QUICKSTEP_SYNTHESIZE_TYPE(type) \
+  template <TypeID, typename> friend class TypeInstancePolicy; \
+  DISALLOW_COPY_AND_ASSIGN(type)
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
index 5a55280..3b16c70 100644
--- a/types/TypeUtil.hpp
+++ b/types/TypeUtil.hpp
@@ -22,6 +22,7 @@
 
 #include <type_traits>
 
+#include "types/ArrayType.hpp"
 #include "types/BoolType.hpp"
 #include "types/CharType.hpp"
 #include "types/DateType.hpp"
@@ -31,6 +32,7 @@
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
+#include "types/MetaType.hpp"
 #include "types/NullType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
@@ -53,7 +55,7 @@ class TypeUtil {
     return InvokeOnTypeID(
         type_id,
         [&](auto tid) -> bool {  // NOLINT(build/c++11)
-      return TypeIDTrait<decltype(tid)::value>::kIsParameterizedPod;
+      return TypeIDTrait<decltype(tid)::value>::kIsParPod;
     });
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/TypedValue.hpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.hpp b/types/TypedValue.hpp
index 196e8ec..d0e8b98 100644
--- a/types/TypedValue.hpp
+++ b/types/TypedValue.hpp
@@ -506,6 +506,28 @@ class TypedValue {
     return value_union_.out_of_line_data;
   }
 
+  inline void* releaseOutOfLineData() {
+    DCHECK(!(getTypeID() == kBool
+                   || getTypeID() == kInt
+                   || getTypeID() == kLong
+                   || getTypeID() == kFloat
+                   || getTypeID() == kDouble
+                   || getTypeID() == kDate
+                   || getTypeID() == kDatetime
+                   || getTypeID() == kDatetimeInterval
+                   || getTypeID() == kYearMonthInterval));
+    DCHECK(!isNull());
+    if (ownsOutOfLineData()) {
+      value_info_ &= ~kOwnershipMask;
+      return const_cast<void*>(value_union_.out_of_line_data);
+    } else {
+      const std::size_t length = value_info_ >> kSizeShift;
+      void *data = std::malloc(length);
+      std::memcpy(data, value_union_.out_of_line_data, length);
+      return data;
+    }
+  }
+
   /**
    * @brief Get the length of the ASCII string this TypedValue represents,
    *        not counting a null terminator character, if any (same behavior

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/VarCharType.cpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.cpp b/types/VarCharType.cpp
index 7eeb04c..f0f677d 100644
--- a/types/VarCharType.cpp
+++ b/types/VarCharType.cpp
@@ -86,21 +86,21 @@ string VarCharType::getName() const {
   return name;
 }
 
-std::string VarCharType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string VarCharType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  return std::string(static_cast<const char*>(value.getOutOfLineData()));
+  return std::string(static_cast<const char*>(castValueToLiteral(value).getOutOfLineData()));
 }
 
-void VarCharType::printValueToFile(const TypedValue &value,
+void VarCharType::printValueToFile(const UntypedLiteral *value,
                                    FILE *file,
                                    const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*s",
                static_cast<int>(padding),
-               static_cast<const char*>(value.getOutOfLineData()));
+               static_cast<const char*>(castValueToLiteral(value).getOutOfLineData()));
 }
 
 bool VarCharType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index 05b2aae..47a2874 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -60,9 +60,9 @@ class VarCharType : public AsciiStringSuperType<kVarChar> {
     return length_;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -73,12 +73,10 @@ class VarCharType : public AsciiStringSuperType<kVarChar> {
                          const Type &original_type) const override;
 
  private:
-  VarCharType(const std::size_t length, const bool nullable)
+  VarCharType(const bool nullable, const std::size_t length)
       : AsciiStringSuperType<kVarChar>(nullable, 1, length + 1, length) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(VarCharType);
+  QUICKSTEP_SYNTHESIZE_TYPE(VarCharType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/YearMonthIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.cpp b/types/YearMonthIntervalType.cpp
index d656fca..b395dff 100644
--- a/types/YearMonthIntervalType.cpp
+++ b/types/YearMonthIntervalType.cpp
@@ -45,10 +45,10 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string YearMonthIntervalType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string YearMonthIntervalType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  std::int64_t months = value.getLiteral<YearMonthIntervalLit>().months;
+  std::int64_t months = castValueToLiteral(value).months;
   const bool negative_interval = months < 0;
   if (negative_interval) {
     months = -months;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index e890ea9..ab06911 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -46,7 +46,7 @@ class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
     return YearMonthIntervalLit::kPrintingChars;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
   TypedValue makeZeroValue() const override {
     return TypedValue(YearMonthIntervalLit{0});
@@ -59,9 +59,7 @@ class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
   explicit YearMonthIntervalType(const bool nullable)
       : TypeSynthesizer<kYearMonthInterval>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(YearMonthIntervalType);
+  QUICKSTEP_SYNTHESIZE_TYPE(YearMonthIntervalType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/containers/ColumnVector.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp
index a312ee2..d524ff5 100644
--- a/types/containers/ColumnVector.hpp
+++ b/types/containers/ColumnVector.hpp
@@ -280,7 +280,8 @@ class NativeColumnVector : public ColumnVector {
    **/
   inline void appendTypedValue(const TypedValue &value) {
     DCHECK_LT(actual_length_, reserved_length_);
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (null_bitmap_ && value.isNull()) {
       null_bitmap_->setBit(actual_length_, true);
     } else {
@@ -319,7 +320,8 @@ class NativeColumnVector : public ColumnVector {
    * @param value A value to fill this ColumnVector with.
    **/
   inline void fillWithValue(const TypedValue &value) {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) {
       fillWithNulls();
     } else {
@@ -408,7 +410,8 @@ class NativeColumnVector : public ColumnVector {
   inline void positionalWriteTypedValue(const std::size_t position,
                                         const TypedValue &value) {
     DCHECK_LT(position, actual_length_);
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (null_bitmap_ && value.isNull()) {
       null_bitmap_->setBit(position, true);
     } else {
@@ -515,7 +518,8 @@ class IndirectColumnVector : public ColumnVector {
    * @param value A value to append to this NativeColumnVector.
    **/
   inline void appendTypedValue(const TypedValue &value) {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     DCHECK_LT(values_.size(), reserved_length_);
     values_.emplace_back(value);
   }
@@ -526,7 +530,8 @@ class IndirectColumnVector : public ColumnVector {
    * @param value A value to append to this NativeColumnVector.
    **/
   inline void appendTypedValue(TypedValue &&value) {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature())) << type_.getName();
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature())) << type_.getName();
+    // TODO(refactor-type): fix signature.
     DCHECK_LT(values_.size(), reserved_length_);
     values_.emplace_back(std::move(value));
   }
@@ -547,7 +552,8 @@ class IndirectColumnVector : public ColumnVector {
    * @param value A value to fill this ColumnVector with.
    **/
   inline void fillWithValue(const TypedValue &value) {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     values_.assign(reserved_length_, value);
   }
 
@@ -576,7 +582,8 @@ class IndirectColumnVector : public ColumnVector {
    **/
   inline void positionalWriteTypedValue(const std::size_t position,
                                         const TypedValue &value) {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     DCHECK_LT(position, values_.size());
     values_[position] = value;
   }
@@ -594,7 +601,8 @@ class IndirectColumnVector : public ColumnVector {
    **/
   inline void positionalWriteTypedValue(const std::size_t position,
                                         TypedValue &&value) {  // NOLINT(whitespace/operators)
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     DCHECK_LT(position, values_.size());
     values_[position] = std::move(value);
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/operations/OperationUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationUtil.hpp b/types/operations/OperationUtil.hpp
index 8290061..af23b1c 100644
--- a/types/operations/OperationUtil.hpp
+++ b/types/operations/OperationUtil.hpp
@@ -17,8 +17,8 @@
  * under the License.
  **/
 
-#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTIL_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTIL_HPP_
+#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
 
 #include <cstddef>
 #include <list>
@@ -103,7 +103,7 @@ template <typename FuncSpec, typename T, typename EnableT = void>
 struct Codegen;
 
 template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kCxxNativePod>> {
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kCxxInlinePod>> {
   using ColumnVectorType = NativeColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -171,7 +171,7 @@ struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kCxxNativePod>>
 };
 
 template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParNativePod>> {
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParInlinePod>> {
   using ColumnVectorType = NativeColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -244,7 +244,7 @@ struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParNativePod>>
 };
 
 template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParIndirectPod>> {
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParOutOfLinePod>> {
   using ColumnVectorType = IndirectColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -331,4 +331,4 @@ struct OperationPack {
 
 }  // namespace quickstep
 
-#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTIL_HPP_
+#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/operations/binary_operations/BinaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationWrapper.hpp b/types/operations/binary_operations/BinaryOperationWrapper.hpp
index d819000..f5edf52 100644
--- a/types/operations/binary_operations/BinaryOperationWrapper.hpp
+++ b/types/operations/binary_operations/BinaryOperationWrapper.hpp
@@ -195,7 +195,7 @@ class UncheckedBinaryOperatorWrapperCodegen : public UncheckedBinaryOperator {
       std::size_t *num_tuples_applied) const override {
     constexpr bool is_supported =
         LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
-        LeftType::kMemoryLayout == kCxxNativePod &&
+        LeftType::kMemoryLayout == kCxxInlinePod &&
         std::is_copy_assignable<typename LeftType::cpptype>::value;
 
     using RightCVT = typename RightGen::ColumnVectorType;
@@ -217,7 +217,7 @@ class UncheckedBinaryOperatorWrapperCodegen : public UncheckedBinaryOperator {
       std::size_t *num_tuples_applied) const override {
     constexpr bool is_supported =
         LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
-        LeftType::kMemoryLayout == kCxxNativePod &&
+        LeftType::kMemoryLayout == kCxxInlinePod &&
         std::is_copy_assignable<typename LeftType::cpptype>::value;
 
     return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
@@ -511,7 +511,7 @@ class BinaryOperationWrapper : public BinaryOperation {
     DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
     DCHECK(right.getTypeID() == RightType::kStaticTypeID);
     DCHECK(static_arguments.empty());
-    return getResultTypeImpl<ResultType::kIsParameterizedPod>(
+    return getResultTypeImpl<ResultType::kIsParPod>(
         left, right, static_arguments);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/operations/comparisons/BasicComparison.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/BasicComparison.hpp b/types/operations/comparisons/BasicComparison.hpp
index a7dd50a..bf80e50 100644
--- a/types/operations/comparisons/BasicComparison.hpp
+++ b/types/operations/comparisons/BasicComparison.hpp
@@ -284,18 +284,19 @@ template <template <typename LeftCppType, bool left_type_nullable,
                     bool right_nullable, bool right_null_terminated, bool right_longer> class StringComparator>
 UncheckedComparator* BasicComparison::makeUncheckedComparatorForTypesHelper(const Type &left,
                                                                             const Type &right) const {
-  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-    return makeNumericComparatorOuterHelper<LiteralComparator>(left, right);
-  } else if ((left.getTypeID() == kDate && right.getTypeID() == kDate)                         ||
-             (left.getTypeID() == kDatetime && right.getTypeID() == kDatetime)                 ||
-             (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval) ||
-             (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval)) {
-    return makeDateComparatorOuterHelper<LiteralComparator>(left, right);
-  } else if (left.getSuperTypeID() == Type::kAsciiString && right.getSuperTypeID() == Type::kAsciiString) {
-    return makeStringComparatorOuterHelper<StringComparator>(left, right);
-  } else {
+//  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
+//    return makeNumericComparatorOuterHelper<LiteralComparator>(left, right);
+//  } else if ((left.getTypeID() == kDate && right.getTypeID() == kDate)                         ||
+//             (left.getTypeID() == kDatetime && right.getTypeID() == kDatetime)                 ||
+//             (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval) ||
+//             (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval)) {
+//    return makeDateComparatorOuterHelper<LiteralComparator>(left, right);
+//  } else if (left.getSuperTypeID() == Type::kAsciiString && right.getSuperTypeID() == Type::kAsciiString) {
+//    return makeStringComparatorOuterHelper<StringComparator>(left, right);
+//  } else {
     throw OperationInapplicableToType(getName(), 2, kTypeNames[left.getTypeID()], kTypeNames[right.getTypeID()]);
-  }
+//  }
+  // TODO(refactor-type): Switch back.
 }
 
 template <template <typename LeftCppType, bool left_type_nullable,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp
index 5091e89..8e0db55 100644
--- a/types/operations/unary_operations/CastOperation.cpp
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -62,7 +62,7 @@ class CastToAsciiStringFunctor : public UnaryFunctor<ArgumentT, ResultT> {
         max_string_length_(max_string_length) {}
 
   inline void apply(const typename ArgumentT::cpptype &argument, void *result) const {
-    std::string str = argument_type_.printValueToString(TypedValue(argument));
+    std::string str = argument_type_.printValueToString(&argument);
     const std::size_t str_len = str.length();
 
     if (str_len < max_string_length_) {
@@ -74,7 +74,7 @@ class CastToAsciiStringFunctor : public UnaryFunctor<ArgumentT, ResultT> {
   }
 
   inline TypedValue apply(const typename ArgumentT::cpptype &argument) const {
-    std::string str = argument_type_.printValueToString(TypedValue(argument));
+    std::string str = argument_type_.printValueToString(&argument);
     const std::size_t len = std::min(str.length(), max_string_length_);
     const std::size_t buf_len = len + 1;
 
@@ -225,7 +225,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
         }
         case kChar:  // Fall through
         case kVarChar: {
-          return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+          return InvokeOnTypeID<TypeIDSelector<kChar, kVarChar>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
             using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
@@ -244,7 +244,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
       }
     });
   } else if (QUICKSTEP_EQUALS_ANY_CONSTANT(argument_type_id, kChar, kVarChar)) {
-    return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+    return InvokeOnTypeID<TypeIDSelector<kChar, kVarChar>>(
         argument_type_id,
         [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
       using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
@@ -270,7 +270,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
         }
         case kChar:  // Fall through
         case kVarChar: {
-          return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+          return InvokeOnTypeID<TypeIDSelector<kChar, kVarChar>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
             using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/operations/unary_operations/UnaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp
index 09e7b05..00562a6 100644
--- a/types/operations/unary_operations/UnaryOperationWrapper.hpp
+++ b/types/operations/unary_operations/UnaryOperationWrapper.hpp
@@ -184,7 +184,7 @@ class UnaryOperationWrapper : public UnaryOperation {
       const std::vector<TypedValue> &static_arguments) const override {
     DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
     DCHECK(static_arguments.empty());
-    return getResultTypeImpl<ResultType::kIsParameterizedPodz>(
+    return getResultTypeImpl<ResultType::kIsParPod>(
         argument_type, static_arguments);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/utility/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt
index 9093910..573ea7e 100644
--- a/utility/CMakeLists.txt
+++ b/utility/CMakeLists.txt
@@ -163,6 +163,9 @@ add_subdirectory(meta)
 
 # Declare micro-libs:
 add_library(quickstep_utility_Alignment ../empty_src.cpp Alignment.hpp)
+add_library(quickstep_utility_BarrieredReadWriteConcurrentBitVector
+            ../empty_src.cpp
+            BarrieredReadWriteConcurrentBitVector.hpp)
 add_library(quickstep_utility_BitManipulation ../empty_src.cpp BitManipulation.hpp)
 add_library(quickstep_utility_BitVector ../empty_src.cpp BitVector.hpp)
 add_library(quickstep_utility_BloomFilter ../empty_src.cpp BloomFilter.hpp)
@@ -172,12 +175,10 @@ add_library(quickstep_utility_BloomFilter_proto
 add_library(quickstep_utility_BulkIoConfiguration BulkIoConfiguration.cpp BulkIoConfiguration.hpp)
 add_library(quickstep_utility_CalculateInstalledMemory CalculateInstalledMemory.cpp CalculateInstalledMemory.hpp)
 add_library(quickstep_utility_Cast ../empty_src.cpp Cast.hpp)
+add_library(quickstep_utility_CharStream ../empty_src.cpp CharStream.hpp)
 add_library(quickstep_utility_CheckSnprintf ../empty_src.cpp CheckSnprintf.hpp)
 add_library(quickstep_utility_ColumnVectorCache ../empty_src.cpp ColumnVectorCache.hpp)
 add_library(quickstep_utility_CompositeHash ../empty_src.cpp CompositeHash.hpp)
-add_library(quickstep_utility_BarrieredReadWriteConcurrentBitVector
-            ../empty_src.cpp
-            BarrieredReadWriteConcurrentBitVector.hpp)
 add_library(quickstep_utility_DAG ../empty_src.cpp DAG.hpp)
 add_library(quickstep_utility_DisjointTreeForest ../empty_src.cpp DisjointTreeForest.hpp)
 add_library(quickstep_utility_EqualsAnyConstant ../empty_src.cpp EqualsAnyConstant.hpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/utility/CharStream.hpp
----------------------------------------------------------------------
diff --git a/utility/CharStream.hpp b/utility/CharStream.hpp
new file mode 100644
index 0000000..060b1a6
--- /dev/null
+++ b/utility/CharStream.hpp
@@ -0,0 +1,106 @@
+/**
+ * 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_UTILITY_CHAR_STREAM_HPP_
+#define QUICKSTEP_UTILITY_CHAR_STREAM_HPP_
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <type_traits>
+
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+class CharStream {
+ public:
+  template <typename T>
+  CharStream(const T &value,
+             std::enable_if_t<std::is_pod<T>::value && sizeof(T) <= sizeof(std::uint64_t)> * = 0)
+      : length_(sizeof(T)),
+        delete_function_(nullptr) {
+    std::memcpy(&value_union_.inline_data, &value, sizeof(T));
+  }
+
+  CharStream(std::vector<char> &&value)
+      : length_(value.size()),
+        delete_function_(&DeleteObject<std::vector<char>>) {
+    value_union_.out_of_line_data = new std::vector<char>(std::move(value));
+  }
+
+  CharStream(const void *value, const std::size_t length, const bool take_ownership)
+      : length_(length),
+        delete_function_(std::free) {
+    if (take_ownership) {
+      value_union_.out_of_line_data = value;
+    } else {
+      void *copy_of_value = std::malloc(length);
+      std::memcpy(copy_of_value, value, length);
+      value_union_.out_of_line_data = copy_of_value;
+    }
+  }
+
+  ~CharStream() {
+    if (delete_function_ != nullptr) {
+      delete_function_(const_cast<void*>(value_union_.out_of_line_data));
+    }
+  }
+
+  std::size_t length() const {
+    return length_;
+  }
+
+  const void* getDataPtr() const {
+    return delete_function_ == nullptr ? &value_union_.inline_data
+                                       : value_union_.out_of_line_data;
+  }
+
+ private:
+  union ValueUnion {
+    std::uint64_t inline_data;
+    const void *out_of_line_data;
+  };
+
+  typedef void (*DeleterFunction)(void*);
+
+  template <typename T>
+  static void DeleteObject(void *object) {
+    delete static_cast<T*>(object);
+  }
+
+  std::size_t length_;
+  ValueUnion value_union_;
+  DeleterFunction delete_function_;
+
+  DISALLOW_COPY_AND_ASSIGN(CharStream);
+};
+
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_CHAR_STREAM_HPP_



[27/38] incubator-quickstep git commit: Add array expression

Posted by ji...@apache.org.
Add array expression


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/1792b9f4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/1792b9f4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/1792b9f4

Branch: refs/heads/refactor-type
Commit: 1792b9f4d63d792fd278e28a6d89b5b6370d74d8
Parents: d6a51ac
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Mon Oct 2 01:30:46 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 parser/ParseBasicExpressions.cpp      |   27 +
 parser/ParseBasicExpressions.hpp      |   42 +
 parser/ParseExpression.hpp            |    1 +
 parser/SqlLexer.lpp                   |    1 +
 parser/SqlParser.ypp                  |   29 +
 parser/preprocessed/SqlLexer_gen.cpp  | 1429 ++++++------
 parser/preprocessed/SqlLexer_gen.hpp  |    2 +-
 parser/preprocessed/SqlParser_gen.cpp | 3339 +++++++++++++++-------------
 parser/preprocessed/SqlParser_gen.hpp |  115 +-
 query_optimizer/resolver/Resolver.cpp |   28 +
 query_optimizer/resolver/Resolver.hpp |    6 +
 types/ArrayType.cpp                   |    2 +-
 12 files changed, 2651 insertions(+), 2370 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/ParseBasicExpressions.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseBasicExpressions.cpp b/parser/ParseBasicExpressions.cpp
index 580cd09..fd9094c 100644
--- a/parser/ParseBasicExpressions.cpp
+++ b/parser/ParseBasicExpressions.cpp
@@ -127,4 +127,31 @@ void ParseFunctionCall::getFieldStringItems(
   }
 }
 
+std::string ParseArray::generateName() const {
+  string name("{");
+  if (!elements_.empty()) {
+    name.append(elements_.front()->generateName());
+    for (std::size_t i = 1; i < elements_.size(); ++i) {
+      name.append(",");
+      name.append(elements_.at(i)->generateName());
+    }
+  }
+  name.append("}");
+  return name;
+}
+
+void ParseArray::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    std::vector<const ParseTreeNode*> *non_container_child_fields,
+    std::vector<std::string> *container_child_field_names,
+    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
+  container_child_field_names->emplace_back("elements");
+  container_child_fields->emplace_back();
+  for (const auto &element : elements_) {
+    container_child_fields->back().emplace_back(element.get());
+  }
+}
+
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/ParseBasicExpressions.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseBasicExpressions.hpp b/parser/ParseBasicExpressions.hpp
index 4572214..af2393f 100644
--- a/parser/ParseBasicExpressions.hpp
+++ b/parser/ParseBasicExpressions.hpp
@@ -344,6 +344,48 @@ class ParseFunctionCall : public ParseExpression {
   DISALLOW_COPY_AND_ASSIGN(ParseFunctionCall);
 };
 
+
+class ParseArray : public ParseExpression {
+ public:
+  ParseArray(const int line_number, const int column_number)
+      : ParseExpression(line_number, column_number) {}
+
+  ~ParseArray() override {
+  }
+
+  ExpressionType getExpressionType() const override {
+    return kArray;
+  }
+
+  std::string getName() const override {
+    return "Array";
+  }
+
+  std::string generateName() const override;
+
+  const std::vector<std::unique_ptr<ParseExpression>>& elements() const {
+    return elements_;
+  }
+
+  void add(ParseExpression *element) {
+    elements_.emplace_back(std::unique_ptr<ParseExpression>(element));
+  }
+
+ protected:
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<const ParseTreeNode*> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
+
+ private:
+  std::vector<std::unique_ptr<ParseExpression>> elements_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParseArray);
+};
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/ParseExpression.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseExpression.hpp b/parser/ParseExpression.hpp
index 94b4487..f9a33a2 100644
--- a/parser/ParseExpression.hpp
+++ b/parser/ParseExpression.hpp
@@ -37,6 +37,7 @@ namespace quickstep {
 class ParseExpression : public ParseTreeNode {
  public:
   enum ExpressionType {
+    kArray,
     kAttribute,
     kBinaryExpression,
     kFunctionCall,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/SqlLexer.lpp
----------------------------------------------------------------------
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index 9a63483..b45d8ab 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -39,6 +39,7 @@ namespace quickstep {
 
 class BinaryOperation;
 class Comparison;
+class ParseArray;
 class ParseAssignment;
 class ParseAttribute;
 class ParseAttributeDefinition;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/SqlParser.ypp
----------------------------------------------------------------------
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index 156e9e7..01be345 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -186,6 +186,7 @@ typedef void* yyscan_t;
   quickstep::ParseString *unary_operation_;
   quickstep::ParseString *binary_operation_;
 
+  quickstep::ParseArray *array_expression_;
   quickstep::ParseFunctionCall *function_call_;
   quickstep::PtrList<quickstep::ParseExpression> *expression_list_;
 
@@ -396,6 +397,11 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
   extract_function
   substr_function
 
+
+%type <array_expression_>
+  array_expression
+  array_element_commalist
+
 %type <attribute_>
   attribute_ref
 
@@ -1710,6 +1716,9 @@ expression_base:
   | literal_value {
     $$ = new quickstep::ParseScalarLiteral($1);
   }
+  | array_expression {
+    $$ = $1;
+  }
   | function_call {
     $$ = $1;
   }
@@ -1740,6 +1749,26 @@ expression_base:
     $$ = $1;
   };
 
+array_expression:
+  array_element_commalist TOKEN_RBRACE {
+    $$ = $1;
+  }
+  | TOKEN_LBRACE TOKEN_RBRACE {
+    $$ = new quickstep::ParseArray(@1.first_line, @1.first_column);
+  }
+  ;
+
+array_element_commalist:
+  array_element_commalist ',' add_expression {
+    $$ = $1;
+    $$->add($3);
+  }
+  | TOKEN_LBRACE add_expression {
+    $$ = new quickstep::ParseArray(@1.first_line, @1.first_column);
+    $$->add($2);
+  }
+  ;
+
 function_call:
   any_name '(' ')' {
     $$ = new quickstep::ParseFunctionCall(


[34/38] incubator-quickstep git commit: More updates, refactor names

Posted by ji...@apache.org.
More updates, refactor names


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/f9e32e6a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/f9e32e6a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/f9e32e6a

Branch: refs/heads/refactor-type
Commit: f9e32e6ad2be1e3ce1f2a548304ad6a1a24094bb
Parents: 8269764
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Thu Oct 5 17:02:33 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 query_optimizer/ExecutionGenerator.cpp          |   3 +-
 query_optimizer/expressions/CMakeLists.txt      |  15 +
 query_optimizer/expressions/Cast.cpp            | 107 ++++++
 query_optimizer/expressions/Cast.hpp            | 125 +++++++
 query_optimizer/resolver/CMakeLists.txt         |   3 +
 query_optimizer/resolver/Resolver.cpp           |  10 +
 types/AsciiStringSuperType.hpp                  |   7 +-
 types/CharType.cpp                              |  64 +++-
 types/CharType.hpp                              |  13 +
 types/GenericValue.hpp                          |   4 +
 types/MetaType-decl.hpp                         |   3 +-
 types/NumericTypeSafeCoercibility.hpp           |  10 +-
 types/TypeRegistrar.hpp                         |   6 +-
 types/TypeSynthesizer.hpp                       | 136 +++++++-
 types/operations/CMakeLists.txt                 |  23 +-
 types/operations/OperationFactory.cpp           |  12 +-
 types/operations/OperationUtil.hpp              | 334 ------------------
 .../binary_operations/AddBinaryOperation.hpp    |  94 ------
 .../ArithmeticBinaryFunctors.hpp                | 182 ++++++++++
 .../ArithmeticBinaryOperations.hpp              | 182 ----------
 .../AsciiStringBinaryFunctors.hpp               | 130 +++++++
 .../AsciiStringBinaryOperations.hpp             | 130 -------
 .../BinaryOperationWrapper.hpp                  |   8 +-
 .../operations/binary_operations/CMakeLists.txt |  30 +-
 .../binary_operations/CMathBinaryFunctors.hpp   |  78 +++++
 .../binary_operations/CMathBinaryOperations.hpp |  78 -----
 .../MultiplyBinaryOperation.hpp                 | 102 ------
 .../ArithmeticUnaryFunctors.hpp                 |  80 +++++
 .../ArithmeticUnaryOperations.hpp               |  81 -----
 .../AsciiStringUnaryFunctors.hpp                | 122 +++++++
 .../AsciiStringUnaryOperations.hpp              | 122 -------
 .../operations/unary_operations/CMakeLists.txt  |  40 ++-
 .../unary_operations/CMathUnaryFunctors.hpp     | 116 +++++++
 .../unary_operations/CMathUnaryOperations.hpp   | 116 -------
 .../unary_operations/CastFunctorOverloads.hpp   | 183 ++++++++++
 .../unary_operations/CastOperation.cpp          | 314 +++++------------
 .../unary_operations/CastOperation.hpp          |  60 +---
 .../unary_operations/UnaryOperationWrapper.hpp  |   6 +-
 types/operations/utility/CMakeLists.txt         |  37 ++
 types/operations/utility/CastUtil.cpp           |   0
 types/operations/utility/CastUtil.hpp           |   0
 .../utility/OperationSynthesizeUtil.hpp         | 335 +++++++++++++++++++
 utility/meta/Common.hpp                         |  15 +-
 utility/meta/Dispatchers.hpp                    |   2 +-
 utility/meta/MetaprogrammingModule.hpp          |  24 ++
 utility/meta/TransitiveClosure.hpp              |   2 +-
 utility/meta/TypeList.hpp                       |  63 ++--
 utility/meta/TypeListMetaFunctions.hpp          |  80 ++++-
 48 files changed, 2045 insertions(+), 1642 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/query_optimizer/ExecutionGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/ExecutionGenerator.cpp b/query_optimizer/ExecutionGenerator.cpp
index 372d576..d4544a0 100644
--- a/query_optimizer/ExecutionGenerator.cpp
+++ b/query_optimizer/ExecutionGenerator.cpp
@@ -1466,7 +1466,8 @@ void ExecutionGenerator::convertInsertTuple(
 
   S::Tuple *tuple_proto = query_context_proto_->add_tuples();
   for (const E::ScalarLiteralPtr &literal : physical_plan->column_values()) {
-    tuple_proto->add_attribute_values()->CopyFrom(literal->value().getProto());
+    tuple_proto->add_attribute_values()->CopyFrom(
+        literal->value().toTypedValue().getProto());
   }
 
   // FIXME(qzeng): A better way is using a traits struct to look up whether a storage

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index cf2727f..b51a0a8 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -20,6 +20,7 @@ add_library(quickstep_queryoptimizer_expressions_AggregateFunction AggregateFunc
 add_library(quickstep_queryoptimizer_expressions_Alias Alias.cpp Alias.hpp)
 add_library(quickstep_queryoptimizer_expressions_AttributeReference AttributeReference.cpp AttributeReference.hpp)
 add_library(quickstep_queryoptimizer_expressions_BinaryExpression BinaryExpression.cpp BinaryExpression.hpp)
+add_library(quickstep_queryoptimizer_expressions_Cast Cast.cpp Cast.hpp)
 add_library(quickstep_queryoptimizer_expressions_CommonSubexpression
             CommonSubexpression.cpp
             CommonSubexpression.hpp)
@@ -102,6 +103,20 @@ target_link_libraries(quickstep_queryoptimizer_expressions_BinaryExpression
                       quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_utility_HashPair
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_queryoptimizer_expressions_Cast
+                      quickstep_expressions_scalar_Scalar
+                      quickstep_expressions_scalar_ScalarUnaryExpression
+                      quickstep_queryoptimizer_OptimizerTree
+                      quickstep_queryoptimizer_expressions_AttributeReference
+                      quickstep_queryoptimizer_expressions_ExprId
+                      quickstep_queryoptimizer_expressions_Expression
+                      quickstep_queryoptimizer_expressions_ExpressionType
+                      quickstep_queryoptimizer_expressions_PatternMatcher
+                      quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_types_Type
+                      quickstep_types_operations_unaryoperations_CastOperation
+                      quickstep_utility_HashPair
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_CommonSubexpression
                       glog
                       quickstep_expressions_scalar_ScalarSharedExpression

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/query_optimizer/expressions/Cast.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Cast.cpp b/query_optimizer/expressions/Cast.cpp
new file mode 100644
index 0000000..6b2015f
--- /dev/null
+++ b/query_optimizer/expressions/Cast.cpp
@@ -0,0 +1,107 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "query_optimizer/expressions/Cast.hpp"
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "expressions/scalar/Scalar.hpp"
+#include "expressions/scalar/ScalarUnaryExpression.hpp"
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/ExprId.hpp"
+#include "query_optimizer/expressions/Expression.hpp"
+#include "query_optimizer/expressions/PatternMatcher.hpp"
+#include "query_optimizer/expressions/Scalar.hpp"
+#include "types/MetaType.hpp"
+#include "types/Type.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/OperationFactory.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/HashPair.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+namespace optimizer {
+namespace expressions {
+
+ExpressionPtr Cast::copyWithNewChildren(
+    const std::vector<ExpressionPtr> &new_children) const {
+  DCHECK_EQ(getNumChildren(), new_children.size());
+  ScalarPtr scalar;
+  CHECK(SomeScalar::MatchesWithConditionalCast(new_children[0], &scalar))
+      << new_children[0]->toString();
+  return Create(scalar, target_type_);
+}
+
+::quickstep::Scalar *Cast::concretize(
+    const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
+  const OperationSignaturePtr op_signature =
+      OperationSignature::Create(
+          "cast", {operand_->getValueType().getTypeID(), kMetaType}, 1);
+  const UnaryOperationPtr cast_operation =
+      OperationFactory::Instance().getUnaryOperation(op_signature);
+
+  std::vector<TypedValue> meta_type_value =
+      { GenericValue::CreateWithLiteral(
+            MetaType::InstanceNonNullable(), &target_type_).toTypedValue() };
+  DCHECK(cast_operation->canApplyTo(operand_->getValueType(), meta_type_value));
+
+  return new ::quickstep::ScalarUnaryExpression(
+      op_signature, cast_operation, operand_->concretize(substitution_map),
+      std::make_shared<const std::vector<TypedValue>>(std::move(meta_type_value)));
+}
+
+std::size_t Cast::computeHash() const {
+  return CombineHashes(
+      CombineHashes(static_cast<std::size_t>(ExpressionType::kCast),
+                    operand_->hash()),
+      static_cast<std::size_t>(target_type_.getTypeID()));
+}
+
+bool Cast::equals(const ScalarPtr &other) const {
+  CastPtr expr;
+  if (SomeCast::MatchesWithConditionalCast(other, &expr)) {
+    return operand_->equals(expr->operand_) && target_type_.equals(expr->target_type_);
+  }
+  return false;
+}
+
+void Cast::getFieldStringItems(
+    std::vector<std::string> *inline_field_names,
+    std::vector<std::string> *inline_field_values,
+    std::vector<std::string> *non_container_child_field_names,
+    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_);
+}
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/query_optimizer/expressions/Cast.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Cast.hpp b/query_optimizer/expressions/Cast.hpp
new file mode 100644
index 0000000..11be775
--- /dev/null
+++ b/query_optimizer/expressions/Cast.hpp
@@ -0,0 +1,125 @@
+/**
+ * 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_QUERY_OPTIMIZER_EXPRESSIONS_CAST_HPP_
+#define QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_CAST_HPP_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "query_optimizer/OptimizerTree.hpp"
+#include "query_optimizer/expressions/AttributeReference.hpp"
+#include "query_optimizer/expressions/ExprId.hpp"
+#include "query_optimizer/expressions/Expression.hpp"
+#include "query_optimizer/expressions/ExpressionType.hpp"
+#include "query_optimizer/expressions/Scalar.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class CatalogAttribute;
+class Type;
+
+namespace optimizer {
+namespace expressions {
+
+/** \addtogroup OptimizerExpressions
+ *  @{
+ */
+
+class Cast;
+typedef std::shared_ptr<const Cast> CastPtr;
+
+/**
+ * @brief Converts a value of a type to another type.
+ */
+class Cast : public Scalar {
+ public:
+  ExpressionType getExpressionType() const override { return ExpressionType::kCast; }
+
+  std::string getName() const override { return "Cast"; }
+
+  const Type& getValueType() const override { return target_type_; }
+
+  bool isConstant() const override { return operand_->isConstant(); }
+
+  /**
+   * @return The expression to be coerced.
+   */
+  const ScalarPtr& operand() const { return operand_; }
+
+  std::vector<AttributeReferencePtr> getReferencedAttributes() const override {
+    return operand_->getReferencedAttributes();
+  }
+
+  ExpressionPtr copyWithNewChildren(
+      const std::vector<ExpressionPtr> &new_children) const override;
+
+  ::quickstep::Scalar* concretize(
+      const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const override;
+
+  bool equals(const ScalarPtr &other) const override;
+
+  /**
+   * @brief Creates a Cast expression that converts \p operand to \p target_type.
+   *
+   * @param operand The input expression to be coerced.
+   * @param target_type The target type that the expression is converted to.
+   * @return A Cast expression.
+   */
+  static CastPtr Create(const ScalarPtr &operand, const Type &target_type) {
+    return CastPtr(new Cast(operand, target_type));
+  }
+
+ protected:
+  std::size_t computeHash() const override;
+
+  void getFieldStringItems(
+      std::vector<std::string> *inline_field_names,
+      std::vector<std::string> *inline_field_values,
+      std::vector<std::string> *non_container_child_field_names,
+      std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
+      std::vector<std::string> *container_child_field_names,
+      std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
+
+ private:
+  Cast(const ScalarPtr &operand, const Type &target_type)
+      : operand_(operand),
+        target_type_(target_type) {
+    addChild(operand);
+    DCHECK(target_type.isCoercibleFrom(operand->getValueType()));
+  }
+
+  ScalarPtr operand_;
+  const Type &target_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(Cast);
+};
+
+/** @} */
+
+}  // namespace expressions
+}  // namespace optimizer
+}  // namespace quickstep
+
+#endif /* QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_CAST_HPP_ */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/query_optimizer/resolver/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index 8a1116a..4dd13f2 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -47,6 +47,7 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
                       quickstep_parser_ParseBasicExpressions
                       quickstep_parser_ParseBlockProperties
                       quickstep_parser_ParseCaseExpressions
+                      quickstep_parser_ParseDataType
                       quickstep_parser_ParseExpression
                       quickstep_parser_ParseGeneratorTableReference
                       quickstep_parser_ParseGroupBy
@@ -74,6 +75,7 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
                       quickstep_queryoptimizer_expressions_Alias
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_BinaryExpression
+                      quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_ComparisonExpression
                       quickstep_queryoptimizer_expressions_Exists
                       quickstep_queryoptimizer_expressions_ExprId
@@ -123,6 +125,7 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
                       quickstep_types_ArrayType
                       quickstep_types_GenericValue
                       quickstep_types_IntType
+                      quickstep_types_LongType
                       quickstep_types_MetaType
                       quickstep_types_NullType
                       quickstep_types_Type

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index cf3ca6e..40b460d 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -71,6 +71,7 @@
 #include "query_optimizer/expressions/Alias.hpp"
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/expressions/BinaryExpression.hpp"
+#include "query_optimizer/expressions/Cast.hpp"
 #include "query_optimizer/expressions/ComparisonExpression.hpp"
 #include "query_optimizer/expressions/Exists.hpp"
 #include "query_optimizer/expressions/ExprId.hpp"
@@ -2551,6 +2552,15 @@ E::ScalarPtr Resolver::resolveExpression(
           expression_resolution_info,
           true /* has_single_column */);
     }
+    case ParseExpression::kTypeCast: {
+      const ParseTypeCast &parse_type_cast =
+          static_cast<const ParseTypeCast&>(parse_expression);
+      return E::Cast::Create(
+          resolveExpression(parse_type_cast.operand(),
+                            nullptr /* type_hint */,
+                            expression_resolution_info),
+          resolveDataType(parse_type_cast.target_type()));
+    }
     default:
       LOG(FATAL) << "Unknown scalar type: "
                  << parse_expression.getExpressionType();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/AsciiStringSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp
index b6abcdf..7de550f 100644
--- a/types/AsciiStringSuperType.hpp
+++ b/types/AsciiStringSuperType.hpp
@@ -52,7 +52,7 @@ class AsciiStringSuperType : public TypeSynthesizer<type_id> {
    * @return The maximum length of a string of this type.
    **/
   inline std::size_t getStringLength() const {
-    return length_;
+    return TypeSynthesizer<type_id>::length_;
   }
 
  protected:
@@ -61,12 +61,9 @@ class AsciiStringSuperType : public TypeSynthesizer<type_id> {
                        const std::size_t maximum_byte_length,
                        const std::size_t string_length)
       : TypeSynthesizer<type_id>(
-            nullable, minimum_byte_length, maximum_byte_length, string_length),
-        length_(string_length) {
+            nullable, minimum_byte_length, maximum_byte_length, string_length) {
   }
 
-  const std::size_t length_;
-
  private:
   DISALLOW_COPY_AND_ASSIGN(AsciiStringSuperType);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/CharType.cpp
----------------------------------------------------------------------
diff --git a/types/CharType.cpp b/types/CharType.cpp
index eb3f64a..319ae33 100644
--- a/types/CharType.cpp
+++ b/types/CharType.cpp
@@ -19,6 +19,7 @@
 
 #include "types/CharType.hpp"
 
+#include <algorithm>
 #include <cstddef>
 #include <cstdio>
 #include <cstdlib>
@@ -33,12 +34,9 @@
 #include "types/port/strnlen.hpp"
 #include "utility/PtrMap.hpp"
 
-#include "glog/logging.h"
+#include "third_party/src/farmhash/farmhash.h"
 
-using std::pair;
-using std::size_t;
-using std::strcmp;
-using std::string;
+#include "glog/logging.h"
 
 namespace quickstep {
 
@@ -55,8 +53,8 @@ bool CharType::isSafelyCoercibleFrom(const Type &original_type) const {
   }
 }
 
-string CharType::getName() const {
-  string name("Char(");
+std::string CharType::getName() const {
+  std::string name("Char(");
   name.append(std::to_string(length_));
   name.push_back(')');
   if (nullable_) {
@@ -65,10 +63,58 @@ string CharType::getName() const {
   return name;
 }
 
+std::size_t CharType::hashValue(const UntypedLiteral *value) const {
+  const char *cstr = static_cast<const char*>(castValueToLiteral(value));
+  const std::size_t len = strnlen(cstr, length_);
+  return util::Hash(cstr, len);
+}
+
+bool CharType::checkValuesEqual(const UntypedLiteral *lhs,
+                                const UntypedLiteral *rhs,
+                                const Type &rhs_type) const {
+  return std::strncmp(static_cast<const char*>(castValueToLiteral(lhs)),
+                      static_cast<const char*>(castValueToLiteral(rhs)),
+                      length_);
+}
+
+UntypedLiteral* CharType::cloneValue(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
+
+  const char *cstr = static_cast<const char*>(castValueToLiteral(value));
+  const std::size_t len = strnlen(cstr, length_);
+  char *value_copy = static_cast<char*>(std::malloc(length_));
+  std::memcpy(value_copy, cstr, len);
+  if (len < length_) {
+    value_copy[len] = 0;
+  }
+  return new cpptype(value_copy);
+}
+
+
+TypedValue CharType::marshallValue(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
+
+  const char *cstr = static_cast<const char*>(castValueToLiteral(value));
+  const std::size_t len = std::min(strnlen(cstr, length_) + 1, length_);
+  return TypedValue(kChar, cstr, len).ensureNotReference();
+}
+
+UntypedLiteral* CharType::unmarshallValue(const void *data,
+                                          const std::size_t length) const {
+  const char *cstr = static_cast<const char*>(data);
+  const std::size_t len = std::min(strnlen(cstr, length), length_);
+  char *value = static_cast<char*>(std::malloc(length_));
+  std::memcpy(value, cstr, len);
+  if (len < length_) {
+    value[len] = 0;
+  }
+  return new cpptype(value);
+}
+
 std::string CharType::printValueToString(const UntypedLiteral *value) const {
   DCHECK(value != nullptr);
 
-  const char *cstr = static_cast<const char*>(castValueToLiteral(value).getOutOfLineData());
+  const char *cstr = static_cast<const char*>(castValueToLiteral(value));
   return std::string(cstr, strnlen(cstr, length_));
 }
 
@@ -84,7 +130,7 @@ void CharType::printValueToFile(const UntypedLiteral *value,
                "%*.*s",
                padding,
                static_cast<int>(length_),
-               castValueToLiteral(value).getOutOfLineData());
+               castValueToLiteral(value));
 }
 
 bool CharType::parseTypedValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index 81a32ff..3355243 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -53,6 +53,19 @@ class CharType : public AsciiStringSuperType<kChar> {
     return length_;
   }
 
+  std::size_t hashValue(const UntypedLiteral *value) const override;
+
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override;
+
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override;
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override;
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override;
+
   std::string printValueToString(const UntypedLiteral *value) const override;
 
   void printValueToFile(const UntypedLiteral *value,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
index 3e8045b..d289a1b 100644
--- a/types/GenericValue.hpp
+++ b/types/GenericValue.hpp
@@ -110,6 +110,10 @@ class GenericValue {
     return type_;
   }
 
+  inline TypeID getTypeID() const {
+    return type_.getTypeID();
+  }
+
   inline const UntypedLiteral* getValue() const {
     return value_;
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/MetaType-decl.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType-decl.hpp b/types/MetaType-decl.hpp
index 6942338..80c5956 100644
--- a/types/MetaType-decl.hpp
+++ b/types/MetaType-decl.hpp
@@ -26,14 +26,13 @@
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypeSynthesizer.hpp"
+#include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
 
 namespace quickstep {
 
-class TypedValue;
-
 /** \addtogroup Types
  *  @{
  */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/NumericTypeSafeCoercibility.hpp
----------------------------------------------------------------------
diff --git a/types/NumericTypeSafeCoercibility.hpp b/types/NumericTypeSafeCoercibility.hpp
index 914927c..b8ff876 100644
--- a/types/NumericTypeSafeCoercibility.hpp
+++ b/types/NumericTypeSafeCoercibility.hpp
@@ -21,15 +21,10 @@
 #define QUICKSTEP_TYPES_NUMERIC_TYPE_SAFE_COERCIBILITY_HPP_
 
 #include "utility/meta/TMP.hpp"
+#include "types/TypeRegistrar.hpp"
 
 namespace quickstep {
 
-class BoolType;
-class DoubleType;
-class FloatType;
-class IntType;
-class LongType;
-
 /** \addtogroup Types
  *  @{
  */
@@ -42,7 +37,8 @@ using NumericTypeSafeCoersionPartialOrder = meta::TypeList<
     IsSafelyCoercible<IntType, FloatType>,
     IsSafelyCoercible<IntType, LongType>,
     IsSafelyCoercible<FloatType, DoubleType>,
-    IsSafelyCoercible<LongType, DoubleType>>;
+    IsSafelyCoercible<LongType, DoubleType>
+>;
 
 using NumericTypeSafeCoersionClosure =
     meta::TransitiveClosure<NumericTypeSafeCoersionPartialOrder>;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
index 3a25226..bb6c40d 100644
--- a/types/TypeRegistrar.hpp
+++ b/types/TypeRegistrar.hpp
@@ -48,6 +48,8 @@ using UntypedLiteral = void;
 
 using ArrayLiteral = std::vector<UntypedLiteral*>;
 using MetaTypeLiteral = const Type*;
+using ParInlinePodLiteral = const void*;
+using ParOutOfLinePodLiteral = TypedValue;
 
 template <TypeID type_id>
 struct TypeIDTrait;
@@ -83,9 +85,9 @@ REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval,
 REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval,
               SuperTypeID::kOther, kCxxInlinePod, YearMonthIntervalLit);
 REGISTER_TYPE(CharType, kChar,
-              SuperTypeID::kAsciiString, kParInlinePod, TypedValue);
+              SuperTypeID::kAsciiString, kParInlinePod, ParInlinePodLiteral);
 REGISTER_TYPE(VarCharType, kVarChar,
-              SuperTypeID::kAsciiString, kParOutOfLinePod, TypedValue);
+              SuperTypeID::kAsciiString, kParOutOfLinePod, ParOutOfLinePodLiteral);
 REGISTER_TYPE(TextType, kText,
               SuperTypeID::kOther, kCxxGeneric, std::string);
 REGISTER_TYPE(ArrayType, kArray,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index 0b5842f..d69b1b4 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -175,20 +175,148 @@ class TypeSynthesizePolicy<
 
 
 ////////////////////////////////////////////////////////////////////////////////
-///////////////////////  ParInlinePod & ParOutOfLinePod  ///////////////////////
+/////////////////////////////////  ParInlinePod  ///////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 template <TypeID type_id>
 class TypeSynthesizePolicy<
     type_id,
-    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod ||
-                     TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> : public Type {
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParInlinePod>> : public Type {
+ private:
+  using Trait = TypeIDTrait<type_id>;
+  using TypeClass = typename Trait::TypeClass;
+  using cpptype = typename Trait::cpptype;
+
+  static_assert(std::is_same<cpptype, const void*>::value,
+                "Unexpected cpptype for ParInlinePod.");
+
+ 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);
+    }
+  }
+
+  std::size_t length() const {
+    return length_;
+  }
+
+  std::size_t getHash() const override {
+    return CombineHashes(static_cast<std::size_t>(type_id), length_);
+  }
+
+  std::size_t hashValue(const UntypedLiteral *value) const override {
+    // TODO(refactor-type): Implementation.
+    return TypedValue(type_id_,
+                      *static_cast<const cpptype*>(value),
+                      maximum_byte_length_).getHash();
+  }
+
+  bool checkValuesEqual(const UntypedLiteral *lhs,
+                        const UntypedLiteral *rhs,
+                        const Type &rhs_type) const override {
+    if (!equals(rhs_type)) {
+      return false;
+    }
+    return !std::memcmp(*static_cast<const cpptype*>(lhs),
+                        *static_cast<const cpptype*>(rhs),
+                        maximum_byte_length_);
+  }
+
+  UntypedLiteral* cloneValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
+    void *value_copy = std::malloc(maximum_byte_length_);
+    std::memcpy(value_copy,
+                *static_cast<const cpptype*>(value),
+                maximum_byte_length_);
+    return new cpptype(value_copy);
+  }
+
+  void destroyValue(UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
+    cpptype *value_ptr = static_cast<cpptype*>(value);
+    std::free(const_cast<void*>(*value_ptr));
+    delete value_ptr;
+  }
+
+  TypedValue marshallValue(const UntypedLiteral *value) const override {
+    return TypedValue(type_id_, value, maximum_byte_length_).ensureNotReference();
+  }
+
+  UntypedLiteral* unmarshallValue(const void *data,
+                                  const std::size_t length) const override {
+    DCHECK_EQ(maximum_byte_length_, length);
+    void *value = std::malloc(maximum_byte_length_);
+    std::memcpy(value, data, length);
+    return new cpptype(value);
+  }
+
+ protected:
+  TypeSynthesizePolicy(const bool nullable,
+                       const std::size_t minimum_byte_length,
+                       const std::size_t maximum_byte_length,
+                       const std::size_t length)
+      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+             minimum_byte_length, maximum_byte_length),
+        length_(length) {}
+
+  const std::size_t length_;
+
+  inline const Type& getInstance(const bool nullable) const {
+    return nullable ? InstanceNullable(length_) : InstanceNonNullable(length_);
+  }
+
+  inline void mergeIntoProto(serialization::Type *proto) const {
+    proto->set_length(length_);
+  }
+
+  inline UntypedLiteral* unmarshallTypedValueInl(const TypedValue &value) const {
+    return unmarshallValue(value.getDataPtr(), value.getDataSize());
+  }
+
+  template <typename Functor>
+  inline auto invokeOnUnmarshalledTypedValue(const TypedValue &value,
+                                             const Functor &functor) const {
+    return functor(&value);
+  }
+
+ private:
+  template <bool nullable>
+  inline static const TypeClass& InstanceInternal(const std::size_t length) {
+    static std::unordered_map<size_t, std::unique_ptr<TypeClass>> instance_map;
+    auto imit = instance_map.find(length);
+    if (imit == instance_map.end()) {
+      std::unique_ptr<TypeClass> instance(new TypeClass(nullable, length));
+      imit = instance_map.emplace(length, std::move(instance)).first;
+    }
+    return *(imit->second);
+  }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////  ParOutOfLinePod  /////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+template <TypeID type_id>
+class TypeSynthesizePolicy<
+    type_id,
+    std::enable_if_t<TypeIDTrait<type_id>::kMemoryLayout == kParOutOfLinePod>> : public Type {
  private:
   using Trait = TypeIDTrait<type_id>;
   using TypeClass = typename Trait::TypeClass;
   using cpptype = typename Trait::cpptype;
 
   static_assert(std::is_same<cpptype, TypedValue>::value,
-                "Unexpected cpptype for paramerized PODs.");
+                "Unexpected cpptype for ParOutOfLinePod.");
 
  public:
   static const TypeClass& InstanceNonNullable(const std::size_t length) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/CMakeLists.txt b/types/operations/CMakeLists.txt
index 948d013..caf5f72 100644
--- a/types/operations/CMakeLists.txt
+++ b/types/operations/CMakeLists.txt
@@ -18,6 +18,7 @@
 add_subdirectory(binary_operations)
 add_subdirectory(comparisons)
 add_subdirectory(unary_operations)
+add_subdirectory(utility)
 
 QS_PROTOBUF_GENERATE_CPP(types_operations_Operation_proto_srcs
                          types_operations_Operation_proto_hdrs
@@ -26,7 +27,6 @@ QS_PROTOBUF_GENERATE_CPP(types_operations_Operation_proto_srcs
 # Declare micro-libs:
 add_library(quickstep_types_operations_Operation Operation.cpp Operation.hpp)
 add_library(quickstep_types_operations_OperationFactory OperationFactory.cpp OperationFactory.hpp)
-add_library(quickstep_types_operations_OperationUtil ../../empty_src.cpp OperationUtil.hpp)
 add_library(quickstep_types_operations_OperationSignature OperationSignature.cpp OperationSignature.hpp)
 add_library(quickstep_types_operations_Operation_proto ${types_operations_Operation_proto_srcs})
 
@@ -42,14 +42,14 @@ target_link_libraries(quickstep_types_operations_OperationFactory
                       quickstep_types_TypedValue
                       quickstep_types_operations_Operation
                       quickstep_types_operations_OperationSignature
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
-                      quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
+                      quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctors
+                      quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors
                       quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_types_operations_binaryoperations_BinaryOperationWrapper
-                      quickstep_types_operations_binaryoperations_CMathBinaryOperations
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
-                      quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
-                      quickstep_types_operations_unaryoperations_CMathUnaryOperations
+                      quickstep_types_operations_binaryoperations_CMathBinaryFunctors
+                      quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
+                      quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors
+                      quickstep_types_operations_unaryoperations_CMathUnaryFunctors
                       quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
@@ -58,11 +58,6 @@ target_link_libraries(quickstep_types_operations_OperationFactory
                       quickstep_utility_HashPair
                       quickstep_utility_Macros
                       quickstep_utility_StringUtil)
-target_link_libraries(quickstep_types_operations_OperationUtil
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_types_Type
-                      quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector)
 target_link_libraries(quickstep_types_operations_OperationSignature
                       quickstep_types_TypeID
                       quickstep_types_Type_proto
@@ -79,9 +74,9 @@ add_library(quickstep_types_operations ../../empty_src.cpp)
 target_link_libraries(quickstep_types_operations
                       quickstep_types_operations_Operation
                       quickstep_types_operations_OperationFactory
-                      quickstep_types_operations_OperationUtil
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_Operation_proto
                       quickstep_types_operations_binaryoperations
                       quickstep_types_operations_comparisons
-                      quickstep_types_operations_unaryoperations)
+                      quickstep_types_operations_unaryoperations
+                      quickstep_types_operations_utility)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/OperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.cpp b/types/operations/OperationFactory.cpp
index 253a75d..74cc3c1 100644
--- a/types/operations/OperationFactory.cpp
+++ b/types/operations/OperationFactory.cpp
@@ -31,13 +31,13 @@
 #include "types/TypeUtil.hpp"
 #include "types/operations/Operation.hpp"
 #include "types/operations/OperationSignature.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperations.hpp"
-#include "types/operations/binary_operations/AsciiStringBinaryOperations.hpp"
+#include "types/operations/binary_operations/ArithmeticBinaryFunctors.hpp"
+#include "types/operations/binary_operations/AsciiStringBinaryFunctors.hpp"
 #include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
-#include "types/operations/binary_operations/CMathBinaryOperations.hpp"
-#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp"
-#include "types/operations/unary_operations/AsciiStringUnaryOperations.hpp"
-#include "types/operations/unary_operations/CMathUnaryOperations.hpp"
+#include "types/operations/binary_operations/CMathBinaryFunctors.hpp"
+#include "types/operations/unary_operations/ArithmeticUnaryFunctors.hpp"
+#include "types/operations/unary_operations/AsciiStringUnaryFunctors.hpp"
+#include "types/operations/unary_operations/CMathUnaryFunctors.hpp"
 #include "types/operations/unary_operations/CastOperation.hpp"
 #include "types/operations/unary_operations/DateExtractOperation.hpp"
 #include "types/operations/unary_operations/SubstringOperation.hpp"

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/OperationUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationUtil.hpp b/types/operations/OperationUtil.hpp
deleted file mode 100644
index af23b1c..0000000
--- a/types/operations/OperationUtil.hpp
+++ /dev/null
@@ -1,334 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
-
-#include <cstddef>
-#include <list>
-#include <string>
-#include <type_traits>
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "types/Type.hpp"
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename FunctorT, typename ...SpecArgs>
-struct FunctorSpecializer {
-  template <bool specialize = (sizeof...(SpecArgs) != 0),
-            typename EnableT = void>
-  struct Implementation;
-
-  typedef Implementation<> type;
-};
-
-template <typename FunctorT, typename ...SpecArgs>
-template <bool specialize>
-struct FunctorSpecializer<FunctorT, SpecArgs...>
-    ::Implementation<specialize, std::enable_if_t<specialize>> {
-  template <typename ...FuncArgs>
-  inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) {
-    return functor.template apply<SpecArgs...>(std::forward<FuncArgs>(args)...);
-  }
-  typedef FunctorT FunctorType;
-};
-
-template <typename FunctorT, typename ...SpecArgs>
-template <bool specialize>
-struct FunctorSpecializer<FunctorT, SpecArgs...>
-    ::Implementation<specialize, std::enable_if_t<!specialize>> {
-  template <typename ...FuncArgs>
-  inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) {
-    return functor.apply(std::forward<FuncArgs>(args)...);
-  }
-  typedef FunctorT FunctorType;
-};
-
-template <typename ColumnVectorT>
-struct ColumnVectorValueAccessor {
-  explicit ColumnVectorValueAccessor(const ColumnVectorT &column_vector_in)
-      : column_vector(column_vector_in),
-        length(column_vector.size()) {}
-
-  inline void beginIteration() {
-    pos = static_cast<std::size_t>(-1);
-  }
-
-  inline bool next() {
-    return (++pos) < length;
-  }
-
-  inline std::size_t getNumTuples() const {
-    return length;
-  }
-
-  template <bool nullable>
-  inline const void* getUntypedValue(const attribute_id) const {
-    return column_vector.template getUntypedValue<nullable>(pos);
-  }
-
-  inline TypedValue getTypedValue(const attribute_id) const {
-    return column_vector.getTypedValue(pos);
-  }
-
-  const ColumnVectorT &column_vector;
-  const std::size_t length;
-  std::size_t pos;
-};
-
-template <typename FuncSpec, typename T, typename EnableT = void>
-struct Codegen;
-
-template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kCxxInlinePod>> {
-  using ColumnVectorType = NativeColumnVector;
-  using FunctorSpecializer = FuncSpec;
-
-  using NativeType = typename T::cpptype;
-  using NativeTypeConst = const typename T::cpptype;
-  using NativeTypeConstRef = const NativeType&;
-  using NativeTypeConstPtr = const NativeType*;
-
-  template <typename ArgumentGen>
-  inline static TypedValue ApplyUnaryTypedValue(
-      typename ArgumentGen::NativeTypeConstRef argument,
-      const Type &result_type,
-      const typename FuncSpec::FunctorType &functor) {
-    return TypedValue(FuncSpec::Invoke(functor, argument));
-  }
-
-  template <typename ArgumentGen>
-  inline static void ApplyUnaryColumnVector(
-      const typename ArgumentGen::NativeTypeConstRef argument,
-      const typename FuncSpec::FunctorType &functor,
-      ColumnVectorType *cv) {
-    *static_cast<NativeType *>(cv->getPtrForDirectWrite()) =
-        FuncSpec::Invoke(functor, argument);
-  }
-
-  template <typename LeftGen, typename RightGen>
-  inline static TypedValue ApplyBinaryTypedValue(
-      typename LeftGen::NativeTypeConstRef left,
-      typename RightGen::NativeTypeConstRef right,
-      const Type &result_type,
-      const typename FuncSpec::FunctorType &functor) {
-    return TypedValue(FuncSpec::Invoke(functor, left, right));
-  }
-
-  template <typename LeftGen, typename RightGen>
-  inline static void ApplyBinaryColumnVector(
-      const typename LeftGen::NativeTypeConstRef left,
-      const typename RightGen::NativeTypeConstRef right,
-      const typename FuncSpec::FunctorType &functor,
-      ColumnVectorType *cv) {
-    *static_cast<NativeType *>(cv->getPtrForDirectWrite()) =
-        FuncSpec::Invoke(functor, left, right);
-  }
-
-  template <bool nullable, typename AccessorT>
-  inline static NativeTypeConstPtr GetValuePtr(
-      const AccessorT *accessor,
-      const attribute_id attr_id) {
-    return static_cast<NativeTypeConstPtr>(
-        accessor->template getUntypedValue<nullable>(attr_id));
-  }
-
-  inline static bool IsNull(const NativeType *value) {
-    return value == nullptr;
-  }
-
-  // Dereference: NativeTypeConstPtr& -> const NativeType&
-  inline static const NativeType& Dereference(const NativeType *value) {
-    return *value;
-  }
-
-  inline static const NativeType ToNativeValueConst(const TypedValue &value) {
-    return value.getLiteral<NativeType>();
-  }
-};
-
-template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParInlinePod>> {
-  using ColumnVectorType = NativeColumnVector;
-  using FunctorSpecializer = FuncSpec;
-
-  using NativeType = void*;
-  using NativeTypeConst = const void*;
-  using NativeTypeConstRef = const void*;
-  using NativeTypeConstPtr = const void*;
-
-  template <typename ArgumentGen>
-  inline static TypedValue ApplyUnaryTypedValue(
-      typename ArgumentGen::NativeTypeConstRef argument,
-      const Type &result_type,
-      const typename FuncSpec::FunctorType &functor) {
-    void *result = std::malloc(result_type.maximumByteLength());
-    FuncSpec::Invoke(functor, argument, result);
-    return TypedValue::CreateWithOwnedData(T::kStaticTypeID,
-                                           result,
-                                           result_type.maximumByteLength());
-  }
-
-  template <typename ArgumentGen>
-  inline static void ApplyUnaryColumnVector(
-      const typename ArgumentGen::NativeTypeConstRef argument,
-      const typename FuncSpec::FunctorType &functor,
-      ColumnVectorType *cv) {
-    FuncSpec::Invoke(functor, argument, cv->getPtrForDirectWrite());
-  }
-
-  template <typename LeftGen, typename RightGen>
-  inline static TypedValue ApplyBinaryTypedValue(
-      typename LeftGen::NativeTypeConstRef left,
-      typename RightGen::NativeTypeConstRef right,
-      const Type &result_type,
-      const typename FuncSpec::FunctorType &functor) {
-    void *result = std::malloc(result_type.maximumByteLength());
-    FuncSpec::Invoke(functor, left, right, result);
-    return TypedValue::CreateWithOwnedData(T::kStaticTypeID,
-                                           result,
-                                           result_type.maximumByteLength());
-  }
-
-  template <typename LeftGen, typename RightGen>
-  inline static void ApplyBinaryColumnVector(
-      const typename LeftGen::NativeTypeConstRef left,
-      const typename RightGen::NativeTypeConstRef right,
-      const typename FuncSpec::FunctorType &functor,
-      ColumnVectorType *cv) {
-    FuncSpec::Invoke(functor, left, right, cv->getPtrForDirectWrite());
-  }
-
-  template <bool nullable, typename AccessorT>
-  inline static NativeTypeConstPtr GetValuePtr(
-      const AccessorT *accessor,
-      const attribute_id attr_id) {
-    return accessor->template getUntypedValue<nullable>(attr_id);
-  }
-
-  inline static bool IsNull(const void *value) {
-    return value == nullptr;
-  }
-
-  // Dereference: NativeTypeConstPtr& -> const NativeType&
-  inline static const void* Dereference(const void *value) {
-    return value;
-  }
-
-  inline static const void* ToNativeValueConst(const TypedValue &value) {
-    return value.getDataPtr();
-  }
-};
-
-template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParOutOfLinePod>> {
-  using ColumnVectorType = IndirectColumnVector;
-  using FunctorSpecializer = FuncSpec;
-
-  using NativeType = TypedValue;
-  using NativeTypeConst = const TypedValue;
-  using NativeTypeConstRef = const TypedValue&;
-  using NativeTypeConstPtr = const TypedValue;
-
-  template <typename ArgumentGen>
-  inline static TypedValue ApplyUnaryTypedValue(
-      typename ArgumentGen::NativeTypeConstRef argument,
-      const Type &result_type,
-      const typename FuncSpec::FunctorType &functor) {
-    return FuncSpec::Invoke(functor, argument);
-  }
-
-  template <typename ArgumentGen>
-  inline static void ApplyUnaryColumnVector(
-      const typename ArgumentGen::NativeTypeConstRef argument,
-      const typename FuncSpec::FunctorType &functor,
-      ColumnVectorType *cv) {
-    cv->appendTypedValue(FuncSpec::Invoke(functor, argument));
-  }
-
-  template <typename LeftGen, typename RightGen>
-  inline static TypedValue ApplyBinaryTypedValue(
-      typename LeftGen::NativeTypeConstRef left,
-      typename RightGen::NativeTypeConstRef right,
-      const Type &result_type,
-      const typename FuncSpec::FunctorType &functor) {
-    return FuncSpec::Invoke(functor, left, right);
-  }
-
-  template <typename LeftGen, typename RightGen>
-  inline static void ApplyBinaryColumnVector(
-      const typename LeftGen::NativeTypeConstRef left,
-      const typename RightGen::NativeTypeConstRef right,
-      const typename FuncSpec::FunctorType &functor,
-      ColumnVectorType *cv) {
-    cv->appendTypedValue(FuncSpec::Invoke(functor, left, right));
-  }
-
-  template <bool nullable, typename AccessorT>
-  inline static NativeTypeConstPtr GetValuePtr(
-      const AccessorT *accessor,
-      const attribute_id attr_id) {
-    return accessor->getTypedValue(attr_id);
-  }
-
-  inline static bool IsNull(NativeTypeConstPtr &value) {
-    return value.isNull();
-  }
-
-  // Dereference: NativeTypeConstPtr& -> const NativeType&
-  inline static const NativeType& Dereference(NativeTypeConstPtr &value) {
-    return value;
-  }
-
-  inline static const NativeType& ToNativeValueConst(const TypedValue &value) {
-    return value;
-  }
-};
-
-template <typename ...FunctorTypes>
-struct FunctorPack {
-  template <typename Dispatcher>
-  inline static std::list<OperationPtr> GenerateOperations() {
-    std::vector<std::list<OperationPtr>> op_list_groups =
-        { Dispatcher::template Generate<FunctorTypes>()... };
-
-    std::list<OperationPtr> operations;
-    for (std::list<OperationPtr> &op_list : op_list_groups) {
-      operations.splice(operations.end(), std::move(op_list));
-    }
-    return operations;
-  }
-};
-
-struct OperationPack {
-  virtual std::vector<OperationPtr> generateOperations() = 0;
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/AddBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/AddBinaryOperation.hpp b/types/operations/binary_operations/AddBinaryOperation.hpp
deleted file mode 100644
index 2309563..0000000
--- a/types/operations/binary_operations/AddBinaryOperation.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ADD_BINARY_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ADD_BINARY_OPERATION_HPP_
-
-#include <utility>
-
-#include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-class UncheckedBinaryOperator;
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief The BinaryOperation for addition.
- **/
-class AddBinaryOperation : public ArithmeticBinaryOperation {
- public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const AddBinaryOperation& Instance() {
-    static AddBinaryOperation instance;
-    return instance;
-  }
-
-  bool isCommutative() const override {
-    return true;
-  }
-
-  bool canApplyToTypes(const Type &left,
-                       const Type &right) const override;
-
-  const Type* resultTypeForArgumentTypes(const Type &left,
-                                         const Type &right) const override;
-
-  const Type* resultTypeForPartialArgumentTypes(const Type *left,
-                                                const Type *right) const override;
-
-  bool partialTypeSignatureIsPlausible(const Type *result_type,
-                                       const Type *left_argument_type,
-                                       const Type *right_argument_type) const override;
-
-  std::pair<const Type*, const Type*> pushDownTypeHint(
-      const Type *result_type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &left,
-                            const Type &left_type,
-                            const TypedValue &right,
-                            const Type &right_type) const override;
-
-  UncheckedBinaryOperator* makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                               const Type &right) const override;
-
- private:
-  AddBinaryOperation()
-      : ArithmeticBinaryOperation(BinaryOperationID::kAdd) {
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(AddBinaryOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ADD_BINARY_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp b/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp
new file mode 100644
index 0000000..402bd0a
--- /dev/null
+++ b/types/operations/binary_operations/ArithmeticBinaryFunctors.hpp
@@ -0,0 +1,182 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_FUNCTORS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_FUNCTORS_HPP_
+
+#include <string>
+#include <tuple>
+
+#include "types/DateType.hpp"
+#include "types/DatetimeIntervalType.hpp"
+#include "types/DatetimeLit.hpp"
+#include "types/DatetimeType.hpp"
+#include "types/IntervalLit.hpp"
+#include "types/NumericTypeUnifier.hpp"
+#include "types/Type.hpp"
+#include "types/TypeErrors.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/YearMonthIntervalType.hpp"
+#include "types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp"
+#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename LeftT, typename RightT, typename ResultT,
+          template <typename LeftCppType,
+                    typename RightCppType,
+                    typename EnableT = void> class FunctorOverload,
+          typename FunctorName>
+struct ArithmeticBinaryFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
+  ArithmeticBinaryFunctor() : spec() {}
+  inline typename ResultT::cpptype apply(const typename LeftT::cpptype &left,
+                                         const typename RightT::cpptype &right) const {
+    return spec(left, right);
+  }
+  inline static std::string GetName() {
+    return FunctorName::ToString();
+  }
+  const FunctorOverload<typename LeftT::cpptype,
+                        typename RightT::cpptype> spec;
+};
+
+template <typename LeftT, typename RightT, typename ResultT>
+using AddFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                           AddFunctorOverloads,
+                                           meta::StringLiteral<'+'>>;
+
+template <typename LeftT, typename RightT, typename ResultT>
+using SubtractFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                                SubtractFunctorOverloads,
+                                                meta::StringLiteral<'-'>>;
+
+template <typename LeftT, typename RightT, typename ResultT>
+using MultiplyFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                                MultiplyFunctorOverloads,
+                                                meta::StringLiteral<'*'>>;
+
+template <typename LeftT, typename RightT, typename ResultT>
+using DivideFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                              DivideFunctorOverloads,
+                                              meta::StringLiteral<'/'>>;
+
+template <typename LeftT, typename RightT, typename ResultT>
+using ModuloFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                              ModuloFunctorOverloads,
+                                              meta::StringLiteral<'%'>>;
+
+// ----------------------------------------------------------------------------
+// Packs of functors:
+
+using AddBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        AddFunctor, NumericTypeUnifier>,
+// Date
+    AddFunctor<DateType, YearMonthIntervalType, DateType>,
+    AddFunctor<YearMonthIntervalType, DateType, DateType>,
+// Datetime
+    AddFunctor<DatetimeType, DatetimeIntervalType, DatetimeType>,
+    AddFunctor<DatetimeType, YearMonthIntervalType, DatetimeType>,
+    AddFunctor<DatetimeIntervalType, DatetimeType, DatetimeType>,
+    AddFunctor<YearMonthIntervalType, DatetimeType, DatetimeType>,
+// DatetimeInterval
+    AddFunctor<DatetimeIntervalType, DatetimeIntervalType, DatetimeIntervalType>,
+// YearMonthInterval
+    AddFunctor<YearMonthIntervalType, YearMonthIntervalType, YearMonthIntervalType>
+>;
+
+using SubtractBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        SubtractFunctor, NumericTypeUnifier>,
+// Date
+    SubtractFunctor<DateType, YearMonthIntervalType, DateType>,
+    // TODO(quickstep-team):
+    // Implement SubtractFunctor<DateType, DateType, YearMonthIntervalType>,
+// Datetime
+    SubtractFunctor<DatetimeType, DatetimeIntervalType, DatetimeType>,
+    SubtractFunctor<DatetimeType, YearMonthIntervalType, DatetimeType>,
+    SubtractFunctor<DatetimeType, DatetimeType, DatetimeIntervalType>,
+// DatetimeInterval
+    SubtractFunctor<DatetimeIntervalType, DatetimeIntervalType, DatetimeIntervalType>,
+// YearMonthInterval
+    SubtractFunctor<YearMonthIntervalType, YearMonthIntervalType, YearMonthIntervalType>
+>;
+
+using MultiplyBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        MultiplyFunctor, NumericTypeUnifier>,
+// DatetimeInterval and YearMonthInterval
+    BinaryFunctorCrossProductPack<
+        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        MultiplyFunctor, meta::PairSelectorLeft>,
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
+        MultiplyFunctor, meta::PairSelectorRight>
+>;
+
+using DivideBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        DivideFunctor, NumericTypeUnifier>,
+// DatetimeInterval and YearMonthInterval
+    BinaryFunctorCrossProductPack<
+        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        DivideFunctor, meta::PairSelectorLeft>
+>;
+
+using ModuloBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        ModuloFunctor, NumericTypeUnifier>
+>;
+
+using ArithmeticBinaryFunctorPack = FunctorPack<
+    AddBinaryFunctorPack,
+    SubtractBinaryFunctorPack,
+    MultiplyBinaryFunctorPack,
+    DivideBinaryFunctorPack,
+    ModuloBinaryFunctorPack
+>;
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_FUNCTORS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryOperations.hpp b/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
deleted file mode 100644
index fa4d926..0000000
--- a/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATIONS_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATIONS_HPP_
-
-#include <string>
-#include <tuple>
-
-#include "types/DateType.hpp"
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DatetimeLit.hpp"
-#include "types/DatetimeType.hpp"
-#include "types/IntervalLit.hpp"
-#include "types/NumericTypeUnifier.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp"
-#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
-#include "utility/meta/Common.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename LeftT, typename RightT, typename ResultT,
-          template <typename LeftCppType,
-                    typename RightCppType,
-                    typename EnableT = void> class FunctorOverloadsT,
-          typename FunctorNameT>
-struct ArithmeticBinaryFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
-  ArithmeticBinaryFunctor() : spec() {}
-  inline typename ResultT::cpptype apply(const typename LeftT::cpptype &left,
-                                         const typename RightT::cpptype &right) const {
-    return spec(left, right);
-  }
-  inline static std::string GetName() {
-    return FunctorNameT::ToString();
-  }
-  const FunctorOverloadsT<typename LeftT::cpptype,
-                          typename RightT::cpptype> spec;
-};
-
-template <typename LeftT, typename RightT, typename ResultT>
-using AddFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
-                                           AddFunctorOverloads,
-                                           meta::StringLiteral<'+'>>;
-
-template <typename LeftT, typename RightT, typename ResultT>
-using SubtractFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
-                                                SubtractFunctorOverloads,
-                                                meta::StringLiteral<'-'>>;
-
-template <typename LeftT, typename RightT, typename ResultT>
-using MultiplyFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
-                                                MultiplyFunctorOverloads,
-                                                meta::StringLiteral<'*'>>;
-
-template <typename LeftT, typename RightT, typename ResultT>
-using DivideFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
-                                              DivideFunctorOverloads,
-                                              meta::StringLiteral<'/'>>;
-
-template <typename LeftT, typename RightT, typename ResultT>
-using ModuloFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
-                                              ModuloFunctorOverloads,
-                                              meta::StringLiteral<'%'>>;
-
-// ----------------------------------------------------------------------------
-// Packs of functors:
-
-using AddBinaryFunctorPack = FunctorPack<
-// Numeric
-    BinaryFunctorCrossProductPack<
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        AddFunctor, NumericTypeUnifier>,
-// Date
-    AddFunctor<DateType, YearMonthIntervalType, DateType>,
-    AddFunctor<YearMonthIntervalType, DateType, DateType>,
-// Datetime
-    AddFunctor<DatetimeType, DatetimeIntervalType, DatetimeType>,
-    AddFunctor<DatetimeType, YearMonthIntervalType, DatetimeType>,
-    AddFunctor<DatetimeIntervalType, DatetimeType, DatetimeType>,
-    AddFunctor<YearMonthIntervalType, DatetimeType, DatetimeType>,
-// DatetimeInterval
-    AddFunctor<DatetimeIntervalType, DatetimeIntervalType, DatetimeIntervalType>,
-// YearMonthInterval
-    AddFunctor<YearMonthIntervalType, YearMonthIntervalType, YearMonthIntervalType>
->;
-
-using SubtractBinaryFunctorPack = FunctorPack<
-// Numeric
-    BinaryFunctorCrossProductPack<
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        SubtractFunctor, NumericTypeUnifier>,
-// Date
-    SubtractFunctor<DateType, YearMonthIntervalType, DateType>,
-    // TODO(quickstep-team):
-    // Implement SubtractFunctor<DateType, DateType, YearMonthIntervalType>,
-// Datetime
-    SubtractFunctor<DatetimeType, DatetimeIntervalType, DatetimeType>,
-    SubtractFunctor<DatetimeType, YearMonthIntervalType, DatetimeType>,
-    SubtractFunctor<DatetimeType, DatetimeType, DatetimeIntervalType>,
-// DatetimeInterval
-    SubtractFunctor<DatetimeIntervalType, DatetimeIntervalType, DatetimeIntervalType>,
-// YearMonthInterval
-    SubtractFunctor<YearMonthIntervalType, YearMonthIntervalType, YearMonthIntervalType>
->;
-
-using MultiplyBinaryFunctorPack = FunctorPack<
-// Numeric
-    BinaryFunctorCrossProductPack<
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        MultiplyFunctor, NumericTypeUnifier>,
-// DatetimeInterval and YearMonthInterval
-    BinaryFunctorCrossProductPack<
-        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        MultiplyFunctor, meta::PairSelectorLeft>,
-    BinaryFunctorCrossProductPack<
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
-        MultiplyFunctor, meta::PairSelectorRight>
->;
-
-using DivideBinaryFunctorPack = FunctorPack<
-// Numeric
-    BinaryFunctorCrossProductPack<
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        DivideFunctor, NumericTypeUnifier>,
-// DatetimeInterval and YearMonthInterval
-    BinaryFunctorCrossProductPack<
-        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        DivideFunctor, meta::PairSelectorLeft>
->;
-
-using ModuloBinaryFunctorPack = FunctorPack<
-// Numeric
-    BinaryFunctorCrossProductPack<
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        std::tuple<IntType, LongType, FloatType, DoubleType>,
-        ModuloFunctor, NumericTypeUnifier>
->;
-
-using ArithmeticBinaryFunctorPack = FunctorPack<
-    AddBinaryFunctorPack,
-    SubtractBinaryFunctorPack,
-    MultiplyBinaryFunctorPack,
-    DivideBinaryFunctorPack,
-    ModuloBinaryFunctorPack
->;
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp b/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp
new file mode 100644
index 0000000..5fd54d6
--- /dev/null
+++ b/types/operations/binary_operations/AsciiStringBinaryFunctors.hpp
@@ -0,0 +1,130 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_FUNCTORS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_FUNCTORS_HPP_
+
+#include <cctype>
+#include <cstring>
+#include <string>
+
+#include "types/CharType.hpp"
+#include "types/IntType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/VarCharType.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
+#include "types/port/strnlen.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename LeftT, typename RightT, typename ResultT>
+struct AsciiStringConcatFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
+  explicit AsciiStringConcatFunctor(const LeftT &left, const RightT &right)
+      : left_max_(left.getStringLength()),
+        right_max_(right.getStringLength()),
+        result_max_(left_max_ + right_max_) {}
+  inline void concat(const void *left, const std::size_t l_len,
+                     const void *right, const std::size_t r_len,
+                     void *result) const {
+    char *result_str = static_cast<char*>(result);
+    std::memcpy(result_str, left, l_len);
+    std::memcpy(result_str + l_len, right, r_len);
+
+    const std::size_t result_len = l_len + r_len;
+    if (ResultT::kStaticTypeID == kVarChar || result_len < result_max_) {
+      result_str[result_len] = 0;
+    }
+  }
+  inline void apply(const void *left, const void *right, void *result) const {
+    concat(left, strnlen(static_cast<const char*>(left), left_max_),
+           right, strnlen(static_cast<const char*>(right), right_max_),
+           result);
+  }
+  inline TypedValue apply(const void *left, const TypedValue &right) const {
+    const std::size_t l_len =
+        strnlen(static_cast<const char*>(left), left_max_);
+    const std::size_t r_len =
+        std::strlen(static_cast<const char*>(right.getOutOfLineData()));
+    const std::size_t buf_len = l_len + r_len + 1;
+    char *buf = static_cast<char*>(std::malloc(buf_len));
+    concat(left, l_len, right.getOutOfLineData(), r_len, buf);
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+  inline TypedValue apply(const TypedValue &left, const void *right) const {
+    const std::size_t l_len =
+        std::strlen(static_cast<const char*>(left.getOutOfLineData()));
+    const std::size_t r_len =
+        strnlen(static_cast<const char*>(right), right_max_);;
+    const std::size_t buf_len = l_len + r_len + 1;
+    char *buf = static_cast<char*>(std::malloc(buf_len));
+    concat(left.getOutOfLineData(), l_len, right, r_len, buf);
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+  inline TypedValue apply(const TypedValue &left, const TypedValue &right) const {
+    const std::size_t l_len =
+        std::strlen(static_cast<const char*>(left.getOutOfLineData()));
+    const std::size_t r_len =
+        std::strlen(static_cast<const char*>(right.getOutOfLineData()));
+    const std::size_t buf_len = l_len + r_len + 1;
+    char *buf = static_cast<char*>(std::malloc(buf_len));
+    concat(left.getOutOfLineData(), l_len, right.getOutOfLineData(), r_len, buf);
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+  inline static std::string GetName() {
+    return "+";
+  }
+  inline static const Type* GetResultType(const Type &left, const Type &right) {
+    DCHECK(left.getTypeID() == LeftT::kStaticTypeID);
+    DCHECK(right.getTypeID() == RightT::kStaticTypeID);
+    const std::size_t result_len =
+        static_cast<const LeftT&>(left).getStringLength() +
+            static_cast<const RightT&>(right).getStringLength();
+    const bool is_nullable = left.isNullable() || right.isNullable();
+    if (LeftT::kStaticTypeID == kChar && RightT::kStaticTypeID == kChar) {
+      return &TypeFactory::GetType(kChar, result_len, is_nullable);
+    } else {
+      return &TypeFactory::GetType(kVarChar, result_len, is_nullable);
+    }
+  }
+  const std::size_t left_max_;
+  const std::size_t right_max_;
+  const std::size_t result_max_;
+};
+
+
+using AsciiStringBinaryFunctorPack = FunctorPack<
+// concat
+    AsciiStringConcatFunctor<CharType, CharType, CharType>,
+    AsciiStringConcatFunctor<CharType, VarCharType, VarCharType>,
+    AsciiStringConcatFunctor<VarCharType, CharType, VarCharType>,
+    AsciiStringConcatFunctor<VarCharType, VarCharType, VarCharType>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_FUNCTORS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/AsciiStringBinaryOperations.hpp b/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
deleted file mode 100644
index 7181bc6..0000000
--- a/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_OPERATIONS_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_OPERATIONS_HPP_
-
-#include <cctype>
-#include <cstring>
-#include <string>
-
-#include "types/CharType.hpp"
-#include "types/IntType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/VarCharType.hpp"
-#include "types/operations/OperationUtil.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
-#include "types/port/strnlen.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename LeftT, typename RightT, typename ResultT>
-struct AsciiStringConcatFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
-  explicit AsciiStringConcatFunctor(const LeftT &left, const RightT &right)
-      : left_max_(left.getStringLength()),
-        right_max_(right.getStringLength()),
-        result_max_(left_max_ + right_max_) {}
-  inline void concat(const void *left, const std::size_t l_len,
-                     const void *right, const std::size_t r_len,
-                     void *result) const {
-    char *result_str = static_cast<char*>(result);
-    std::memcpy(result_str, left, l_len);
-    std::memcpy(result_str + l_len, right, r_len);
-
-    const std::size_t result_len = l_len + r_len;
-    if (ResultT::kStaticTypeID == kVarChar || result_len < result_max_) {
-      result_str[result_len] = 0;
-    }
-  }
-  inline void apply(const void *left, const void *right, void *result) const {
-    concat(left, strnlen(static_cast<const char*>(left), left_max_),
-           right, strnlen(static_cast<const char*>(right), right_max_),
-           result);
-  }
-  inline TypedValue apply(const void *left, const TypedValue &right) const {
-    const std::size_t l_len =
-        strnlen(static_cast<const char*>(left), left_max_);
-    const std::size_t r_len =
-        std::strlen(static_cast<const char*>(right.getOutOfLineData()));
-    const std::size_t buf_len = l_len + r_len + 1;
-    char *buf = static_cast<char*>(std::malloc(buf_len));
-    concat(left, l_len, right.getOutOfLineData(), r_len, buf);
-    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
-  }
-  inline TypedValue apply(const TypedValue &left, const void *right) const {
-    const std::size_t l_len =
-        std::strlen(static_cast<const char*>(left.getOutOfLineData()));
-    const std::size_t r_len =
-        strnlen(static_cast<const char*>(right), right_max_);;
-    const std::size_t buf_len = l_len + r_len + 1;
-    char *buf = static_cast<char*>(std::malloc(buf_len));
-    concat(left.getOutOfLineData(), l_len, right, r_len, buf);
-    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
-  }
-  inline TypedValue apply(const TypedValue &left, const TypedValue &right) const {
-    const std::size_t l_len =
-        std::strlen(static_cast<const char*>(left.getOutOfLineData()));
-    const std::size_t r_len =
-        std::strlen(static_cast<const char*>(right.getOutOfLineData()));
-    const std::size_t buf_len = l_len + r_len + 1;
-    char *buf = static_cast<char*>(std::malloc(buf_len));
-    concat(left.getOutOfLineData(), l_len, right.getOutOfLineData(), r_len, buf);
-    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
-  }
-  inline static std::string GetName() {
-    return "+";
-  }
-  inline static const Type* GetResultType(const Type &left, const Type &right) {
-    DCHECK(left.getTypeID() == LeftT::kStaticTypeID);
-    DCHECK(right.getTypeID() == RightT::kStaticTypeID);
-    const std::size_t result_len =
-        static_cast<const LeftT&>(left).getStringLength() +
-            static_cast<const RightT&>(right).getStringLength();
-    const bool is_nullable = left.isNullable() || right.isNullable();
-    if (LeftT::kStaticTypeID == kChar && RightT::kStaticTypeID == kChar) {
-      return &TypeFactory::GetType(kChar, result_len, is_nullable);
-    } else {
-      return &TypeFactory::GetType(kVarChar, result_len, is_nullable);
-    }
-  }
-  const std::size_t left_max_;
-  const std::size_t right_max_;
-  const std::size_t result_max_;
-};
-
-
-using AsciiStringBinaryFunctorPack = FunctorPack<
-// concat
-    AsciiStringConcatFunctor<CharType, CharType, CharType>,
-    AsciiStringConcatFunctor<CharType, VarCharType, VarCharType>,
-    AsciiStringConcatFunctor<VarCharType, CharType, VarCharType>,
-    AsciiStringConcatFunctor<VarCharType, VarCharType, VarCharType>
->;
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/BinaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationWrapper.hpp b/types/operations/binary_operations/BinaryOperationWrapper.hpp
index f5edf52..3a336ee 100644
--- a/types/operations/binary_operations/BinaryOperationWrapper.hpp
+++ b/types/operations/binary_operations/BinaryOperationWrapper.hpp
@@ -35,8 +35,8 @@
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVector.hpp"
 #include "types/operations/OperationSignature.hpp"
-#include "types/operations/OperationUtil.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
 #include "utility/Macros.hpp"
 #include "utility/meta/Common.hpp"
 
@@ -237,9 +237,9 @@ class UncheckedBinaryOperatorWrapperCodegen : public UncheckedBinaryOperator {
   using ResultType = typename FunctorT::ResultType;
 
   using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
-  using LeftGen = Codegen<FuncSpec, LeftType>;
-  using RightGen = Codegen<FuncSpec, RightType>;
-  using ResultGen = Codegen<FuncSpec, ResultType>;
+  using LeftGen = OperationCodegen<FuncSpec, LeftType>;
+  using RightGen = OperationCodegen<FuncSpec, RightType>;
+  using ResultGen = OperationCodegen<FuncSpec, ResultType>;
 
   template <bool left_nullable, bool right_nullable>
   struct Implementation;


[03/38] incubator-quickstep git commit: Updates to casts

Posted by ji...@apache.org.
Updates to casts


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/4bf0857c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/4bf0857c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/4bf0857c

Branch: refs/heads/refactor-type
Commit: 4bf0857c57ef2f9fed8fad5a35255b471341918c
Parents: f9e32e6
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Tue Oct 10 13:20:17 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 expressions/ExpressionFactories.cpp             |   4 +-
 .../aggregation/AggregateFunctionAvg.cpp        |  13 +-
 .../aggregation/AggregateFunctionSum.cpp        |   4 +-
 .../aggregation/AggregationHandleAvg.cpp        |  16 +-
 .../aggregation/AggregationHandleSum.cpp        |   8 +-
 expressions/scalar/ScalarCaseExpression.cpp     |   8 +-
 .../WindowAggregateFunctionAvg.cpp              |   3 +-
 .../WindowAggregateFunctionSum.cpp              |   2 +-
 .../WindowAggregationHandle.cpp                 |   4 +-
 .../WindowAggregationHandleAvg.cpp              |   4 +-
 query_optimizer/expressions/CMakeLists.txt      |  11 +-
 query_optimizer/expressions/Cast.cpp            |   2 +-
 query_optimizer/resolver/Resolver.cpp           |  80 ++-
 query_optimizer/rules/Partition.cpp             |   2 +-
 .../rules/ReuseAggregateExpressions.cpp         |   2 +-
 storage/SMAIndexSubBlock.cpp                    |   7 +-
 storage/WindowAggregationOperationState.cpp     |   4 +-
 types/ArrayLit.hpp                              | 112 ++++
 types/ArrayType.cpp                             |  30 +-
 types/ArrayType.hpp                             |  10 +-
 types/AsciiStringSuperType.hpp                  |   8 -
 types/BoolType.hpp                              |   2 +-
 types/CMakeLists.txt                            |   7 +-
 types/CharType.hpp                              |   2 +-
 types/DateType.hpp                              |   2 +-
 types/DatetimeIntervalType.hpp                  |   2 +-
 types/DatetimeType.hpp                          |   3 +-
 types/DoubleType.hpp                            |   2 +-
 types/FloatType.hpp                             |   2 +-
 types/IntType.hpp                               |   2 +-
 types/LongType.hpp                              |   2 +-
 types/MetaType-decl.hpp                         |   2 +-
 types/MetaType.cpp                              |   2 +-
 types/NullType.hpp                              |   2 +-
 types/NumericSuperType.hpp                      |   5 -
 types/TextType.hpp                              |   2 +-
 types/Type.cpp                                  |  22 +-
 types/Type.hpp                                  |   9 +-
 types/Type.proto                                |   4 +-
 types/TypeRegistrar.hpp                         |  16 +-
 types/TypeSynthesizer.hpp                       |  34 +-
 types/VarCharType.hpp                           |   2 +-
 types/YearMonthIntervalType.hpp                 |   2 +-
 types/containers/CMakeLists.txt                 |   1 +
 types/containers/ColumnVector.cpp               |  43 +-
 types/containers/ColumnVector.hpp               | 124 +++-
 types/containers/ColumnVectorUtil.hpp           |   6 +-
 types/containers/ColumnVectorsValueAccessor.hpp |  41 +-
 types/operations/CMakeLists.txt                 |   5 +-
 types/operations/OperationFactory.cpp           | 160 ++++-
 types/operations/OperationFactory.hpp           | 138 ++--
 .../ArithmeticBinaryFunctors.hpp                |   2 +-
 .../AsciiStringBinaryFunctors.hpp               |  24 +-
 .../BinaryOperationSynthesizer.hpp              | 660 +++++++++++++++++++
 .../BinaryOperationWrapper.hpp                  | 629 ------------------
 .../operations/binary_operations/CMakeLists.txt |  15 +-
 .../binary_operations/CMathBinaryFunctors.hpp   |   2 +-
 .../operations/comparisons/BasicComparison.hpp  |  23 +-
 .../comparisons/LiteralComparators-inl.hpp      |  10 +-
 .../ArithmeticUnaryFunctors.hpp                 |   2 +-
 .../AsciiStringUnaryFunctors.hpp                |   2 +-
 .../operations/unary_operations/CMakeLists.txt  |  29 +-
 .../unary_operations/CMathUnaryFunctors.hpp     |   2 +-
 .../unary_operations/CastFunctorOverloads.hpp   | 195 +++---
 .../unary_operations/CastOperation.cpp          |   6 +-
 .../unary_operations/CastOperation.hpp          |   4 +-
 .../unary_operations/DateExtractOperation.cpp   |  20 +-
 .../UnaryOperationSynthesizer.hpp               | 273 ++++++++
 .../unary_operations/UnaryOperationWrapper.hpp  | 250 -------
 types/operations/utility/CMakeLists.txt         |  11 +-
 types/operations/utility/CastUtil.cpp           |  66 ++
 types/operations/utility/CastUtil.hpp           |  50 ++
 .../utility/OperationSynthesizeUtil.hpp         | 184 +++++-
 utility/Cast.hpp                                |   7 +-
 utility/meta/Common.hpp                         |  20 +-
 utility/meta/TypeList.hpp                       |  32 +-
 utility/meta/TypeListMetaFunctions.hpp          |  11 +-
 77 files changed, 2168 insertions(+), 1341 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/ExpressionFactories.cpp
----------------------------------------------------------------------
diff --git a/expressions/ExpressionFactories.cpp b/expressions/ExpressionFactories.cpp
index f8913ba..2dd5124 100644
--- a/expressions/ExpressionFactories.cpp
+++ b/expressions/ExpressionFactories.cpp
@@ -181,7 +181,7 @@ Scalar* ScalarFactory::ReconstructFromProto(const serialization::Scalar &proto,
               proto.GetExtension(serialization::ScalarUnaryExpression::op_signature));
       return new ScalarUnaryExpression(
           op_signature,
-          OperationFactory::Instance().getUnaryOperation(op_signature),
+          OperationFactory::GetUnaryOperation(op_signature),
           ReconstructFromProto(proto.GetExtension(serialization::ScalarUnaryExpression::operand), database),
           std::make_shared<std::vector<TypedValue>>(std::move(static_arguments)));
     }
@@ -199,7 +199,7 @@ Scalar* ScalarFactory::ReconstructFromProto(const serialization::Scalar &proto,
               proto.GetExtension(serialization::ScalarBinaryExpression::op_signature));
       return new ScalarBinaryExpression(
           op_signature,
-          OperationFactory::Instance().getBinaryOperation(op_signature),
+          OperationFactory::GetBinaryOperation(op_signature),
           ReconstructFromProto(
               proto.GetExtension(serialization::ScalarBinaryExpression::left_operand), database),
           ReconstructFromProto(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/aggregation/AggregateFunctionAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionAvg.cpp b/expressions/aggregation/AggregateFunctionAvg.cpp
index b2b99c7..3acdb5b 100644
--- a/expressions/aggregation/AggregateFunctionAvg.cpp
+++ b/expressions/aggregation/AggregateFunctionAvg.cpp
@@ -41,14 +41,11 @@ bool AggregateFunctionAvg::canApplyToTypes(
 
   // Argument must be addable and divisible.
   const Type &type = *argument_types.front();
-  if (!OperationFactory::Instance()
-          .getBinaryOperation("+", {type.getTypeID(), type.getTypeID()})
-              ->canApplyTo(type, type)) {
+  if (!OperationFactory::CanApplyAddOperation(type, type)) {
     return false;
   }
-  return OperationFactory::Instance()
-      .getBinaryOperation("/", {type.getTypeID(), kDouble})
-          ->canApplyTo(type, TypeFactory::GetType(kDouble));
+  return OperationFactory::CanApplyDivideOperation(
+      type, TypeFactory::GetType(kDouble));
 }
 
 const Type* AggregateFunctionAvg::resultTypeForArgumentTypes(
@@ -71,8 +68,8 @@ const Type* AggregateFunctionAvg::resultTypeForArgumentTypes(
       break;
   }
 
-  return OperationFactory::Instance()
-      .getBinaryOperation("/", {sum_type->getTypeID(), kDouble})
+  return OperationFactory::GetDivideOperation(
+      sum_type->getTypeID(), kDouble)
           ->getResultType(*sum_type, TypeFactory::GetType(kDouble));
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/aggregation/AggregateFunctionSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionSum.cpp b/expressions/aggregation/AggregateFunctionSum.cpp
index 11b33c0..b8c94b3 100644
--- a/expressions/aggregation/AggregateFunctionSum.cpp
+++ b/expressions/aggregation/AggregateFunctionSum.cpp
@@ -41,9 +41,7 @@ bool AggregateFunctionSum::canApplyToTypes(
 
   // Argument must be addable.
   const Type &type = *argument_types.front();
-  return OperationFactory::Instance()
-      .getBinaryOperation("+", {type.getTypeID(), type.getTypeID()})
-          ->canApplyTo(type, type);
+  return OperationFactory::CanApplyAddOperation(type, type);
 }
 
 const Type* AggregateFunctionSum::resultTypeForArgumentTypes(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/aggregation/AggregationHandleAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleAvg.cpp b/expressions/aggregation/AggregationHandleAvg.cpp
index 1324fd8..6ec59c7 100644
--- a/expressions/aggregation/AggregationHandleAvg.cpp
+++ b/expressions/aggregation/AggregationHandleAvg.cpp
@@ -67,22 +67,22 @@ AggregationHandleAvg::AggregationHandleAvg(const Type &type)
 
   // Make operators to do arithmetic:
   // Add operator for summing argument values.
-  fast_add_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("+", {type_precision_id, argument_type_.getTypeID()})
+  fast_add_operator_.reset(
+      OperationFactory::GetAddOperation(type_precision_id, argument_type_.getTypeID())
           ->makeUncheckedBinaryOperator(sum_type, argument_type_));
   // Add operator for merging states.
-  merge_add_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("+", {type_precision_id, type_precision_id})
+  merge_add_operator_.reset(
+      OperationFactory::GetAddOperation(type_precision_id, type_precision_id)
           ->makeUncheckedBinaryOperator(sum_type, sum_type));
   // Divide operator for dividing sum by count to get final average.
-  divide_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("/", {type_precision_id, kDouble})
+  divide_operator_.reset(
+      OperationFactory::GetDivideOperation(type_precision_id, kDouble)
           ->makeUncheckedBinaryOperator(sum_type, TypeFactory::GetType(kDouble)));
 
   // Result is nullable, because AVG() over 0 values (or all NULL values) is
   // NULL.
-  result_type_ = &OperationFactory::Instance()
-      .getBinaryOperation("/", {type_precision_id, kDouble})
+  result_type_ =
+      &OperationFactory::GetDivideOperation(type_precision_id, kDouble)
           ->getResultType(sum_type, TypeFactory::GetType(kDouble))
               ->getNullableVersion();
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/aggregation/AggregationHandleSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleSum.cpp b/expressions/aggregation/AggregationHandleSum.cpp
index c7ee776..9fdbab7 100644
--- a/expressions/aggregation/AggregationHandleSum.cpp
+++ b/expressions/aggregation/AggregationHandleSum.cpp
@@ -66,12 +66,12 @@ AggregationHandleSum::AggregationHandleSum(const Type &type)
 
   // Make operators to do arithmetic:
   // Add operator for summing argument values.
-  fast_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("+", {type_precision_id, argument_type_.getTypeID()})
+  fast_operator_.reset(
+      OperationFactory::GetAddOperation(type_precision_id, argument_type_.getTypeID())
           ->makeUncheckedBinaryOperator(sum_type, argument_type_));
   // Add operator for merging states.
-  merge_operator_.reset(OperationFactory::Instance()
-      .getBinaryOperation("+", {type_precision_id, type_precision_id})
+  merge_operator_.reset(
+      OperationFactory::GetAddOperation(type_precision_id, type_precision_id)
           ->makeUncheckedBinaryOperator(sum_type, sum_type));
 
   // Result is nullable, because SUM() over 0 values (or all NULL values) is

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/scalar/ScalarCaseExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarCaseExpression.cpp b/expressions/scalar/ScalarCaseExpression.cpp
index 6fd2c0f..4a0cc72 100644
--- a/expressions/scalar/ScalarCaseExpression.cpp
+++ b/expressions/scalar/ScalarCaseExpression.cpp
@@ -470,7 +470,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors(
     for (std::vector<std::unique_ptr<TupleIdSequence>>::size_type case_idx = 0;
          case_idx < case_matches.size();
          ++case_idx) {
-      DCHECK(case_results[case_idx]->isNative());
+      DCHECK(case_results[case_idx]->getImplementation() == ColumnVector::kNative);
       if (!case_matches[case_idx]->empty()) {
         MultiplexNativeColumnVector(
             source_sequence,
@@ -481,7 +481,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors(
     }
 
     if (else_result != nullptr) {
-      DCHECK(else_result->isNative());
+      DCHECK(else_result->getImplementation() == ColumnVector::kNative);
       DCHECK(!else_matches.empty());
       MultiplexNativeColumnVector(source_sequence,
                                   else_matches,
@@ -498,7 +498,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors(
     for (std::vector<std::unique_ptr<TupleIdSequence>>::size_type case_idx = 0;
          case_idx < case_matches.size();
          ++case_idx) {
-      DCHECK(!case_results[case_idx]->isNative());
+      DCHECK(case_results[case_idx]->getImplementation() == ColumnVector::kIndirect);
       if (!case_matches[case_idx]->empty()) {
         MultiplexIndirectColumnVector(
             source_sequence,
@@ -509,7 +509,7 @@ ColumnVectorPtr ScalarCaseExpression::multiplexColumnVectors(
     }
 
     if (else_result != nullptr) {
-      DCHECK(!else_result->isNative());
+      DCHECK(else_result->getImplementation() == ColumnVector::kIndirect);
       DCHECK(!else_matches.empty());
       MultiplexIndirectColumnVector(source_sequence,
                                     else_matches,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp b/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
index a70a8bc..fcd737e 100644
--- a/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
+++ b/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
@@ -39,6 +39,7 @@ bool WindowAggregateFunctionAvg::canApplyToTypes(
   }
 
   // Argument must be addable and divisible.
+  // TODO(refactor-type): Fix this.
 //  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
 //             .canApplyTo(*argument_types.front(), *argument_types.front()) &&
 //         BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
@@ -66,7 +67,7 @@ const Type* WindowAggregateFunctionAvg::resultTypeForArgumentTypes(
       break;
   }
 
-// TODO
+  // TODO(refactor-type): Fix this.
 //  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
 //             .getResultType(*sum_type, TypeFactory::GetType(kDouble));
   return nullptr;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregateFunctionSum.cpp b/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
index e383c63..09bc4e9 100644
--- a/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
+++ b/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
@@ -39,7 +39,7 @@ bool WindowAggregateFunctionSum::canApplyToTypes(
   }
 
   // Argument must be addable.
-// TODO
+  // TODO(refactor-type): Fix this.
 //  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
 //             .canApplyTo(*argument_types.front(), *argument_types.front());
   return false;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/window_aggregation/WindowAggregationHandle.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregationHandle.cpp b/expressions/window_aggregation/WindowAggregationHandle.cpp
index 7621726..e327a4f 100644
--- a/expressions/window_aggregation/WindowAggregationHandle.cpp
+++ b/expressions/window_aggregation/WindowAggregationHandle.cpp
@@ -82,8 +82,8 @@ WindowAggregationHandle::WindowAggregationHandle(
         TypeFactory::GetUnifyingType(*first_order_key_type, long_type);
 
     range_add_operator_.reset(
-        OperationFactory::Instance().getBinaryOperation(
-            "+", {first_order_key_type->getTypeID(), kLong}, 0)
+        OperationFactory::GetAddOperation(
+            first_order_key_type->getTypeID(), kLong)
                 ->makeUncheckedBinaryOperator(*first_order_key_type, long_type));
     range_comparator_.reset(
         ComparisonFactory::GetComparison(ComparisonID::kLessOrEqual)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregationHandleAvg.cpp b/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
index 3539d03..10272a9 100644
--- a/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
+++ b/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
@@ -69,7 +69,7 @@ WindowAggregationHandleAvg::WindowAggregationHandleAvg(
 
   sum_type_ = &(TypeFactory::GetType(type_id));
 
-// TODO
+  LOG(FATAL) << "TODO(refactor-type)";
 //  // Result is nullable, because AVG() over 0 values (or all NULL values) is
 //  // NULL.
 //  result_type_
@@ -98,7 +98,7 @@ ColumnVector* WindowAggregationHandleAvg::calculate(
     ColumnVectorsValueAccessor *tuple_accessor,
     const std::vector<ColumnVector*> &arguments) const {
   DCHECK_EQ(1u, arguments.size());
-  DCHECK(arguments[0]->isNative());
+  DCHECK(arguments[0]->getImplementation() == ColumnVector::kNative);
   DCHECK_EQ(static_cast<std::size_t>(tuple_accessor->getNumTuples()),
             static_cast<const NativeColumnVector*>(arguments[0])->size());
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index b51a0a8..889c450 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -113,8 +113,11 @@ target_link_libraries(quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_ExpressionType
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_types_MetaType
                       quickstep_types_Type
-                      quickstep_types_operations_unaryoperations_CastOperation
+                      quickstep_types_operations_OperationFactory
+                      quickstep_types_operations_OperationSignature
+                      quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_utility_HashPair
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_CommonSubexpression
@@ -255,6 +258,8 @@ target_link_libraries(quickstep_queryoptimizer_expressions_Scalar
                       glog
                       quickstep_queryoptimizer_expressions_ExprId
                       quickstep_queryoptimizer_expressions_Expression
+                      quickstep_types_GenericValue
+                      quickstep_types_TypedValue
                       quickstep_utility_HashError
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_ScalarLiteral
@@ -267,8 +272,8 @@ target_link_libraries(quickstep_queryoptimizer_expressions_ScalarLiteral
                       quickstep_queryoptimizer_expressions_ExpressionType
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_types_GenericValue
                       quickstep_types_Type
-                      quickstep_types_TypedValue
                       quickstep_utility_HashPair
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_SearchedCase
@@ -327,6 +332,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions_UnaryExpression
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
                       quickstep_queryoptimizer_expressions_ScalarLiteral
+                      quickstep_types_GenericValue
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_utility_HashPair
@@ -352,6 +358,7 @@ target_link_libraries(quickstep_queryoptimizer_expressions
                       quickstep_queryoptimizer_expressions_Alias
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_BinaryExpression
+                      quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_CommonSubexpression
                       quickstep_queryoptimizer_expressions_ComparisonExpression
                       quickstep_queryoptimizer_expressions_Exists

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/expressions/Cast.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Cast.cpp b/query_optimizer/expressions/Cast.cpp
index 6b2015f..2315f92 100644
--- a/query_optimizer/expressions/Cast.cpp
+++ b/query_optimizer/expressions/Cast.cpp
@@ -61,7 +61,7 @@ ExpressionPtr Cast::copyWithNewChildren(
       OperationSignature::Create(
           "cast", {operand_->getValueType().getTypeID(), kMetaType}, 1);
   const UnaryOperationPtr cast_operation =
-      OperationFactory::Instance().getUnaryOperation(op_signature);
+      OperationFactory::GetUnaryOperation(op_signature);
 
   std::vector<TypedValue> meta_type_value =
       { GenericValue::CreateWithLiteral(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 40b460d..b3e8c2c 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -1021,19 +1021,15 @@ L::LogicalPtr Resolver::resolveInsertSelection(
       cast_expressions.emplace_back(selection_attributes[aid]);
     } else {
       // TODO(jianqiao): implement Cast operation for non-numeric types.
-      if (destination_type.getSuperTypeID() == SuperTypeID::kNumeric &&
-          selection_type.getSuperTypeID() == SuperTypeID::kNumeric &&
-          destination_type.isSafelyCoercibleFrom(selection_type)) {
+      if (destination_type.isSafelyCoercibleFrom(selection_type)) {
         // Add cast operation
-//        const E::AttributeReferencePtr attr = selection_attributes[aid];
-//        const E::ExpressionPtr cast_expr =
-//            E::Cast::Create(attr, destination_type);
-//        cast_expressions.emplace_back(
-//            E::Alias::Create(context_->nextExprId(),
-//                             cast_expr,
-//                             attr->attribute_name(),
-//                             attr->attribute_alias()));
-        THROW_SQL_ERROR_AT(insert_statement.relation_name()) << "TODO: not handled";
+        const E::AttributeReferencePtr attr = selection_attributes[aid];
+        const E::ExpressionPtr cast_expr = E::Cast::Create(attr, destination_type);
+        cast_expressions.emplace_back(
+            E::Alias::Create(context_->nextExprId(),
+                             cast_expr,
+                             attr->attribute_name(),
+                             attr->attribute_alias()));
       } else {
         THROW_SQL_ERROR_AT(insert_statement.relation_name())
             << "The assigned value for the column "
@@ -1166,9 +1162,8 @@ L::LogicalPtr Resolver::resolveUpdate(
     // Coerce the assignment expression if its Type is not equal to that of the
     // assigned attribute.
     if (!assignment_expression->getValueType().equals(attribute->getValueType())) {
-//      assignment_expression =
-//          E::Cast::Create(assignment_expression, attribute->getValueType());
-      THROW_SQL_ERROR_AT(&assignment) << "TODO: not handled";
+      assignment_expression =
+          E::Cast::Create(assignment_expression, attribute->getValueType());
     }
     if (assignee_ids.find(attribute->id()) != assignee_ids.end()) {
       THROW_SQL_ERROR_AT(&assignment) << "Multiple assignments to the column "
@@ -1652,12 +1647,11 @@ L::LogicalPtr Resolver::resolveSetOperations(
       if (possible_type.equals(current_type)) {
         cast_expressions.emplace_back(current_attr);
       } else {
-//        cast_expressions.emplace_back(
-//            E::Alias::Create(context_->nextExprId(),
-//                             E::Cast::Create(current_attr, possible_type),
-//                             current_attr->attribute_name(),
-//                             current_attr->attribute_alias()));
-        LOG(FATAL) << "TODO: not handled";
+        cast_expressions.emplace_back(
+            E::Alias::Create(context_->nextExprId(),
+                             E::Cast::Create(current_attr, possible_type),
+                             current_attr->attribute_name(),
+                             current_attr->attribute_alias()));
       }
     }
     resolved_operations[opid] = L::Project::Create(resolved_operations[opid], cast_expressions);
@@ -2555,11 +2549,19 @@ E::ScalarPtr Resolver::resolveExpression(
     case ParseExpression::kTypeCast: {
       const ParseTypeCast &parse_type_cast =
           static_cast<const ParseTypeCast&>(parse_expression);
-      return E::Cast::Create(
+      const E::ScalarPtr operand =
           resolveExpression(parse_type_cast.operand(),
                             nullptr /* type_hint */,
-                            expression_resolution_info),
-          resolveDataType(parse_type_cast.target_type()));
+                            expression_resolution_info);
+      const Type &target_type =
+          resolveDataType(parse_type_cast.target_type());
+      if (!OperationFactory::CanApplyCastOperation(operand->getValueType(),
+                                                   target_type)) {
+        THROW_SQL_ERROR_AT(&parse_type_cast)
+            << "Cannot cast from " << operand->getValueType().getName()
+            << " type to " << target_type.getName() << " type";
+      }
+      return E::Cast::Create(operand, target_type);
     }
     default:
       LOG(FATAL) << "Unknown scalar type: "
@@ -2580,7 +2582,7 @@ E::ScalarPtr Resolver::resolveArray(
     return E::ScalarLiteral::Create(
         GenericValue::CreateWithLiteral(
             ArrayType::InstanceNonNullable({meta_null_type_value}),
-            ArrayLiteral()));
+            ArrayLit(NullType::InstanceNullable())));
   } else {
     // Currently we only support homogeneous array with literal values.
     std::vector<E::ScalarLiteralPtr> literals;
@@ -2617,9 +2619,9 @@ E::ScalarPtr Resolver::resolveArray(
         ArrayType::InstanceNonNullable({meta_element_type_value});
 
     // NOTE(refactor-type): Possibly memory leak region, noexcept.
-    std::unique_ptr<ArrayLiteral> array_literal = std::make_unique<ArrayLiteral>();
+    std::unique_ptr<ArrayLit> array_literal = std::make_unique<ArrayLit>(*element_type);
     for (const auto &literal : literals) {
-      array_literal->emplace_back(
+      array_literal->push_back(
           element_type->cloneValue(literal->value().getValue()));
     }
     return E::ScalarLiteral::Create(
@@ -2715,15 +2717,13 @@ E::ScalarPtr Resolver::resolveSearchedCaseExpression(
   // Cast all the result expressions to the same type.
   for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) {
     if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-//      conditional_result_expression =
-//          E::Cast::Create(conditional_result_expression, *result_data_type);
-      LOG(FATAL) << "TODO: not handled";
+      conditional_result_expression =
+          E::Cast::Create(conditional_result_expression, *result_data_type);
     }
   }
   if (else_result_expression != nullptr
       && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-//    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
-    LOG(FATAL) << "TODO: not handled";
+    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
   }
 
   if (else_result_expression == nullptr) {
@@ -2861,15 +2861,13 @@ E::ScalarPtr Resolver::resolveSimpleCaseExpression(
   // Cast all the result expressions to the same type.
   for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) {
     if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-//      conditional_result_expression =
-//          E::Cast::Create(conditional_result_expression, *result_data_type);
-      LOG(FATAL) << "TODO: not handled";
+      conditional_result_expression =
+          E::Cast::Create(conditional_result_expression, *result_data_type);
     }
   }
   if (else_result_expression != nullptr
       && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-//    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
-    LOG(FATAL) << "TODO: not handled";
+    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
   }
 
   if (else_result_expression == nullptr) {
@@ -2913,7 +2911,7 @@ E::ScalarPtr Resolver::resolveScalarFunction(
   std::shared_ptr<const std::vector<GenericValue>> coerced_static_arguments;
   std::string message;
   const OperationSignaturePtr op_signature =
-      OperationFactory::Instance().resolveOperation(
+      OperationFactory::ResolveOperation(
           function_name,
           std::make_shared<const std::vector<const Type*>>(std::move(argument_types)),
           std::make_shared<const std::vector<GenericValue>>(std::move(static_arguments)),
@@ -2933,8 +2931,7 @@ E::ScalarPtr Resolver::resolveScalarFunction(
   // TODO: add cast if neccessary.
   (void)coerced_argument_types;
 
-  const OperationPtr operation =
-      OperationFactory::Instance().getOperation(op_signature);
+  const OperationPtr operation = OperationFactory::GetOperation(op_signature);
   switch (operation->getOperationSuperTypeID()) {
     case Operation::kUnaryOperation:
       return E::UnaryExpression::Create(
@@ -3005,8 +3002,7 @@ E::ScalarPtr Resolver::resolveFunctionCall(
     }
   }
 
-  if (OperationFactory::Instance().hasOperation(function_name,
-                                                resolved_arguments.size())) {
+  if (OperationFactory::HasOperation(function_name, resolved_arguments.size())) {
     E::ScalarPtr scalar = resolveScalarFunction(parse_function_call,
                                                 function_name,
                                                 resolved_arguments,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/rules/Partition.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/Partition.cpp b/query_optimizer/rules/Partition.cpp
index d55d296..0e21b98 100644
--- a/query_optimizer/rules/Partition.cpp
+++ b/query_optimizer/rules/Partition.cpp
@@ -416,7 +416,7 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
                   get<2>(avg_recompute_expression)->getValueType().getTypeID() },
                 0);
         const BinaryOperationPtr divide_op =
-            OperationFactory::Instance().getBinaryOperation(op_sig);
+            OperationFactory::GetBinaryOperation(op_sig);
         const E::BinaryExpressionPtr new_avg_expr =
             E::BinaryExpression::Create(op_sig,
                                         divide_op,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/query_optimizer/rules/ReuseAggregateExpressions.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/ReuseAggregateExpressions.cpp b/query_optimizer/rules/ReuseAggregateExpressions.cpp
index d63715a..65832e7 100644
--- a/query_optimizer/rules/ReuseAggregateExpressions.cpp
+++ b/query_optimizer/rules/ReuseAggregateExpressions.cpp
@@ -324,7 +324,7 @@ P::PhysicalPtr ReuseAggregateExpressions::applyToNode(
               OperationSignature::Create("/", operand_tids, 0);
 
           const BinaryOperationPtr &divide_op =
-              OperationFactory::Instance().getBinaryOperation(op_sig);
+              OperationFactory::GetBinaryOperation(op_sig);
           const E::BinaryExpressionPtr avg_expr =
               E::BinaryExpression::Create(op_sig,
                                           divide_op,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/storage/SMAIndexSubBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/SMAIndexSubBlock.cpp b/storage/SMAIndexSubBlock.cpp
index 5a8a747..2f7c474 100644
--- a/storage/SMAIndexSubBlock.cpp
+++ b/storage/SMAIndexSubBlock.cpp
@@ -358,10 +358,9 @@ SMAIndexSubBlock::SMAIndexSubBlock(const TupleStorageSubBlock &tuple_store,
       TypeID attr_sum_typeid = sma_internal::getTypeForSum(attr_typeid);
       if (add_operations_.elementIsNullAt(attr_typeid)) {
         add_operations_.replaceElement(attr_typeid,
-            OperationFactory::Instance().getBinaryOperation(
-                "+", {attr_typeid, attr_sum_typeid})
-                    ->makeUncheckedBinaryOperator(TypeFactory::GetType(attr_typeid),
-                                                  TypeFactory::GetType(attr_sum_typeid)));
+            OperationFactory::GetAddOperation(attr_typeid, attr_sum_typeid)
+                ->makeUncheckedBinaryOperator(TypeFactory::GetType(attr_typeid),
+                                              TypeFactory::GetType(attr_sum_typeid)));
       }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/storage/WindowAggregationOperationState.cpp
----------------------------------------------------------------------
diff --git a/storage/WindowAggregationOperationState.cpp b/storage/WindowAggregationOperationState.cpp
index 30d91db..2b63a6c 100644
--- a/storage/WindowAggregationOperationState.cpp
+++ b/storage/WindowAggregationOperationState.cpp
@@ -261,7 +261,7 @@ void WindowAggregationOperationState::windowAggregateBlocks(
 
         for (std::size_t attr_id = 0; attr_id < attribute_vecs.size(); ++attr_id) {
           ColumnVector *attr_vec = attribute_vecs[attr_id];
-          if (attr_vec->isNative()) {
+          if (attr_vec->getImplementation() == ColumnVector::kNative) {
             static_cast<NativeColumnVector*>(attr_vec)->appendTypedValue(
                 tuple_accessor->getTypedValue(attr_id));
           } else {
@@ -274,7 +274,7 @@ void WindowAggregationOperationState::windowAggregateBlocks(
              argument_idx < argument_vecs.size();
              ++argument_idx) {
           ColumnVector *argument = argument_vecs[argument_idx];
-          if (argument->isNative()) {
+          if (argument->getImplementation() == ColumnVector::kNative) {
             static_cast<NativeColumnVector*>(argument)->appendTypedValue(
                 argument_accessor->getTypedValue(argument_idx));
           } else {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/ArrayLit.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayLit.hpp b/types/ArrayLit.hpp
new file mode 100644
index 0000000..b5d3548
--- /dev/null
+++ b/types/ArrayLit.hpp
@@ -0,0 +1,112 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_ARRAY_LIT_HPP_
+#define QUICKSTEP_TYPES_ARRAY_LIT_HPP_
+
+#include <cstddef>
+#include <vector>
+
+#include "types/Type.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+typedef void UntypedLiteral;
+
+class ArrayLit {
+ public:
+  using const_iterator = std::vector<UntypedLiteral*>::const_iterator;
+
+  ArrayLit(const Type &type)
+      : type_(type) {
+  }
+
+  ArrayLit(const ArrayLit &other)
+      : type_(other.type_) {
+    for (const UntypedLiteral *value :other.elements_) {
+      elements_.emplace_back(type_.cloneValue(value));
+    }
+  }
+
+  ArrayLit(ArrayLit &&other)
+      : type_(other.type_),
+        elements_(std::move(other.elements_)) {
+  }
+
+  ~ArrayLit() {
+    clear();
+  }
+
+  void clear() {
+    for (UntypedLiteral *value : elements_) {
+      type_.destroyValue(value);
+    }
+    elements_.clear();
+  }
+
+  bool empty() const {
+    return elements_.empty();
+  }
+
+  std::size_t size() const {
+    return elements_.size();
+  }
+
+
+  void push_back(UntypedLiteral *value) {
+    elements_.emplace_back(value);
+  }
+
+  const UntypedLiteral* operator[](const std::size_t idx) const {
+    DCHECK_LT(idx, elements_.size());
+    return elements_[idx];
+  }
+
+  const_iterator begin() const {
+    return elements_.begin();
+  }
+
+  const_iterator end() const {
+    return elements_.end();
+  }
+
+  const UntypedLiteral* front() const {
+    return elements_.front();
+  }
+
+  const UntypedLiteral* back() const {
+    return elements_.back();
+  }
+
+ private:
+  const Type &type_;
+  std::vector<UntypedLiteral*> elements_;
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_NULL_LIT_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
index 765a1a0..8d8313f 100644
--- a/types/ArrayType.cpp
+++ b/types/ArrayType.cpp
@@ -22,6 +22,7 @@
 #include <cstdlib>
 #include <string>
 
+#include "types/ArrayLit.hpp"
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 
@@ -39,6 +40,15 @@ std::string ArrayType::getName() const {
   return name;
 }
 
+bool ArrayType::isCoercibleFrom(const Type &original_type) const {
+  if (original_type.getTypeID() != kArray) {
+    return false;
+  }
+  const Type &original_element_type =
+      static_cast<const ArrayType&>(original_type).element_type_;
+  return element_type_.isCoercibleFrom(original_element_type);
+}
+
 bool ArrayType::TypeParametersAreValid(const std::vector<GenericValue> &parameters) {
   if (parameters.size() != 1u) {
     return false;
@@ -52,13 +62,13 @@ bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs,
   if (!equals(rhs_type)) {
     return false;
   }
-  const ArrayLiteral &lhs_array = castValueToLiteral(lhs);
-  const ArrayLiteral &rhs_array = castValueToLiteral(rhs);
+  const ArrayLit &lhs_array = castValueToLiteral(lhs);
+  const ArrayLit &rhs_array = castValueToLiteral(rhs);
   if (lhs_array.size() != rhs_array.size()) {
     return false;
   }
   for (std::size_t i = 0; i < lhs_array.size(); ++i) {
-    if (!element_type_.checkValuesEqual(lhs_array.at(i), rhs_array.at(i))) {
+    if (!element_type_.checkValuesEqual(lhs_array[i], rhs_array[i])) {
       return false;
     }
   }
@@ -66,8 +76,8 @@ bool ArrayType::checkValuesEqual(const UntypedLiteral *lhs,
 }
 
 TypedValue ArrayType::marshallValue(const UntypedLiteral *value) const {
-  const ArrayLiteral &array = *static_cast<const ArrayLiteral*>(value);
-  serialization::ArrayLiteral proto;
+  const ArrayLit &array = *static_cast<const ArrayLit*>(value);
+  serialization::ArrayLit proto;
   for (const auto &element : array) {
     // TODO(refactor-type): Improve performance.
     TypedValue value = element_type_.marshallValue(element);
@@ -81,12 +91,12 @@ TypedValue ArrayType::marshallValue(const UntypedLiteral *value) const {
 
 UntypedLiteral* ArrayType::unmarshallValue(const void *data,
                                            const std::size_t data_size) const {
-  std::unique_ptr<ArrayLiteral> array = std::make_unique<ArrayLiteral>();
-  serialization::ArrayLiteral proto;
+  std::unique_ptr<ArrayLit> array = std::make_unique<ArrayLit>(element_type_);
+  serialization::ArrayLit proto;
   proto.ParseFromArray(data, data_size);
   for (int i = 0; i < proto.data_size(); ++i) {
     const std::string &element_data = proto.data(i);
-    array->emplace_back(
+    array->push_back(
         element_type_.unmarshallValue(element_data.c_str(), element_data.size()));
   }
   return array.release();
@@ -95,13 +105,13 @@ UntypedLiteral* ArrayType::unmarshallValue(const void *data,
 std::string ArrayType::printValueToString(const UntypedLiteral *value) const {
   DCHECK(value != nullptr);
 
-  const std::vector<UntypedLiteral*> &literals = castValueToLiteral(value);
+  const ArrayLit &literals = castValueToLiteral(value);
   std::string ret = "{";
   if (!literals.empty()) {
     ret.append(element_type_.printValueToString(literals.front()));
     for (std::size_t i = 1; i < literals.size(); ++i) {
       ret.append(",");
-      ret.append(element_type_.printValueToString(literals.at(i)));
+      ret.append(element_type_.printValueToString(literals[i]));
     }
   }
   ret.append("}");

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
index 5eaff92..e79e389 100644
--- a/types/ArrayType.hpp
+++ b/types/ArrayType.hpp
@@ -39,7 +39,7 @@ class TypedValue;
  *  @{
  */
 
-class ArrayType : public TypeSynthesizer<kArray> {
+class ArrayType final : public TypeSynthesizer<kArray> {
  public:
   int getPrintWidth() const override {
     return 32;
@@ -47,6 +47,8 @@ class ArrayType : public TypeSynthesizer<kArray> {
 
   std::string getName() const override;
 
+  bool isCoercibleFrom(const Type &original_type) const override;
+
   bool checkValuesEqual(const UntypedLiteral *lhs,
                         const UntypedLiteral *rhs,
                         const Type &rhs_type) const override;
@@ -63,6 +65,10 @@ class ArrayType : public TypeSynthesizer<kArray> {
     return false;
   }
 
+  const Type &getElementType() const {
+    return element_type_;
+  }
+
   static bool TypeParametersAreValid(const std::vector<GenericValue> &parameters);
 
  private:
@@ -73,7 +79,7 @@ class ArrayType : public TypeSynthesizer<kArray> {
 
   static const Type& ExtractType(const std::vector<GenericValue> &parameters) {
     DCHECK(TypeParametersAreValid(parameters));
-    return **static_cast<const MetaTypeLiteral*>(parameters.front().getValue());
+    return **static_cast<const MetaTypeLit*>(parameters.front().getValue());
   }
 
   const Type &element_type_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/AsciiStringSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp
index 7de550f..252a1a7 100644
--- a/types/AsciiStringSuperType.hpp
+++ b/types/AsciiStringSuperType.hpp
@@ -38,14 +38,6 @@ namespace quickstep {
 template <TypeID type_id>
 class AsciiStringSuperType : public TypeSynthesizer<type_id> {
  public:
-  bool isCoercibleFrom(const Type &original_type) const override {
-    if (original_type.isNullable() && !this->nullable_) {
-      return false;
-    }
-    return (original_type.getSuperTypeID() == SuperTypeID::kAsciiString)
-           || (original_type.getTypeID() == kNullType);
-  }
-
   /**
    * @brief Get the character-length of this string type.
    *

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/BoolType.hpp
----------------------------------------------------------------------
diff --git a/types/BoolType.hpp b/types/BoolType.hpp
index ed819ae..49fbfa3 100644
--- a/types/BoolType.hpp
+++ b/types/BoolType.hpp
@@ -41,7 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing a 8-bit bool.
  **/
-class BoolType : public NumericSuperType<kBool> {
+class BoolType final : public NumericSuperType<kBool> {
  public:
   int getPrintWidth() const override {
     // "true" or "false"

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 0ee4f26..271700b 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -32,6 +32,7 @@ QS_PROTOBUF_GENERATE_CPP(types_TypedValue_proto_srcs types_TypedValue_proto_hdrs
 QS_PROTOBUF_GENERATE_CPP(types_Type_proto_srcs types_Type_proto_hdrs Type.proto)
 
 # Declare micro-libs:
+add_library(quickstep_types_ArrayLit ../empty_src.cpp ArrayLit.hpp)
 add_library(quickstep_types_ArrayType ArrayType.cpp ArrayType.hpp)
 add_library(quickstep_types_AsciiStringSuperType ../empty_src.cpp AsciiStringSuperType.hpp)
 add_library(quickstep_types_BoolType BoolType.cpp BoolType.hpp)
@@ -185,6 +186,7 @@ target_link_libraries(quickstep_types_MetaType-decl
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeSynthesizer
+                      quickstep_types_TypedValue
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_NullType
                       glog
@@ -203,6 +205,7 @@ target_link_libraries(quickstep_types_NumericSuperType
                       quickstep_utility_Macros
                       quickstep_utility_meta_TMP)
 target_link_libraries(quickstep_types_NumericTypeSafeCoercibility
+                      quickstep_types_TypeRegistrar
                       quickstep_utility_meta_TMP)
 target_link_libraries(quickstep_types_NumericTypeUnifier
                       quickstep_types_NumericTypeSafeCoercibility)
@@ -228,7 +231,8 @@ target_link_libraries(quickstep_types_TypeFactory
                       quickstep_types_TypeSynthesizer
                       quickstep_types_TypeUtil
                       quickstep_types_Type_proto
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_types_TypeFactory-decl
                       glog
                       quickstep_types_GenericValue
@@ -254,6 +258,7 @@ target_link_libraries(quickstep_types_TypeSynthesizer
                       quickstep_types_TypeRegistrar
                       quickstep_types_TypedValue
                       quickstep_types_Type_proto
+                      quickstep_types_operations_utility_CastUtil
                       quickstep_utility_HashPair
                       quickstep_utility_Macros
                       quickstep_utility_meta_Common)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index 3355243..cfd695e 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -43,7 +43,7 @@ namespace quickstep {
  *       represented WITHOUT a null-terminator character. Any strings shorter
  *       than the maximum length will have a null-terminator.
  **/
-class CharType : public AsciiStringSuperType<kChar> {
+class CharType final : public AsciiStringSuperType<kChar> {
  public:
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index 1c9eaf9..b88bb82 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -41,7 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing the date.
  **/
-class DateType : public TypeSynthesizer<kDate> {
+class DateType final : public TypeSynthesizer<kDate> {
  public:
   int getPrintWidth() const override {
     return DateLit::kIsoChars;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index cb2534d..b80b2a7 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -41,7 +41,7 @@ namespace quickstep {
 /**
  * @brief A type representing the datetime interval.
  **/
-class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
+class DatetimeIntervalType final : public TypeSynthesizer<kDatetimeInterval> {
  public:
   int getPrintWidth() const override {
     return DatetimeIntervalLit::kPrintingChars;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index d0ac1e2..dbad0e2 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -41,8 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing the datetime.
  **/
-class DatetimeType
-    : public TypeSynthesizer<kDatetime> {
+class DatetimeType final : public TypeSynthesizer<kDatetime> {
  public:
   int getPrintWidth() const override {
     return DatetimeLit::kIsoChars;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index 6959817..3e906db 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -40,7 +40,7 @@ class TypedValue;
 /**
  * @brief A type representing a double-precision floating-point number.
  **/
-class DoubleType : public NumericSuperType<kDouble> {
+class DoubleType final : public NumericSuperType<kDouble> {
  public:
   int getPrintWidth() const override {
     return kPrintWidth;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 3a7aa41..e9062e0 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -40,7 +40,7 @@ class TypedValue;
 /**
  * @brief A type representing a single-precision floating-point number.
  **/
-class FloatType : public NumericSuperType<kFloat> {
+class FloatType final : public NumericSuperType<kFloat> {
  public:
   int getPrintWidth() const override {
     return kPrintWidth;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index eb5e5aa..7b42906 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -40,7 +40,7 @@ class TypedValue;
 /**
  * @brief A type representing a 32-bit integer.
  **/
-class IntType : public NumericSuperType<kInt> {
+class IntType final : public NumericSuperType<kInt> {
  public:
   int getPrintWidth() const override {
     // Fully represented digits, single leading digit, and possible '-'

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index dc75310..3cd3fc0 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -41,7 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing a 64-bit integer.
  **/
-class LongType : public NumericSuperType<kLong> {
+class LongType final : public NumericSuperType<kLong> {
  public:
   // Fully represented digits, single leading digit, and possible '-'
   // character.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/MetaType-decl.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType-decl.hpp b/types/MetaType-decl.hpp
index 80c5956..569c956 100644
--- a/types/MetaType-decl.hpp
+++ b/types/MetaType-decl.hpp
@@ -37,7 +37,7 @@ namespace quickstep {
  *  @{
  */
 
-class MetaType : public TypeSynthesizer<kMetaType> {
+class MetaType final : public TypeSynthesizer<kMetaType> {
  public:
   int getPrintWidth() const override {
     return 16;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/MetaType.cpp
----------------------------------------------------------------------
diff --git a/types/MetaType.cpp b/types/MetaType.cpp
index 16a86c2..f3da71b 100644
--- a/types/MetaType.cpp
+++ b/types/MetaType.cpp
@@ -51,7 +51,7 @@ UntypedLiteral* MetaType::unmarshallValue(const void *data,
                                           const std::size_t data_size) const {
   serialization::Type proto;
   proto.ParseFromArray(data, data_size);
-  return new MetaTypeLiteral(&TypeFactory::ReconstructFromProto(proto));
+  return new MetaTypeLit(&TypeFactory::ReconstructFromProto(proto));
 }
 
 std::string MetaType::printValueToString(const UntypedLiteral *value) const {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index 1aa8a1c..ae448ea 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -49,7 +49,7 @@ class TypedValue;
  *       a particular operation may accept. It is also assumed that applying
  *       any operation to an argument of NullType always yields NULL values.
  **/
-class NullType : public TypeSynthesizer<kNullType> {
+class NullType final : public TypeSynthesizer<kNullType> {
  public:
   static const NullType& InstanceNonNullable() {
     LOG(FATAL) << "Called NullType::InstanceNonNullable(), "

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index f474d52..6a6ad96 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -53,11 +53,6 @@ class NumericSuperType : public TypeSynthesizer<type_id> {
     return it != safe_coerce_cache_.end();
   }
 
-  bool isCoercibleFrom(const Type &original_type) const override {
-    QUICKSTEP_NULL_COERCIBILITY_CHECK();
-    return (original_type.getSuperTypeID() == SuperTypeID::kNumeric);
-  }
-
   TypedValue makeZeroValue() const override {
     return TypedValue(static_cast<typename TypeIDTrait<type_id>::cpptype>(0));
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/TextType.hpp
----------------------------------------------------------------------
diff --git a/types/TextType.hpp b/types/TextType.hpp
index 9ceea35..a1fc04e 100644
--- a/types/TextType.hpp
+++ b/types/TextType.hpp
@@ -36,7 +36,7 @@ namespace quickstep {
  *  @{
  */
 
-class TextType : public TypeSynthesizer<kText> {
+class TextType final : public TypeSynthesizer<kText> {
  public:
   int getPrintWidth() const override {
     return 32;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index 41780f8..cbfd8dd 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -28,10 +28,6 @@
 
 namespace quickstep {
 
-bool Type::isCoercibleFrom(const Type &original_type) const {
-  return isSafelyCoercibleFrom(original_type);
-}
-
 bool Type::isSafelyCoercibleFrom(const Type &original_type) const {
   if (original_type.isNullable() && !this->nullable_) {
     return false;
@@ -79,20 +75,10 @@ TypedValue Type::coerceTypedValue(const TypedValue &original_value,
 
 UntypedLiteral* Type::coerceValue(const UntypedLiteral *original_value,
                                   const Type &original_type) const {
-  DCHECK(isCoercibleFrom(original_type))
-      << "Can't coerce value of Type " << original_type.getName()
-      << " to Type " << getName();
-
-  if (original_type.getTypeID() == kNullType) {
-    return nullptr;
-  }
-
-  DCHECK(equals(original_type) || equals(original_type.getNullableVersion()))
-      << "Base version of Type::coerceValue() called for a non-trivial "
-      << "coercion from Type " << original_type.getName()
-      << " to Type " << getName();
-
-  return cloneValue(original_value);
+  // TODO(refactor-type): Implement coerceValue based on CastFunctor.
+  TypedValue original_tv = original_type.marshallValue(original_value);
+  TypedValue target_tv = coerceTypedValue(original_tv, original_type);
+  return unmarshallTypedValue(target_tv);
 }
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index e5d5528..0929bc7 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -126,6 +126,10 @@ class Type {
     return type_id_;
   }
 
+  inline MemoryLayout getMemoryLayout() const {
+    return memory_layout_;
+  }
+
   /**
    * @brief Determine whether this Type allows NULL values.
    *
@@ -223,7 +227,7 @@ class Type {
    * @param original_type The original Type for coercion to this Type.
    * @return true if coercion is supported, false otherwise.
    **/
-  virtual bool isCoercibleFrom(const Type &original_type) const;
+  virtual bool isCoercibleFrom(const Type &original_type) const = 0;
 
   /**
    * @brief Determine whether data items of another type can be coerced (used
@@ -431,11 +435,13 @@ class Type {
  protected:
   Type(const SuperTypeID super_type_id,
        const TypeID type_id,
+       const MemoryLayout memory_layout,
        const bool nullable,
        const std::size_t minimum_byte_length,
        const std::size_t maximum_byte_length)
       : super_type_id_(super_type_id),
         type_id_(type_id),
+        memory_layout_(memory_layout),
         nullable_(nullable),
         minimum_byte_length_(minimum_byte_length),
         maximum_byte_length_(maximum_byte_length) {
@@ -443,6 +449,7 @@ class Type {
 
   const SuperTypeID super_type_id_;
   const TypeID type_id_;
+  const MemoryLayout memory_layout_;
   const bool nullable_;
   const std::size_t minimum_byte_length_;
   const std::size_t maximum_byte_length_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index 8092953..5882b8c 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -35,6 +35,6 @@ message GenericValue {
   optional bytes data = 2;
 }
 
-message ArrayLiteral {
+message ArrayLit {
   repeated bytes data = 1;
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
index bb6c40d..d72788b 100644
--- a/types/TypeRegistrar.hpp
+++ b/types/TypeRegistrar.hpp
@@ -43,13 +43,13 @@ namespace quickstep {
 
 class Type;
 class TypedValue;
+class ArrayLit;
 
 using UntypedLiteral = void;
 
-using ArrayLiteral = std::vector<UntypedLiteral*>;
-using MetaTypeLiteral = const Type*;
-using ParInlinePodLiteral = const void*;
-using ParOutOfLinePodLiteral = TypedValue;
+using MetaTypeLit = const Type*;
+using ParInlinePodLit = const void*;
+using ParOutOfLinePodLit = TypedValue;
 
 template <TypeID type_id>
 struct TypeIDTrait;
@@ -85,15 +85,15 @@ REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval,
 REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval,
               SuperTypeID::kOther, kCxxInlinePod, YearMonthIntervalLit);
 REGISTER_TYPE(CharType, kChar,
-              SuperTypeID::kAsciiString, kParInlinePod, ParInlinePodLiteral);
+              SuperTypeID::kAsciiString, kParInlinePod, ParInlinePodLit);
 REGISTER_TYPE(VarCharType, kVarChar,
-              SuperTypeID::kAsciiString, kParOutOfLinePod, ParOutOfLinePodLiteral);
+              SuperTypeID::kAsciiString, kParOutOfLinePod, ParOutOfLinePodLit);
 REGISTER_TYPE(TextType, kText,
               SuperTypeID::kOther, kCxxGeneric, std::string);
 REGISTER_TYPE(ArrayType, kArray,
-              SuperTypeID::kOther, kCxxGeneric, ArrayLiteral);
+              SuperTypeID::kOther, kCxxGeneric, ArrayLit);
 REGISTER_TYPE(MetaType, kMetaType,
-              SuperTypeID::kOther, kCxxGeneric, MetaTypeLiteral);
+              SuperTypeID::kOther, kCxxGeneric, MetaTypeLit);
 REGISTER_TYPE(NullType, kNullType,
               SuperTypeID::kOther, kCxxInlinePod, NullLit);
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index d69b1b4..23d072c 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -30,12 +30,15 @@
 #include <unordered_map>
 #include <vector>
 
+#include "types/ArrayLit.hpp"
 #include "types/GenericValue.hpp"
 #include "types/Type.hpp"
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
+#include "types/operations/utility/CastUtil.hpp"
+#include "utility/Cast.hpp"
 #include "utility/HashPair.hpp"
 #include "utility/Macros.hpp"
 #include "utility/meta/Common.hpp"
@@ -90,6 +93,8 @@ class TypeSynthesizePolicy<
   bool checkValuesEqual(const UntypedLiteral *lhs,
                         const UntypedLiteral *rhs,
                         const Type &rhs_type) const override {
+    DCHECK(lhs != nullptr);
+    DCHECK(rhs != nullptr);
     // TODO(refactor-type): Operator == overloading.
     if (type_id_ != rhs_type.getTypeID()) {
       return false;
@@ -110,15 +115,18 @@ class TypeSynthesizePolicy<
   }
 
   std::size_t hashValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
     return hashValueInl<sizeof(cpptype)>(value);
   }
 
   TypedValue marshallValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
     return makeValue(value, sizeof(cpptype)).ensureNotReference();
   }
 
   UntypedLiteral* unmarshallValue(const void *data,
                                   const std::size_t length) const override {
+    DCHECK(data != nullptr);
     DCHECK_EQ(sizeof(cpptype), length);
     UntypedLiteral *value = std::malloc(sizeof(cpptype));
     std::memcpy(value, data, sizeof(cpptype));
@@ -127,7 +135,7 @@ class TypeSynthesizePolicy<
 
  protected:
   explicit TypeSynthesizePolicy(const bool nullable)
-      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+      : Type(Trait::kStaticSuperTypeID, type_id, kCxxInlinePod, nullable,
              sizeof(cpptype), sizeof(cpptype)) {}
 
   inline const Type& getInstance(const bool nullable) const {
@@ -216,6 +224,7 @@ class TypeSynthesizePolicy<
 
   std::size_t hashValue(const UntypedLiteral *value) const override {
     // TODO(refactor-type): Implementation.
+    DCHECK(value != nullptr);
     return TypedValue(type_id_,
                       *static_cast<const cpptype*>(value),
                       maximum_byte_length_).getHash();
@@ -224,6 +233,8 @@ class TypeSynthesizePolicy<
   bool checkValuesEqual(const UntypedLiteral *lhs,
                         const UntypedLiteral *rhs,
                         const Type &rhs_type) const override {
+    DCHECK(lhs != nullptr);
+    DCHECK(rhs != nullptr);
     if (!equals(rhs_type)) {
       return false;
     }
@@ -254,6 +265,7 @@ class TypeSynthesizePolicy<
 
   UntypedLiteral* unmarshallValue(const void *data,
                                   const std::size_t length) const override {
+    DCHECK(data != nullptr);
     DCHECK_EQ(maximum_byte_length_, length);
     void *value = std::malloc(maximum_byte_length_);
     std::memcpy(value, data, length);
@@ -265,7 +277,7 @@ class TypeSynthesizePolicy<
                        const std::size_t minimum_byte_length,
                        const std::size_t maximum_byte_length,
                        const std::size_t length)
-      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+      : Type(Trait::kStaticSuperTypeID, type_id, kParInlinePod, nullable,
              minimum_byte_length, maximum_byte_length),
         length_(length) {}
 
@@ -345,6 +357,7 @@ class TypeSynthesizePolicy<
 
   std::size_t hashValue(const UntypedLiteral *value) const override {
     // TODO(refactor-type): Better implementation.
+    DCHECK(value != nullptr);
     return static_cast<const TypedValue*>(value)->getHash();
   }
 
@@ -368,11 +381,13 @@ class TypeSynthesizePolicy<
   }
 
   TypedValue marshallValue(const UntypedLiteral *value) const override {
+    DCHECK(value != nullptr);
     return *static_cast<const TypedValue*>(value);
   }
 
   UntypedLiteral* unmarshallValue(const void *data,
                                   const std::size_t length) const override {
+    DCHECK(data != nullptr);
     TypedValue *value = new TypedValue(makeValue(data, length));
     value->ensureNotReference();
     return value;
@@ -383,7 +398,7 @@ class TypeSynthesizePolicy<
                        const std::size_t minimum_byte_length,
                        const std::size_t maximum_byte_length,
                        const std::size_t length)
-      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+      : Type(Trait::kStaticSuperTypeID, type_id, kParOutOfLinePod, nullable,
              minimum_byte_length, maximum_byte_length),
         length_(length) {}
 
@@ -504,7 +519,7 @@ class TypeSynthesizePolicy<
                        const std::size_t minimum_byte_length,
                        const std::size_t maximum_byte_length,
                        const std::vector<GenericValue> &parameters)
-      : Type(Trait::kStaticSuperTypeID, type_id, nullable,
+      : Type(Trait::kStaticSuperTypeID, type_id, kCxxGeneric, nullable,
              minimum_byte_length, maximum_byte_length),
         parameters_(parameters) {}
 
@@ -619,6 +634,11 @@ class TypeSynthesizer : public TypeSynthesizePolicy<type_id> {
     return SynthesizePolicy::getInstance(false);
   }
 
+  bool isCoercibleFrom(const Type &original_type) const override {
+    auto it = kCoercibleSourceTypeIDs.find(original_type.getTypeID());
+    return it != kCoercibleSourceTypeIDs.end();
+  };
+
   UntypedLiteral* unmarshallTypedValue(const TypedValue &value) const override {
     return SynthesizePolicy::unmarshallTypedValueInl(value);
   }
@@ -680,6 +700,8 @@ class TypeSynthesizer : public TypeSynthesizePolicy<type_id> {
  private:
   template <TypeID, typename> friend class TypeSynthesizePolicy;
 
+  static const std::unordered_set<TypeID> kCoercibleSourceTypeIDs;
+
   DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
 
@@ -695,6 +717,10 @@ constexpr bool TypeSynthesizer<type_id>::kIsParPod;
 template <TypeID type_id>
 constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
 
+template <TypeID type_id>
+const std::unordered_set<TypeID> TypeSynthesizer<type_id>::kCoercibleSourceTypeIDs =
+    CastSTLContainer<std::unordered_set<TypeID>>(
+        CastUtil::GetCoercibleSourceTypeIDs(type_id));
 
 #define QUICKSTEP_SYNTHESIZE_TYPE(type) \
   template <TypeID, typename> friend class TypeSynthesizePolicy; \

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index 0b16061..639d0fb 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -43,7 +43,7 @@ namespace quickstep {
  *       character. This means that the VARCHAR(X) type requires from 1 to X+1
  *       bytes of storage, depending on string length.
  **/
-class VarCharType : public AsciiStringSuperType<kVarChar> {
+class VarCharType final : public AsciiStringSuperType<kVarChar> {
  public:
   /**
    * @note Includes an extra byte for a terminating null character.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index ee1eb97..c729411 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -40,7 +40,7 @@ namespace quickstep {
 /**
  * @brief A type representing the year-month interval.
  **/
-class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
+class YearMonthIntervalType final : public TypeSynthesizer<kYearMonthInterval> {
  public:
   int getPrintWidth() const override {
     return YearMonthIntervalLit::kPrintingChars;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/containers/CMakeLists.txt b/types/containers/CMakeLists.txt
index 97841c2..675805a 100644
--- a/types/containers/CMakeLists.txt
+++ b/types/containers/CMakeLists.txt
@@ -29,6 +29,7 @@ add_library(quickstep_types_containers_Tuple_proto ${types_containers_Tuple_prot
 target_link_libraries(quickstep_types_containers_ColumnVector
                       glog
                       quickstep_types_Type
+                      quickstep_types_TypeRegistrar
                       quickstep_types_TypedValue
                       quickstep_utility_BitVector
                       quickstep_utility_Macros)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/ColumnVector.cpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.cpp b/types/containers/ColumnVector.cpp
index ef3587e..476accc 100644
--- a/types/containers/ColumnVector.cpp
+++ b/types/containers/ColumnVector.cpp
@@ -21,6 +21,12 @@
 
 #include <cstddef>
 
+#include "types/TypeID.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "types/TypeIDSelectors.hpp"
+#include "utility/Macros.hpp"
+
 namespace quickstep {
 
 class Type;
@@ -30,19 +36,36 @@ ColumnVector* ColumnVector::MakeVectorOfValue(
     const Type &value_type,
     const TypedValue &value,
     const std::size_t num_copies) {
-  if (NativeColumnVector::UsableForType(value_type)) {
-    NativeColumnVector *result = new NativeColumnVector(value_type, num_copies);
-    result->fillWithValue(value);
-    return result;
-  } else {
-    IndirectColumnVector *result = new IndirectColumnVector(value_type, num_copies);
-    result->fillWithValue(value);
-    return result;
+  switch (value_type.getMemoryLayout()) {
+    case kCxxInlinePod:  // Fall through
+    case kParInlinePod: {
+      NativeColumnVector *result = new NativeColumnVector(value_type, num_copies);
+      result->fillWithValue(value);
+      return result;
+    }
+    case kParOutOfLinePod: {
+      IndirectColumnVector *result = new IndirectColumnVector(value_type, num_copies);
+      result->fillWithValue(value);
+      return result;
+    }
+    case kCxxGeneric: {
+      // TODO(refactor-type): Omit non-supported types.
+      return InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxGeneric>>(
+          value_type.getTypeID(),
+          [&](auto tid) -> ColumnVector* {
+        using TypeClass = typename TypeIDTrait<decltype(tid)::value>::TypeClass;
+        GenericColumnVector<TypeClass> *result =
+            new GenericColumnVector<TypeClass>(value_type, num_copies);
+        result->fillWithValue(value);
+        return result;
+      });
+    }
   }
+  QUICKSTEP_UNREACHABLE();
 }
 
-constexpr bool NativeColumnVector::kNative;
+constexpr ColumnVector::Implementation NativeColumnVector::kImplementation;
 
-constexpr bool IndirectColumnVector::kNative;
+constexpr ColumnVector::Implementation IndirectColumnVector::kImplementation;
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/ColumnVector.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp
index d524ff5..18b8b86 100644
--- a/types/containers/ColumnVector.hpp
+++ b/types/containers/ColumnVector.hpp
@@ -28,6 +28,7 @@
 #include <vector>
 
 #include "types/Type.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/BitVector.hpp"
 #include "utility/Macros.hpp"
@@ -123,18 +124,6 @@ class ColumnVector {
     return implementation_;
   }
 
-  inline bool isNative() const {
-    return implementation_ == kNative;
-  }
-
-  inline bool isIndrect() const {
-    return implementation_ == kIndirect;
-  }
-
-  inline bool isGeneric() const {
-    return implementation_ == kGeneric;
-  }
-
   /**
    * @brief Get the number of values in this ColumnVector.
    *
@@ -142,6 +131,10 @@ class ColumnVector {
    **/
   virtual std::size_t size() const = 0;
 
+  virtual TypedValue getTypedValueVirtual(const std::size_t position) const {
+    LOG(FATAL) << "Unexpected call to ColumnVector::getTypedValueVirtual()";
+  }
+
  protected:
   const Implementation implementation_;
   const Type &type_;
@@ -155,7 +148,7 @@ class ColumnVector {
  **/
 class NativeColumnVector : public ColumnVector {
  public:
-  static constexpr bool kNative = true;
+  static constexpr Implementation kImplementation = ColumnVector::kNative;
 
   /**
    * @brief Constructor for a NativeColumnVector which owns its own array of
@@ -166,16 +159,13 @@ class NativeColumnVector : public ColumnVector {
    *        NativeColumnVector will hold.
    **/
   NativeColumnVector(const Type &type, const std::size_t reserved_length)
-      : ColumnVector(ColumnVector::kNative, type),
+      : ColumnVector(kImplementation, type),
         type_length_(type.maximumByteLength()),
         reserved_length_(reserved_length),
         values_(std::malloc(type.maximumByteLength() * reserved_length)),
         actual_length_(0u),
         null_bitmap_(type.isNullable() ? new BitVector<false>(reserved_length) : nullptr) {
     DCHECK(UsableForType(type_));
-    if (null_bitmap_) {
-      null_bitmap_->clear();
-    }
   }
 
   /**
@@ -193,7 +183,8 @@ class NativeColumnVector : public ColumnVector {
    *         IndirectColumnVector must be used instead.
    **/
   static bool UsableForType(const Type &type) {
-    return !type.isVariableLength();
+    return type.getMemoryLayout() == kCxxInlinePod ||
+           type.getMemoryLayout() == kParInlinePod;
   }
 
   /**
@@ -437,7 +428,7 @@ class NativeColumnVector : public ColumnVector {
  **/
 class IndirectColumnVector : public ColumnVector {
  public:
-  static constexpr bool kNative = false;
+  static constexpr Implementation kImplementation = ColumnVector::kIndirect;
 
   /**
    * @brief Constructor.
@@ -446,7 +437,7 @@ class IndirectColumnVector : public ColumnVector {
    * @param reserved_length The number of values to reserve space for.
    **/
   IndirectColumnVector(const Type &type, const std::size_t reserved_length)
-      : ColumnVector(ColumnVector::kIndirect, type),
+      : ColumnVector(kImplementation, type),
         type_is_nullable_(type.isNullable()),
         reserved_length_(reserved_length) {
     values_.reserve(reserved_length);
@@ -616,11 +607,102 @@ class IndirectColumnVector : public ColumnVector {
   DISALLOW_COPY_AND_ASSIGN(IndirectColumnVector);
 };
 
-class GenericColumnVector {
+template <typename TypeClass>
+class GenericColumnVector : public ColumnVector {
+ public:
+  static constexpr Implementation kImplementation = ColumnVector::kGeneric;
+
+  using cpptype = typename TypeClass::cpptype;
+
+  GenericColumnVector(const Type &type, const std::size_t reserved_length)
+      : ColumnVector(kImplementation, type),
+        type_(static_cast<const TypeClass&>(type)),
+        reserved_length_(reserved_length) {
+    DCHECK(TypeClass::kStaticTypeID == type.getTypeID());
+    values_.reserve(reserved_length_);
+    if (type.isNullable()) {
+      null_bitmap_ = std::make_unique<BitVector<false>>(reserved_length_);
+    }
+  }
+
+  static bool UsableForType(const Type &type) {
+    return type.getMemoryLayout() == kCxxGeneric;
+  }
+
+  inline bool typeIsNullable() const {
+    return null_bitmap_.get() != nullptr;
+  }
 
+  inline std::size_t size() const override {
+    return values_.size();
+  }
 
+  template <bool check_null = true>
+  inline cpptype& getLiteralValue(const std::size_t position) const {
+    DCHECK_LT(position, values_.size());
+    return (check_null && null_bitmap_ && null_bitmap_->getBit(position))
+        ? nullptr
+        : values_[position];
+  }
+
+  TypedValue getTypedValueVirtual(const std::size_t position) const override {
+    return getTypedValue(position);
+  }
+
+  inline TypedValue getTypedValue(const std::size_t position) const {
+    DCHECK_LT(position, values_.size());
+    // TODO(refactor-type): Implement marshallValueMaybeReference() to improve performance.
+    return (null_bitmap_ && null_bitmap_->getBit(position))
+        ? type_.makeNullValue()
+        : type_.marshallValue(&values_[position]);
+  }
+
+  inline void appendNullValue() {
+    DCHECK_LT(values_.size(), reserved_length_);
+    DCHECK(null_bitmap_);
+    null_bitmap_->setBit(values_.size(), true);
+    // TODO(refactor-type): Specialize nullable GenericColumnVector.
+    LOG(FATAL) << "Not implemented";
+  }
+
+  inline void fillWithNulls() {
+    DCHECK(null_bitmap_);
+    null_bitmap_->setBitRange(0, reserved_length_, true);
+    // TODO(refactor-type): Specialize nullable GenericColumnVector.
+    LOG(FATAL) << "Not implemented";
+  }
+
+  inline void fillWithValue(const TypedValue &value) {
+    std::unique_ptr<cpptype> cppvalue = std::unique_ptr<cpptype>(
+        static_cast<cpptype*>(type_.unmarshallTypedValue(value)));
+    for (std::size_t i = 0; i < reserved_length_; ++i) {
+      values_.emplace_back(*cppvalue);
+    }
+  }
+
+  inline void appendLiteralValue(const cpptype &value) {
+    DCHECK_LT(values_.size(), reserved_length_);
+    values_.emplace_back(value);
+  }
+
+  inline void appendLiteralValue(cpptype &&value) {
+    DCHECK_LT(values_.size(), reserved_length_);
+    values_.emplace_back(std::move(value));
+  }
+
+ private:
+  const TypeClass &type_;
+  const std::size_t reserved_length_;
+
+  std::vector<cpptype> values_;
+  std::unique_ptr<BitVector<false>> null_bitmap_;
+
+  DISALLOW_COPY_AND_ASSIGN(GenericColumnVector);
 };
 
+template <typename TypeClass>
+constexpr ColumnVector::Implementation GenericColumnVector<TypeClass>::kImplementation;
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/ColumnVectorUtil.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVectorUtil.hpp b/types/containers/ColumnVectorUtil.hpp
index 5a560a4..e241a21 100644
--- a/types/containers/ColumnVectorUtil.hpp
+++ b/types/containers/ColumnVectorUtil.hpp
@@ -22,6 +22,8 @@
 
 #include "types/containers/ColumnVector.hpp"
 
+#include "glog/logging.h"
+
 namespace quickstep {
 
 /** \addtogroup Types
@@ -43,9 +45,11 @@ namespace quickstep {
 template <typename FunctorT>
 auto InvokeOnColumnVector(const ColumnVector &column_vector,
                           const FunctorT &functor) {
-  if (column_vector.isNative()) {
+  // TODO(refactor-type):
+  if (column_vector.getImplementation() == ColumnVector::kNative) {
     return functor(static_cast<const NativeColumnVector&>(column_vector));
   } else {
+    DCHECK(column_vector.getImplementation() == ColumnVector::kIndirect);
     return functor(static_cast<const IndirectColumnVector&>(column_vector));
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/containers/ColumnVectorsValueAccessor.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVectorsValueAccessor.hpp b/types/containers/ColumnVectorsValueAccessor.hpp
index 0ea6d50..bec232f 100644
--- a/types/containers/ColumnVectorsValueAccessor.hpp
+++ b/types/containers/ColumnVectorsValueAccessor.hpp
@@ -38,6 +38,7 @@
 namespace quickstep {
 
 class TupleIdSequence;
+typedef void UntypedLiteral;
 
 /**
  * @brief Implementation of ValueAccessor as a group of equal-length
@@ -77,9 +78,8 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
     // If this is not the first column to be added, make sure it is the same
     // length as the others.
     DCHECK(columns_.empty() || column->size() == column_length_);
-    DCHECK(column->isNative() || column->isIndrect());
-    columns_.push_back(column);
-    column_native_.push_back(column->isNative());
+    columns_.emplace_back(column);
+    column_impl_.emplace_back(column->getImplementation());
     column_length_ = column->size();
   }
 
@@ -152,10 +152,15 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
                                                        const tuple_id tid) const {
     DCHECK(attributeIdInRange(attr_id));
     DCHECK(tupleIdInRange(tid));
-    if (column_native_[attr_id]) {
-      return static_cast<const NativeColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid);
-    } else {
-      return static_cast<const IndirectColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid);
+    // TODO(jianqiao): Implement specialized column accessors to improve performance.
+    switch (column_impl_[attr_id]) {
+      case ColumnVector::kNative:
+        return static_cast<const NativeColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid);
+      case ColumnVector::kIndirect:
+        return static_cast<const IndirectColumnVector&>(*columns_[attr_id]).getUntypedValue<check_null>(tid);
+      default:
+        LOG(FATAL) << "Can not apply getUntypedValueAtAbsolutionPosition() to "
+                   << "GenericColumnVector";
     }
   }
 
@@ -163,14 +168,18 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
                                                     const tuple_id tid) const {
     DCHECK(attributeIdInRange(attr_id));
     DCHECK(tupleIdInRange(tid));
-    if (column_native_[attr_id]) {
-      return static_cast<const NativeColumnVector&>(*columns_[attr_id])
-          .getTypedValue(tid)
-          .makeReferenceToThis();
-    } else {
-      return static_cast<const IndirectColumnVector&>(*columns_[attr_id])
-          .getTypedValue(tid)
-          .makeReferenceToThis();
+    // TODO(jianqiao): Implement specialized column accessors to improve performance.
+    switch (column_impl_[attr_id]) {
+      case ColumnVector::kNative:
+        return static_cast<const NativeColumnVector&>(*columns_[attr_id])
+            .getTypedValue(tid)
+            .makeReferenceToThis();
+      case ColumnVector::kIndirect:
+        return static_cast<const IndirectColumnVector&>(*columns_[attr_id])
+            .getTypedValue(tid)
+            .makeReferenceToThis();
+      case ColumnVector::kGeneric:
+        return columns_[attr_id]->getTypedValueVirtual(tid);
     }
   }
 
@@ -305,7 +314,7 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
   }
 
   std::vector<ColumnVectorPtr> columns_;
-  std::vector<bool> column_native_;
+  std::vector<ColumnVector::Implementation> column_impl_;
   std::size_t column_length_;
   std::size_t current_position_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/4bf0857c/types/operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/CMakeLists.txt b/types/operations/CMakeLists.txt
index caf5f72..1e622dd 100644
--- a/types/operations/CMakeLists.txt
+++ b/types/operations/CMakeLists.txt
@@ -39,13 +39,12 @@ target_link_libraries(quickstep_types_operations_OperationFactory
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypeUtil
-                      quickstep_types_TypedValue
                       quickstep_types_operations_Operation
                       quickstep_types_operations_OperationSignature
                       quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctors
                       quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_types_operations_binaryoperations_BinaryOperationSynthesizer
                       quickstep_types_operations_binaryoperations_CMathBinaryFunctors
                       quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
                       quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors
@@ -54,7 +53,7 @@ target_link_libraries(quickstep_types_operations_OperationFactory
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_unaryoperations_UnaryOperationSynthesizer
                       quickstep_utility_HashPair
                       quickstep_utility_Macros
                       quickstep_utility_StringUtil)



[13/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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/9b23a4d3/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_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/TypedValue.cpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.cpp b/types/TypedValue.cpp
index 8dd8b60..ad1eb0f 100644
--- a/types/TypedValue.cpp
+++ b/types/TypedValue.cpp
@@ -47,6 +47,7 @@ bool TypedValue::isPlausibleInstanceOf(const TypeSignature type) const {
   }
 
   switch (type_id) {
+    case kBool:
     case kInt:
     case kLong:
     case kFloat:
@@ -82,33 +83,34 @@ 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 kBool:
+      if (!isNull()) {
+        proto.set_int_value(getLiteral<bool>());
+      }
+      break;
     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 +119,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 +162,29 @@ 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 kBool:
+      return proto.has_bool_value() ?
+          TypedValue(static_cast<bool>(proto.bool_value())) :
+          TypedValue(kBool);
+    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 +192,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 +200,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 +208,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 +216,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/9b23a4d3/types/TypedValue.hpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.hpp b/types/TypedValue.hpp
index 0ba3d53..196e8ec 100644
--- a/types/TypedValue.hpp
+++ b/types/TypedValue.hpp
@@ -90,6 +90,16 @@ class TypedValue {
   }
 
   /**
+   * @brief Constructor for a literal value of BoolType.
+   **/
+  explicit TypedValue(const bool literal_bool)
+      : value_info_(static_cast<std::uint64_t>(kBool)) {
+    // Zero-out all bytes in the union for getHash() and fastEqualCheck().
+    value_union_.hash64 = 0;
+    value_union_.bool_value = literal_bool;
+  }
+
+  /**
    * @brief Constructor for a literal value of IntType.
    **/
   explicit TypedValue(const int literal_int)
@@ -264,9 +274,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;
@@ -282,6 +292,7 @@ class TypedValue {
    **/
   static bool RepresentedInline(const TypeID type_id) {
     switch (type_id) {
+      case kBool:
       case kInt:
       case kLong:
       case kFloat:
@@ -313,6 +324,8 @@ class TypedValue {
    **/
   static bool HashIsReversible(const TypeID type_id) {
     switch (type_id) {
+      case kBool:
+        return true;
       case kInt:
       case kFloat:
         return sizeof(value_union_.int_value) <= sizeof(std::size_t);
@@ -391,6 +404,8 @@ class TypedValue {
   inline std::size_t getDataSize() const {
     DCHECK(!isNull());
     switch (getTypeID()) {
+      case kBool:
+        return sizeof(bool);
       case kInt:
       case kFloat:
         return sizeof(int);
@@ -478,7 +493,8 @@ class TypedValue {
    * @return The out-of-line data this TypedValue points to.
    **/
   inline const void* getOutOfLineData() const {
-    DCHECK(!(getTypeID() == kInt
+    DCHECK(!(getTypeID() == kBool
+                   || getTypeID() == kInt
                    || getTypeID() == kLong
                    || getTypeID() == kFloat
                    || getTypeID() == kDouble
@@ -547,6 +563,10 @@ class TypedValue {
                   value_info_ >> kSizeShift);
     } else {
       switch (getTypeID()) {
+        case kBool:
+          // 1 byte copy.
+          *static_cast<bool*>(destination) = value_union_.bool_value;
+          break;
         case kInt:
         case kFloat:
           // 4 bytes byte-for-byte copy.
@@ -574,6 +594,7 @@ class TypedValue {
    **/
   inline std::size_t getHash() const {
     switch (getTypeID()) {
+      case kBool:
       case kInt:
       case kLong:
       case kFloat:
@@ -670,6 +691,7 @@ class TypedValue {
     DCHECK(!other.isNull());
     DCHECK_EQ(getTypeID(), other.getTypeID());
     switch (getTypeID()) {
+      case kBool:
       case kInt:
       case kLong:
       case kFloat:
@@ -710,6 +732,16 @@ class TypedValue {
     }
   }
 
+  bool operator==(const TypedValue &other) const {
+    if (getTypeID() != other.getTypeID()) {
+      return false;
+    }
+    if (isNull() || other.isNull()) {
+      return isNull() == other.isNull();
+    }
+    return fastEqualCheck(other);
+  }
+
   /**
    * @brief Generate a serialized Protocol Buffer representation
    *        of this TypedValue.
@@ -789,6 +821,7 @@ class TypedValue {
   inline void reverseHash(const std::size_t hash);
 
   union ValueUnion {
+    bool bool_value;
     int int_value;
     std::int64_t long_value;
     float float_value;
@@ -842,6 +875,13 @@ class TypedValue {
 
 // Explicit specializations of getLiteral().
 template <>
+inline bool TypedValue::getLiteral<bool>() const {
+  DCHECK_EQ(kBool, getTypeID());
+  DCHECK(!isNull());
+  return value_union_.bool_value;
+}
+
+template <>
 inline int TypedValue::getLiteral<int>() const {
   DCHECK_EQ(kInt, getTypeID());
   DCHECK(!isNull());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/TypedValue.proto
----------------------------------------------------------------------
diff --git a/types/TypedValue.proto b/types/TypedValue.proto
index 7f3ab7a..7cf3eca 100644
--- a/types/TypedValue.proto
+++ b/types/TypedValue.proto
@@ -22,17 +22,18 @@ 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;
-  optional int64 long_value = 3;
-  optional float float_value = 4;
-  optional double double_value = 5;
-  optional bytes out_of_line_data = 6;
-  optional int64 datetime_value = 7;
-  optional int64 datetime_interval_value = 8;
-  optional int64 year_month_interval_value = 9;
+  optional bool bool_value = 2;
+  optional int32 int_value = 3;
+  optional int64 long_value = 4;
+  optional float float_value = 5;
+  optional double double_value = 6;
+  optional bytes out_of_line_data = 7;
+  optional int64 datetime_value = 8;
+  optional int64 datetime_interval_value = 9;
+  optional int64 year_month_interval_value = 10;
 
   message DateLit {
     required int32 year = 1;
@@ -40,5 +41,5 @@ message TypedValue {
     required uint32 day = 3;
   }
 
-  optional DateLit date_value = 10;
+  optional DateLit date_value = 11;
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/VarCharType.cpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.cpp b/types/VarCharType.cpp
index 02845b1..7eeb04c 100644
--- a/types/VarCharType.cpp
+++ b/types/VarCharType.cpp
@@ -42,38 +42,6 @@ using std::string;
 
 namespace quickstep {
 
-template <bool nullable_internal>
-const VarCharType& VarCharType::InstanceInternal(const std::size_t length) {
-  static PtrMap<size_t, VarCharType> instance_map;
-  PtrMap<size_t, VarCharType>::iterator imit = instance_map.find(length);
-  if (imit == instance_map.end()) {
-    imit = instance_map.insert(length, new VarCharType(length, nullable_internal)).first;
-  }
-  return *(imit->second);
-}
-
-const VarCharType& VarCharType::InstanceNonNullable(const std::size_t length) {
-  return InstanceInternal<false>(length);
-}
-
-const VarCharType& VarCharType::InstanceNullable(const std::size_t length) {
-  return InstanceInternal<true>(length);
-}
-
-const VarCharType& VarCharType::InstanceFromProto(const serialization::Type &proto) {
-  return Instance(proto.GetExtension(serialization::VarCharType::length), proto.nullable());
-}
-
-serialization::Type VarCharType::getProto() const {
-  serialization::Type proto;
-  proto.set_type_id(serialization::Type::VAR_CHAR);
-
-  proto.set_nullable(nullable_);
-
-  proto.SetExtension(serialization::VarCharType::length, length_);
-  return proto;
-}
-
 size_t VarCharType::estimateAverageByteLength() const {
   if (length_ > 160) {
     return 80;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index bb50e92..05b2aae 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -24,8 +24,8 @@
 #include <cstdio>
 #include <string>
 
+#include "types/AsciiStringSuperType.hpp"
 #include "types/Type.hpp"
-#include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
@@ -43,72 +43,9 @@ 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> {
  public:
   /**
-   * @brief Get a reference to the non-nullable singleton instance of this Type
-   *        for the specified length.
-   *
-   * @param length The length parameter of the VarCharType.
-   * @return A reference to the non-nullable singleton instance of this Type
-   *         for the specified length.
-   **/
-  static const VarCharType& InstanceNonNullable(const std::size_t length);
-
-  /**
-   * @brief Get a reference to the nullable singleton instance of this Type for
-   *        the specified length.
-   *
-   * @param length The length parameter of the VarCharType.
-   * @return A reference to the nullable singleton instance of this Type for
-   *         the specified length.
-   **/
-  static const VarCharType& InstanceNullable(const std::size_t length);
-
-  /**
-   * @brief Get a reference to the singleton instance of this Type for the
-   *        specified length and nullability.
-   *
-   * @param length The length parameter of the VarCharType.
-   * @param nullable Whether to get the nullable version of this Type.
-   * @return A reference to the singleton instance of this Type for the
-   *         specified length and nullability.
-   **/
-  static const VarCharType& Instance(const std::size_t length, const bool nullable) {
-    if (nullable) {
-      return InstanceNullable(length);
-    } else {
-      return InstanceNonNullable(length);
-    }
-  }
-
-  /**
-   * @brief Get a reference to the singleton instance of this Type described
-   *        by the given Protocol Buffer serialization.
-   *
-   * @param type The serialized Protocol Buffer representation of the desired
-   *        VarCharType.
-   * @return A reference to the singleton instance of this Type for the given
-   *         Protocol Buffer.
-   **/
-  static const VarCharType& InstanceFromProto(const serialization::Type &type);
-
-  /**
-   * @brief Generate a serialized Protocol Buffer representation of this Type.
-   *
-   * @return The serialized Protocol Buffer representation of this Type.
-   **/
-  serialization::Type getProto() const override;
-
-  const Type& getNullableVersion() const override {
-    return InstanceNullable(length_);
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return InstanceNonNullable(length_);
-  }
-
-  /**
    * @note Includes an extra byte for a terminating null character.
    **/
   std::size_t estimateAverageByteLength() const override;
@@ -137,11 +74,9 @@ class VarCharType : public AsciiStringSuperType {
 
  private:
   VarCharType(const std::size_t length, const bool nullable)
-      : AsciiStringSuperType(kVarChar, nullable, 1, length + 1, length) {
-  }
+      : AsciiStringSuperType<kVarChar>(nullable, 1, length + 1, length) {}
 
-  template <bool nullable_internal>
-  static const VarCharType& InstanceInternal(const std::size_t length);
+  template <typename, bool> friend class TypeInstance;
 
   DISALLOW_COPY_AND_ASSIGN(VarCharType);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/YearMonthIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.cpp b/types/YearMonthIntervalType.cpp
index 3c15a91..d656fca 100644
--- a/types/YearMonthIntervalType.cpp
+++ b/types/YearMonthIntervalType.cpp
@@ -30,7 +30,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"
@@ -46,16 +45,6 @@ using std::snprintf;
 
 namespace quickstep {
 
-bool YearMonthIntervalType::isCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kYearMonthInterval);
-}
-
-bool YearMonthIntervalType::isSafelyCoercibleFrom(const Type &original_type) const {
-  QUICKSTEP_NULL_COERCIBILITY_CHECK();
-  return (original_type.getTypeID() == kYearMonthInterval);
-}
-
 std::string YearMonthIntervalType::printValueToString(const TypedValue &value) const {
   DCHECK(!value.isNull());
 
@@ -127,14 +116,6 @@ std::string YearMonthIntervalType::printValueToString(const TypedValue &value) c
   return std::string(interval_buf);
 }
 
-void YearMonthIntervalType::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", static_cast<int>(padding), printValueToString(value).c_str());
-}
-
 bool YearMonthIntervalType::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/9b23a4d3/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index a2ba175..e890ea9 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -27,6 +27,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"
 
@@ -39,73 +40,14 @@ namespace quickstep {
 /**
  * @brief A type representing the year-month interval.
  **/
-class YearMonthIntervalType : public Type {
+class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
  public:
-  typedef YearMonthIntervalLit cpptype;
-
-  static const TypeID kStaticTypeID = kYearMonthInterval;
-
-  /**
-   * @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 YearMonthIntervalType& InstanceNonNullable() {
-    static YearMonthIntervalType 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 YearMonthIntervalType& InstanceNullable() {
-    static YearMonthIntervalType 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 YearMonthIntervalType& 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(YearMonthIntervalLit);
-  }
-
-  bool isCoercibleFrom(const Type &original_type) const override;
-
-  bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
   int getPrintWidth() const override {
     return YearMonthIntervalLit::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(YearMonthIntervalLit{0});
   }
@@ -115,8 +57,9 @@ class YearMonthIntervalType : public Type {
 
  private:
   explicit YearMonthIntervalType(const bool nullable)
-      : Type(Type::kOther, kYearMonthInterval, nullable, sizeof(YearMonthIntervalLit), sizeof(YearMonthIntervalLit)) {
-  }
+      : TypeSynthesizer<kYearMonthInterval>(nullable) {}
+
+  template <typename, bool> friend class TypeInstance;
 
   DISALLOW_COPY_AND_ASSIGN(YearMonthIntervalType);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/containers/ColumnVector.cpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.cpp b/types/containers/ColumnVector.cpp
index dfc0fae..ef3587e 100644
--- a/types/containers/ColumnVector.cpp
+++ b/types/containers/ColumnVector.cpp
@@ -41,4 +41,8 @@ ColumnVector* ColumnVector::MakeVectorOfValue(
   }
 }
 
+constexpr bool NativeColumnVector::kNative;
+
+constexpr bool IndirectColumnVector::kNative;
+
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/containers/ColumnVector.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp
index 5ef9871..0d6447d 100644
--- a/types/containers/ColumnVector.hpp
+++ b/types/containers/ColumnVector.hpp
@@ -129,6 +129,8 @@ class ColumnVector {
  **/
 class NativeColumnVector : public ColumnVector {
  public:
+  static constexpr bool kNative = true;
+
   /**
    * @brief Constructor for a NativeColumnVector which owns its own array of
    *        values.
@@ -140,8 +142,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_));
@@ -395,8 +397,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_;
 
@@ -409,6 +412,8 @@ class NativeColumnVector : public ColumnVector {
  **/
 class IndirectColumnVector : public ColumnVector {
  public:
+  static constexpr bool kNative = false;
+
   /**
    * @brief Constructor.
    *
@@ -503,11 +508,21 @@ class IndirectColumnVector : public ColumnVector {
    * @param value A value to append to this NativeColumnVector.
    **/
   inline void appendTypedValue(TypedValue &&value) {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    DCHECK(value.isPlausibleInstanceOf(type_.getSignature())) << type_.getName();
     DCHECK_LT(values_.size(), reserved_length_);
     values_.emplace_back(std::move(value));
   }
 
+  inline void appendNullValue() {
+    DCHECK(type_.isNullable());
+    DCHECK_LT(values_.size(), reserved_length_);
+    values_.emplace_back(type_.makeNullValue());
+  }
+
+  inline void fillWithNulls() {
+    fillWithValue(type_.makeNullValue());
+  }
+
   /**
    * @brief Fill this entire ColumnVector with copies of value.
    *
@@ -569,6 +584,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);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/CMakeLists.txt b/types/operations/CMakeLists.txt
index c5dad0f..948d013 100644
--- a/types/operations/CMakeLists.txt
+++ b/types/operations/CMakeLists.txt
@@ -25,19 +25,62 @@ QS_PROTOBUF_GENERATE_CPP(types_operations_Operation_proto_srcs
 
 # Declare micro-libs:
 add_library(quickstep_types_operations_Operation Operation.cpp Operation.hpp)
+add_library(quickstep_types_operations_OperationFactory OperationFactory.cpp OperationFactory.hpp)
+add_library(quickstep_types_operations_OperationUtil ../../empty_src.cpp OperationUtil.hpp)
+add_library(quickstep_types_operations_OperationSignature OperationSignature.cpp OperationSignature.hpp)
 add_library(quickstep_types_operations_Operation_proto ${types_operations_Operation_proto_srcs})
 
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_Operation
+                      quickstep_types_operations_OperationSignature
+                      quickstep_utility_Macros)
+target_link_libraries(quickstep_types_operations_OperationFactory
+                      quickstep_types_Type
+                      quickstep_types_TypeFactory
+                      quickstep_types_TypeID
+                      quickstep_types_TypeUtil
+                      quickstep_types_TypedValue
+                      quickstep_types_operations_Operation
+                      quickstep_types_operations_OperationSignature
+                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
+                      quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
+                      quickstep_types_operations_binaryoperations_BinaryOperation
+                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_types_operations_binaryoperations_CMathBinaryOperations
+                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+                      quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+                      quickstep_types_operations_unaryoperations_CMathUnaryOperations
+                      quickstep_types_operations_unaryoperations_CastOperation
+                      quickstep_types_operations_unaryoperations_DateExtractOperation
+                      quickstep_types_operations_unaryoperations_SubstringOperation
+                      quickstep_types_operations_unaryoperations_UnaryOperation
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_utility_HashPair
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
+target_link_libraries(quickstep_types_operations_OperationUtil
+                      quickstep_catalog_CatalogTypedefs
+                      quickstep_types_Type
+                      quickstep_types_TypedValue
+                      quickstep_types_containers_ColumnVector)
+target_link_libraries(quickstep_types_operations_OperationSignature
+                      quickstep_types_TypeID
+                      quickstep_types_Type_proto
+                      quickstep_types_operations_Operation_proto
+                      quickstep_utility_HashPair
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_operations_Operation_proto
                       quickstep_types_Type_proto
+                      quickstep_types_TypedValue_proto
                       ${PROTOBUF_LIBRARY})
 
 # Module all-in-one library:
 add_library(quickstep_types_operations ../../empty_src.cpp)
 target_link_libraries(quickstep_types_operations
                       quickstep_types_operations_Operation
+                      quickstep_types_operations_OperationFactory
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_Operation_proto
                       quickstep_types_operations_binaryoperations
                       quickstep_types_operations_comparisons

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/Operation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/Operation.hpp b/types/operations/Operation.hpp
index 51178b5..6da0f4c 100644
--- a/types/operations/Operation.hpp
+++ b/types/operations/Operation.hpp
@@ -20,6 +20,10 @@
 #ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_HPP_
 #define QUICKSTEP_TYPES_OPERATIONS_OPERATION_HPP_
 
+#include <string>
+#include <vector>
+
+#include "types/operations/OperationSignature.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -28,6 +32,9 @@ namespace quickstep {
  *  @{
  */
 
+class Operation;
+typedef std::shared_ptr<const Operation> OperationPtr;
+
 /**
  * @brief An operation which can be applied to typed values. Each exact
  *        concrete Operation is a singleton.
@@ -72,7 +79,7 @@ class Operation {
    * @return The human-readable name of this Operation.
    **/
   inline const char* getName() const {
-    return name_;
+    return "NoName";
   }
 
   /**
@@ -81,7 +88,11 @@ class Operation {
    * @return The short name of this Operation.
    **/
   inline const char* getShortName() const {
-    return short_name_;
+    return "NoShortName";
+  }
+
+  virtual std::vector<OperationSignaturePtr> getSignatures() const {
+    return {};
   }
 
   /**
@@ -98,19 +109,12 @@ class Operation {
   }
 
  protected:
-  Operation(const OperationSuperTypeID super_type_id,
-            const char *name,
-            const char *short_name)
-      : super_type_id_(super_type_id),
-        name_(name),
-        short_name_(short_name) {
+  explicit Operation(const OperationSuperTypeID super_type_id)
+      : super_type_id_(super_type_id) {
   }
 
  private:
   const OperationSuperTypeID super_type_id_;
-  const char *name_;
-  const char *short_name_;
-
 
   DISALLOW_COPY_AND_ASSIGN(Operation);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/Operation.proto
----------------------------------------------------------------------
diff --git a/types/operations/Operation.proto b/types/operations/Operation.proto
index d6391f0..da2a282 100644
--- a/types/operations/Operation.proto
+++ b/types/operations/Operation.proto
@@ -20,6 +20,7 @@ syntax = "proto2";
 package quickstep.serialization;
 
 import "types/Type.proto";
+import "types/TypedValue.proto";
 
 message Comparison {
   enum ComparisonID {
@@ -38,58 +39,8 @@ message Comparison {
   required ComparisonID comparison_id = 1;
 }
 
-message UnaryOperation {
-  enum UnaryOperationID {
-    NEGATE = 0;
-    CAST = 1;
-    DATE_EXTRACT = 2;
-    SUBSTRING = 3;
-  }
-
-  required UnaryOperationID operation_id = 1;
-
-  extensions 32 to max;
-}
-
-message CastOperation {
-  extend UnaryOperation {
-    // Required when operation_id = CAST.
-    optional Type target_type = 64;
-  }
-}
-
-message DateExtractOperation {
-  enum Unit {
-    YEAR = 0;
-    MONTH = 1;
-    DAY = 2;
-    HOUR = 3;
-    MINUTE = 4;
-    SECOND = 5;
-  }
-
-  extend UnaryOperation {
-    // Required when operation_id = DATE_EXTRACT.
-    optional Unit unit = 96;
-  }
-}
-
-message SubstringOperation {
-  extend UnaryOperation {
-    // Required when operation_id = SUBSTRING.
-    optional int64 start_position = 100;
-    optional int64 substring_length = 101;
-  }
-}
-
-message BinaryOperation {
-  enum BinaryOperationID {
-    ADD = 0;
-    SUBTRACT = 1;
-    MULTIPLY = 2;
-    DIVIDE = 3;
-    MODULO = 4;
-  }
-
-  required BinaryOperationID operation_id = 1;
+message OperationSignature {
+  required string operation_name = 1;
+  repeated TypeID argument_type_ids = 2;
+  required uint32 num_static_arguments = 3;
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/OperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.cpp b/types/operations/OperationFactory.cpp
new file mode 100644
index 0000000..531318b
--- /dev/null
+++ b/types/operations/OperationFactory.cpp
@@ -0,0 +1,357 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/operations/OperationFactory.hpp"
+
+#include <list>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/TypedValue.hpp"
+#include "types/operations/Operation.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/binary_operations/ArithmeticBinaryOperations.hpp"
+#include "types/operations/binary_operations/AsciiStringBinaryOperations.hpp"
+#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "types/operations/binary_operations/CMathBinaryOperations.hpp"
+#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp"
+#include "types/operations/unary_operations/AsciiStringUnaryOperations.hpp"
+#include "types/operations/unary_operations/CMathUnaryOperations.hpp"
+#include "types/operations/unary_operations/CastOperation.hpp"
+#include "types/operations/unary_operations/DateExtractOperation.hpp"
+#include "types/operations/unary_operations/SubstringOperation.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "utility/StringUtil.hpp"
+
+namespace quickstep {
+
+namespace {
+
+struct FunctorPackDispatcher {
+  template <typename FunctorT>
+  inline static std::list<OperationPtr> Generate(
+      std::enable_if_t<FunctorT::kOperationSuperTypeID == Operation::kUnaryOperation>* = 0) {
+    return { std::make_shared<const UnaryOperationWrapper<FunctorT>>() };
+  }
+
+  template <typename FunctorT>
+  inline static std::list<OperationPtr> Generate(
+      std::enable_if_t<FunctorT::kOperationSuperTypeID == Operation::kBinaryOperation>* = 0) {
+    return { std::make_shared<const BinaryOperationWrapper<FunctorT>>() };
+  }
+
+  template <typename FunctorT>
+  inline static std::list<OperationPtr> Generate(
+      decltype(FunctorT::template GenerateOperations<FunctorPackDispatcher>())* = 0) {
+    return FunctorT::template GenerateOperations<FunctorPackDispatcher>();
+  }
+};
+
+}  // namespace
+
+OperationFactory::OperationFactory() {
+  registerOperation<CastOperation>();
+  registerOperation<DateExtractOperation>();
+  registerOperation<SubstringOperation>();
+
+  registerFunctorPack<ArithmeticUnaryFunctorPack>();
+  registerFunctorPack<AsciiStringUnaryFunctorPack>();
+  registerFunctorPack<CMathUnaryFunctorPack>();
+
+  registerFunctorPack<ArithmeticBinaryFunctorPack>();
+  registerFunctorPack<AsciiStringBinaryFunctorPack>();
+  registerFunctorPack<CMathBinaryFunctorPack>();
+}
+
+OperationSignaturePtr OperationFactory::resolveOperation(
+    const std::string &operation_name,
+    const std::shared_ptr<const std::vector<const Type*>> &argument_types,
+    const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+    std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+    std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+    std::string *message) const {
+  const std::string lower_case_name = ToLower(operation_name);
+  const std::size_t arity = argument_types->size();
+  const auto &indices_it =
+      primary_index_.find(std::make_pair(lower_case_name, arity));
+
+  if (indices_it == primary_index_.end()) {
+    *message = "Unrecognized function " + operation_name
+                   + " with " + std::to_string(arity) + " arguments";
+  }
+
+  ResolveStatus status;
+  OperationSignaturePtr op_signature = nullptr;
+  const auto &secondary_index = indices_it->second;
+
+  std::vector<TypeID> argument_type_ids;
+  for (const auto *type : *argument_types) {
+    argument_type_ids.emplace_back(type->getTypeID());
+  }
+
+  // First, try full exact matching.
+  status = resolveOperationWithFullTypeMatch(secondary_index,
+                                             argument_type_ids,
+                                             *argument_types,
+                                             *static_arguments,
+                                             coerced_static_arguments,
+                                             &op_signature,
+                                             message);
+  if (status == ResolveStatus::kSuccess) {
+    DCHECK(op_signature != nullptr);
+    *coerced_argument_types = argument_types;
+    return op_signature;
+  } else if (status == ResolveStatus::kError) {
+    return nullptr;
+  }
+
+  // Otherwise, try partial (non-static arguments) exact matching.
+  status = resolveOperationWithPartialTypeMatch(secondary_index,
+                                                argument_type_ids,
+                                                *argument_types,
+                                                *static_arguments,
+                                                coerced_argument_types,
+                                                coerced_static_arguments,
+                                                &op_signature,
+                                                message);
+  if (status == ResolveStatus::kSuccess) {
+    DCHECK(op_signature != nullptr);
+    return op_signature;
+  } else if (status == ResolveStatus::kError) {
+    return nullptr;
+  }
+
+  // TODO
+  *message = "Unexpected argument types for function " + operation_name;
+  return nullptr;
+}
+
+OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMatch(
+    const PartialSignatureIndex &secondary_index,
+    const std::vector<TypeID> &argument_type_ids,
+    const std::vector<const Type*> &argument_types,
+    const std::vector<TypedValue> &static_arguments,
+    std::shared_ptr<const std::vector<TypedValue>> *partial_static_arguments,
+    OperationSignaturePtr *resolved_op_signature,
+    std::string *message) const {
+  const std::size_t max_num_static_arguments = static_arguments.size();
+  auto it = secondary_index.lower_bound(
+      std::make_pair(&argument_type_ids, max_num_static_arguments));
+
+  if (it != secondary_index.end() && *it->first.first == argument_type_ids) {
+    const OperationSignaturePtr op_signature = it->second;
+    const OperationPtr operation = getOperation(op_signature);
+
+    *partial_static_arguments =
+        std::make_shared<const std::vector<TypedValue>>(
+            static_arguments.begin()
+                + (max_num_static_arguments - op_signature->getNumStaticArguments()),
+            static_arguments.end());
+
+    if (canApplyOperationTo(operation,
+                            argument_types,
+                            **partial_static_arguments,
+                            message)) {
+      *resolved_op_signature = op_signature;
+      return ResolveStatus::kSuccess;
+    } else {
+      return ResolveStatus::kError;
+    }
+  }
+
+  return ResolveStatus::kNotFound;
+}
+
+OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTypeMatch(
+    const PartialSignatureIndex &secondary_index,
+    const std::vector<TypeID> &argument_type_ids,
+    const std::vector<const Type*> &argument_types,
+    const std::vector<TypedValue> &static_arguments,
+    std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+    std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+    OperationSignaturePtr *resolved_op_signature,
+    std::string *message) const {
+  const std::size_t arity = argument_types.size();
+  const std::size_t max_num_static_arguments = static_arguments.size();
+  const std::size_t first_static_argument_position = arity - max_num_static_arguments;
+
+  auto it = secondary_index.lower_bound(
+      std::make_pair(&argument_type_ids, max_num_static_arguments));
+  while (it != secondary_index.end()) {
+    const std::vector<TypeID> &expected_type_ids = *it->first.first;
+    DCHECK_GE(expected_type_ids.size(), it->first.second);
+    const std::size_t num_non_static_arguments =
+        expected_type_ids.size() - it->first.second;
+
+    if (!std::equal(expected_type_ids.begin(),
+                    expected_type_ids.begin() + num_non_static_arguments,
+                    argument_type_ids.begin())) {
+      break;
+    }
+
+    // Coerce static arguments
+    std::vector<const Type*> coerced_static_arg_types;
+    std::vector<TypedValue> coerced_static_args;
+
+    bool is_coercible = true;
+    for (std::size_t i = num_non_static_arguments; i < arity; ++i) {
+      const Type &arg_type = *argument_types.at(i);
+      const TypedValue &arg_value =
+          static_arguments.at(i - first_static_argument_position);
+      const TypeID &expected_type_id = expected_type_ids.at(i);
+
+      if (arg_type.getTypeID() == expected_type_id) {
+        coerced_static_arg_types.emplace_back(&arg_type);
+        coerced_static_args.emplace_back(arg_value);
+      } else {
+        const Type *expected_type = nullptr;
+        if (TypeFactory::TypeRequiresLengthParameter(expected_type_id)) {
+          // TODO: refactor type system to make this coercion extensible.
+          if (expected_type_id == kChar && arg_type.getTypeID() == kVarChar) {
+            expected_type = &TypeFactory::GetType(
+                expected_type_id, arg_type.maximumByteLength() - 1);
+          } else if (expected_type_id == kVarChar && arg_type.getTypeID() == kChar) {
+            expected_type = &TypeFactory::GetType(
+                expected_type_id, arg_type.maximumByteLength() + 1);
+          }
+        } else {
+          expected_type = &TypeFactory::GetType(expected_type_id);
+        }
+
+        if (expected_type != nullptr && expected_type->isSafelyCoercibleFrom(arg_type)) {
+          coerced_static_arg_types.emplace_back(expected_type);
+          coerced_static_args.emplace_back(
+              expected_type->coerceValue(arg_value, arg_type));
+        } else {
+          is_coercible = false;
+          break;
+        }
+      }
+    }
+
+    if (is_coercible) {
+      std::vector<const Type*> coerced_arg_types(
+          argument_types.begin(),
+          argument_types.begin() + num_non_static_arguments);
+      for (const Type *type : coerced_static_arg_types) {
+        coerced_arg_types.emplace_back(type);
+      }
+
+      const OperationPtr operation = getOperation(it->second);
+      if (canApplyOperationTo(operation,
+                              coerced_arg_types,
+                              coerced_static_args,
+                              message)) {
+        *coerced_argument_types =
+            std::make_shared<const std::vector<const Type*>>(std::move(coerced_arg_types));
+        *coerced_static_arguments =
+            std::make_shared<const std::vector<TypedValue>>(std::move(coerced_static_args));
+        *resolved_op_signature = it->second;
+        return ResolveStatus::kSuccess;
+      }
+    }
+
+    ++it;
+  }
+
+  return ResolveStatus::kNotFound;
+}
+
+bool OperationFactory::canApplyOperationTo(
+    const OperationPtr operation,
+    const std::vector<const Type*> &argument_types,
+    const std::vector<TypedValue> &static_arguments,
+    std::string *message) const {
+  switch (operation->getOperationSuperTypeID()) {
+    case Operation::kUnaryOperation: {
+      const UnaryOperationPtr unary_operation =
+          std::static_pointer_cast<const UnaryOperation>(operation);
+      return unary_operation->canApplyTo(*argument_types[0],
+                                         static_arguments,
+                                         message);
+    }
+    case Operation::kBinaryOperation: {
+      const BinaryOperationPtr binary_operation =
+          std::static_pointer_cast<const BinaryOperation>(operation);
+      return binary_operation->canApplyTo(*argument_types[0],
+                                          *argument_types[1],
+                                          static_arguments,
+                                          message);
+    }
+    default: {
+      const auto operation_id =
+         static_cast<std::underlying_type_t<Operation::OperationSuperTypeID>>(
+             operation->getOperationSuperTypeID());
+      LOG(FATAL) << "Unknown opeation super type id: " << operation_id;
+    }
+  }
+}
+
+
+const OperationFactory& OperationFactory::Instance() {
+  static OperationFactory instance;
+  return instance;
+}
+
+template <typename OperationT>
+void OperationFactory::registerOperation() {
+  registerOperationInternal(std::make_shared<const OperationT>());
+}
+
+template <typename FunctorPackT>
+void OperationFactory::registerFunctorPack() {
+  for (const OperationPtr &operation :
+           FunctorPackT::template GenerateOperations<FunctorPackDispatcher>()) {
+    registerOperationInternal(operation);
+  }
+}
+
+void OperationFactory::registerOperationInternal(const OperationPtr &operation) {
+  DCHECK(operation->getOperationSuperTypeID() == Operation::kUnaryOperation ||
+         operation->getOperationSuperTypeID() == Operation::kBinaryOperation);
+
+  for (const OperationSignaturePtr op_sig_orig : operation->getSignatures()) {
+    DCHECK(operation->getOperationSuperTypeID() != Operation::kUnaryOperation ||
+           op_sig_orig->getNonStaticArity() == 1u);
+    DCHECK(operation->getOperationSuperTypeID() != Operation::kBinaryOperation ||
+           op_sig_orig->getNonStaticArity() == 2u);
+
+    const OperationSignaturePtr op_sig =
+        OperationSignature::Create(ToLower(op_sig_orig->getName()),
+                                   op_sig_orig->getArgumentTypeIDs(),
+                                   op_sig_orig->getNumStaticArguments());
+
+    // TODO: print error message for collision
+    operations_.emplace(op_sig, operation);
+
+    const PartialSignature sig_ref =
+        std::make_pair(&op_sig->getArgumentTypeIDs(),
+                       op_sig->getNumStaticArguments());
+    primary_index_[std::make_pair(op_sig->getName(),
+                                  op_sig->getArity())].emplace(sig_ref, op_sig);
+  }
+}
+
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/OperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.hpp b/types/operations/OperationFactory.hpp
new file mode 100644
index 0000000..3e90b6d
--- /dev/null
+++ b/types/operations/OperationFactory.hpp
@@ -0,0 +1,203 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_FACTORY_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_FACTORY_HPP_
+
+#include <memory>
+#include <set>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/operations/Operation.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/binary_operations/BinaryOperation.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/HashPair.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class Type;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class OperationFactory {
+ public:
+  static const OperationFactory& Instance();
+
+  inline bool hasOperation(const std::string &operation_name,
+                           const std::size_t arity) const {
+    const auto indices_it =
+        primary_index_.find(std::make_pair(operation_name, arity));
+    return indices_it != primary_index_.end();
+  }
+
+  inline OperationPtr getOperation(const OperationSignaturePtr &op_signature) const {
+    DCHECK(operations_.find(op_signature) != operations_.end());
+    return operations_.at(op_signature);
+  }
+
+  inline OperationPtr getOperation(const std::string &operation_name,
+                                   const std::vector<TypeID> &argument_type_ids,
+                                   const std::size_t num_static_arguments = 0) const {
+    return getOperation(
+        OperationSignature::Create(
+            operation_name, argument_type_ids, num_static_arguments));
+  }
+
+  inline UnaryOperationPtr getUnaryOperation(
+      const OperationSignaturePtr &op_signature) const {
+    const OperationPtr operation = getOperation(op_signature);
+    DCHECK(operation->getOperationSuperTypeID() == Operation::kUnaryOperation);
+    return std::static_pointer_cast<const UnaryOperation>(operation);
+  }
+
+  inline UnaryOperationPtr getUnaryOperation(
+      const std::string &operation_name,
+      const std::vector<TypeID> &argument_type_ids,
+      const std::size_t num_static_arguments = 0) const {
+    return getUnaryOperation(
+        OperationSignature::Create(
+            operation_name, argument_type_ids, num_static_arguments));
+  }
+
+  inline BinaryOperationPtr getBinaryOperation(
+      const OperationSignaturePtr &op_signature) const {
+    const OperationPtr operation = getOperation(op_signature);
+    DCHECK(operation->getOperationSuperTypeID() == Operation::kBinaryOperation);
+    return std::static_pointer_cast<const BinaryOperation>(operation);
+  }
+
+  inline BinaryOperationPtr getBinaryOperation(
+      const std::string &operation_name,
+      const std::vector<TypeID> &argument_type_ids,
+      const std::size_t num_static_arguments = 0) const {
+    return getBinaryOperation(
+        OperationSignature::Create(
+            operation_name, argument_type_ids, num_static_arguments));
+  }
+
+  OperationSignaturePtr resolveOperation(
+      const std::string &operation_name,
+      const std::shared_ptr<const std::vector<const Type*>> &argument_types,
+      const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+      std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+      std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+      std::string *message) const;
+
+ private:
+  OperationFactory();
+
+  template <typename OperationT>
+  void registerOperation();
+
+  template <typename FunctorPackT>
+  void registerFunctorPack();
+
+  void registerOperationInternal(const OperationPtr &operation);
+
+  using PartialSignature = std::pair<const std::vector<TypeID>*, std::size_t>;
+
+  struct PartialSignatureLess {
+    inline bool operator()(const PartialSignature &lhs,
+                           const PartialSignature &rhs) const {
+      int cmp_code = static_cast<int>(lhs.first->size())
+                         - static_cast<int>(lhs.first->size());
+      if (cmp_code != 0) {
+        return cmp_code < 0;
+      }
+      for (std::size_t i = 0; i < lhs.first->size(); ++i) {
+        cmp_code = static_cast<int>(lhs.first->at(i))
+                       - static_cast<int>(rhs.first->at(i));
+        if (cmp_code != 0) {
+          return cmp_code < 0;
+        }
+      }
+      return lhs.second > rhs.second;
+    }
+  };
+
+  using PartialSignatureIndex = std::map<PartialSignature,
+                                         OperationSignaturePtr,
+                                         PartialSignatureLess>;
+
+  enum class ResolveStatus {
+    kSuccess = 0,
+    kError,
+    kNotFound
+  };
+
+  ResolveStatus resolveOperationWithFullTypeMatch(
+      const PartialSignatureIndex &secondary_index,
+      const std::vector<TypeID> &argument_type_ids,
+      const std::vector<const Type*> &argument_types,
+      const std::vector<TypedValue> &static_arguments,
+      std::shared_ptr<const std::vector<TypedValue>> *trimmed_static_arguments,
+      OperationSignaturePtr *resolved_op_signature,
+      std::string *message) const;
+
+  ResolveStatus resolveOperationWithPartialTypeMatch(
+      const PartialSignatureIndex &secondary_index,
+      const std::vector<TypeID> &argument_type_ids,
+      const std::vector<const Type*> &argument_types,
+      const std::vector<TypedValue> &static_arguments,
+      std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+      std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+      OperationSignaturePtr *resolved_op_signature,
+      std::string *message) const;
+
+//  ResolveStatus resolveOperationGeneric(
+//      const std::set<OperationSignaturePtr> signatures,
+//      const std::vector<TypeID> &argument_type_ids,
+//      const std::vector<const Type*> &argument_types,
+//      const std::vector<TypedValue> &static_arguments,
+//      std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+//      std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+//      OperationSignaturePtr *op_signature,
+//      std::string *message) const;
+
+  bool canApplyOperationTo(const OperationPtr operation,
+                           const std::vector<const Type*> &argument_types,
+                           const std::vector<TypedValue> &static_arguments,
+                           std::string *message) const;
+
+  std::unordered_map<OperationSignaturePtr,
+                     OperationPtr,
+                     OperationSignatureHash,
+                     OperationSignatureEqual> operations_;
+
+  std::unordered_map<std::pair<std::string, std::size_t>,
+                     PartialSignatureIndex> primary_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(OperationFactory);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_FACTORY_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/OperationSignature.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationSignature.cpp b/types/operations/OperationSignature.cpp
new file mode 100644
index 0000000..6b6c4a6
--- /dev/null
+++ b/types/operations/OperationSignature.cpp
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/operations/OperationSignature.hpp"
+
+#include <cstdint>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/Type.pb.h"
+#include "types/operations/Operation.pb.h"
+
+namespace quickstep {
+
+serialization::OperationSignature OperationSignature::getProto() const {
+  serialization::OperationSignature op_signature;
+
+  op_signature.set_operation_name(operation_name_);
+  for (const TypeID tid : argument_type_ids_) {
+    op_signature.add_argument_type_ids()->CopyFrom(TypeIDFactory::GetProto(tid));
+  }
+  op_signature.set_num_static_arguments(
+      static_cast<std::uint32_t>(num_static_arguments_));
+
+  return op_signature;
+}
+
+OperationSignaturePtr OperationSignature::ReconstructFromProto(
+    const serialization::OperationSignature &proto) {
+  std::vector<TypeID> argument_type_ids;
+  for (int i = 0; i < proto.argument_type_ids_size(); ++i) {
+    argument_type_ids.emplace_back(
+        TypeIDFactory::ReconstructFromProto(proto.argument_type_ids(i)));
+  }
+
+  return Create(proto.operation_name(),
+                argument_type_ids,
+                proto.num_static_arguments());
+}
+
+std::string OperationSignature::toString() const {
+  const std::size_t num_regular_arguments =
+      argument_type_ids_.size() - num_static_arguments_;
+
+  std::string str;
+  str.append(operation_name_);
+  str.push_back('(');
+  for (std::size_t i = 0; i < num_regular_arguments; ++i) {
+    if (i != 0) {
+      str.append(", ");
+    }
+    str.append(
+        kTypeNames[static_cast<std::underlying_type_t<TypeID>>(
+            argument_type_ids_[i])]);
+  }
+  if (num_static_arguments_ > 0) {
+    str.append(", static(");
+    for (std::size_t i = 0; i < num_static_arguments_; ++i) {
+      if (i != 0) {
+        str.append(", ");
+      }
+      str.append(
+          kTypeNames[static_cast<std::underlying_type_t<TypeID>>(
+              argument_type_ids_[i + num_regular_arguments])]);
+    }
+    str.push_back(')');
+  }
+  str.push_back(')');
+
+  return str;
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/OperationSignature.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationSignature.hpp b/types/operations/OperationSignature.hpp
new file mode 100644
index 0000000..6659a85
--- /dev/null
+++ b/types/operations/OperationSignature.hpp
@@ -0,0 +1,182 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_SIGNATURE_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SIGNATURE_HPP_
+
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/operations/Operation.pb.h"
+
+#include "utility/HashPair.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class OperationSignature;
+typedef std::shared_ptr<const OperationSignature> OperationSignaturePtr;
+
+class OperationSignature {
+ public:
+  serialization::OperationSignature getProto() const;
+
+  static OperationSignaturePtr ReconstructFromProto(
+      const serialization::OperationSignature &proto);
+
+  inline const std::string& getName() const {
+    return operation_name_;
+  }
+
+  inline std::size_t getArity() const {
+    return argument_type_ids_.size();
+  }
+
+  inline std::size_t getNonStaticArity() const {
+    return argument_type_ids_.size() - num_static_arguments_;
+  }
+
+  inline const std::vector<TypeID>& getArgumentTypeIDs() const {
+    return argument_type_ids_;
+  }
+
+  inline std::size_t getNumStaticArguments() const {
+    return num_static_arguments_;
+  }
+
+  inline bool operator==(const OperationSignature &r) const {
+    return operation_name_ == r.operation_name_
+        && argument_type_ids_ == r.argument_type_ids_
+        && num_static_arguments_ == r.num_static_arguments_;
+  }
+
+  inline bool operator!=(const OperationSignature &r) const {
+    return !(*this == r);
+  }
+
+  inline bool operator<(const OperationSignature &r) const {
+    int cmp_code = operation_name_.compare(r.operation_name_);
+    if (cmp_code != 0) {
+      return cmp_code < 0;
+    }
+    cmp_code = static_cast<int>(getArity() - r.getArity());
+    if (cmp_code != 0) {
+      return cmp_code < 0;
+    }
+    cmp_code = static_cast<int>(num_static_arguments_ - r.num_static_arguments_);
+    if (cmp_code != 0) {
+      return cmp_code > 0;
+    }
+    for (std::size_t i = 0; i < getArity(); ++i) {
+      const auto l_tid =
+          static_cast<std::underlying_type_t<TypeID>>(argument_type_ids_.at(i));
+      const auto r_tid =
+          static_cast<std::underlying_type_t<TypeID>>(r.argument_type_ids_.at(i));
+      if (l_tid != r_tid) {
+        return l_tid < r_tid;
+      }
+    }
+    return false;
+  }
+
+  inline std::size_t hash() const {
+    std::size_t hash_code = std::hash<std::string>()(operation_name_);
+    for (const TypeID tid : argument_type_ids_) {
+      hash_code = CombineHashes(hash_code, static_cast<std::size_t>(tid));
+    }
+    hash_code = CombineHashes(hash_code, num_static_arguments_);
+    return hash_code;
+  }
+
+  std::string toString() const;
+
+  static OperationSignaturePtr Create(
+      const std::string &operation_name,
+      const std::vector<TypeID> &argument_type_ids,
+      const std::size_t num_static_arguments) {
+    return OperationSignaturePtr(
+        new OperationSignature(operation_name,
+                               argument_type_ids,
+                               num_static_arguments));
+  }
+
+  static OperationSignaturePtr Create(
+      const std::string &operation_name,
+      const std::vector<TypeID> &regular_argument_type_ids,
+      const std::vector<TypeID> &static_argument_type_ids) {
+    std::vector<TypeID> argument_type_ids = regular_argument_type_ids;
+    argument_type_ids.insert(argument_type_ids.end(),
+                             static_argument_type_ids.begin(),
+                             static_argument_type_ids.end());
+    return OperationSignaturePtr(
+        new OperationSignature(operation_name,
+                               argument_type_ids,
+                               static_argument_type_ids.size()));
+  }
+
+ private:
+  OperationSignature(const std::string &operation_name,
+                     const std::vector<TypeID> &argument_type_ids,
+                     const std::size_t num_static_arguments)
+      : operation_name_(operation_name),
+        argument_type_ids_(argument_type_ids),
+        num_static_arguments_(num_static_arguments) {
+    DCHECK_GE(argument_type_ids_.size(), num_static_arguments_);
+  }
+
+  const std::string operation_name_;
+  const std::vector<TypeID> argument_type_ids_;
+  const std::size_t num_static_arguments_;
+
+  DISALLOW_COPY_AND_ASSIGN(OperationSignature);
+};
+
+/**
+ * @brief Implements the equal function for operation signatures.
+ */
+struct OperationSignatureEqual {
+  inline bool operator()(const OperationSignaturePtr &lhs,
+                         const OperationSignaturePtr &rhs) const {
+    return *lhs == *rhs;
+  }
+};
+
+/**
+ * @brief Implements the hash function for operation signatures.
+ */
+struct OperationSignatureHash {
+  inline std::size_t operator()(const OperationSignaturePtr &op_sig) const {
+    return op_sig->hash();
+  }
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SIGNATURE_HPP_


[15/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index f6b5247..ff73cc7 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -81,104 +81,105 @@ extern int quickstep_yydebug;
     TOKEN_CSB_TREE = 291,
     TOKEN_BY = 292,
     TOKEN_CASE = 293,
-    TOKEN_CHARACTER = 294,
-    TOKEN_CHECK = 295,
-    TOKEN_COLUMN = 296,
-    TOKEN_CONSTRAINT = 297,
-    TOKEN_COPY = 298,
-    TOKEN_CREATE = 299,
-    TOKEN_CURRENT = 300,
-    TOKEN_DATE = 301,
-    TOKEN_DATETIME = 302,
-    TOKEN_DAY = 303,
-    TOKEN_DECIMAL = 304,
-    TOKEN_DEFAULT = 305,
-    TOKEN_DELETE = 306,
-    TOKEN_DESC = 307,
-    TOKEN_DISTINCT = 308,
-    TOKEN_DOUBLE = 309,
-    TOKEN_DROP = 310,
-    TOKEN_ELSE = 311,
-    TOKEN_END = 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_STDERR = 368,
-    TOKEN_STDOUT = 369,
-    TOKEN_SUBSTRING = 370,
-    TOKEN_TABLE = 371,
-    TOKEN_THEN = 372,
-    TOKEN_TIME = 373,
-    TOKEN_TIMESTAMP = 374,
-    TOKEN_TO = 375,
-    TOKEN_TRUE = 376,
-    TOKEN_TUPLESAMPLE = 377,
-    TOKEN_UNBOUNDED = 378,
-    TOKEN_UNIQUE = 379,
-    TOKEN_UPDATE = 380,
-    TOKEN_USING = 381,
-    TOKEN_VALUES = 382,
-    TOKEN_VARCHAR = 383,
-    TOKEN_WHEN = 384,
-    TOKEN_WHERE = 385,
-    TOKEN_WINDOW = 386,
-    TOKEN_WITH = 387,
-    TOKEN_YEAR = 388,
-    TOKEN_YEARMONTH = 389,
-    TOKEN_EOF = 390,
-    TOKEN_LEX_ERROR = 391
+    TOKEN_CAST = 294,
+    TOKEN_CHARACTER = 295,
+    TOKEN_CHECK = 296,
+    TOKEN_COLUMN = 297,
+    TOKEN_CONSTRAINT = 298,
+    TOKEN_COPY = 299,
+    TOKEN_CREATE = 300,
+    TOKEN_CURRENT = 301,
+    TOKEN_DATE = 302,
+    TOKEN_DATETIME = 303,
+    TOKEN_DAY = 304,
+    TOKEN_DECIMAL = 305,
+    TOKEN_DEFAULT = 306,
+    TOKEN_DELETE = 307,
+    TOKEN_DESC = 308,
+    TOKEN_DISTINCT = 309,
+    TOKEN_DOUBLE = 310,
+    TOKEN_DROP = 311,
+    TOKEN_ELSE = 312,
+    TOKEN_END = 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_STDERR = 369,
+    TOKEN_STDOUT = 370,
+    TOKEN_SUBSTRING = 371,
+    TOKEN_TABLE = 372,
+    TOKEN_THEN = 373,
+    TOKEN_TIME = 374,
+    TOKEN_TIMESTAMP = 375,
+    TOKEN_TO = 376,
+    TOKEN_TRUE = 377,
+    TOKEN_TUPLESAMPLE = 378,
+    TOKEN_UNBOUNDED = 379,
+    TOKEN_UNIQUE = 380,
+    TOKEN_UPDATE = 381,
+    TOKEN_USING = 382,
+    TOKEN_VALUES = 383,
+    TOKEN_VARCHAR = 384,
+    TOKEN_WHEN = 385,
+    TOKEN_WHERE = 386,
+    TOKEN_WINDOW = 387,
+    TOKEN_WITH = 388,
+    TOKEN_YEAR = 389,
+    TOKEN_YEARMONTH = 390,
+    TOKEN_EOF = 391,
+    TOKEN_LEX_ERROR = 392
   };
 #endif
 
@@ -187,7 +188,7 @@ extern int quickstep_yydebug;
 
 union YYSTYPE
 {
-#line 121 "../SqlParser.ypp" /* yacc.c:1915  */
+#line 115 "../SqlParser.ypp" /* yacc.c:1915  */
 
   quickstep::ParseString *string_value_;
 
@@ -259,8 +260,8 @@ union YYSTYPE
   quickstep::ParseStatementQuit *quit_statement_;
 
   const quickstep::Comparison *comparison_;
-  const quickstep::UnaryOperation *unary_operation_;
-  const quickstep::BinaryOperation *binary_operation_;
+  quickstep::ParseString *unary_operation_;
+  quickstep::ParseString *binary_operation_;
 
   quickstep::ParseFunctionCall *function_call_;
   quickstep::PtrList<quickstep::ParseExpression> *expression_list_;
@@ -288,7 +289,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 292 "SqlParser_gen.hpp" /* yacc.c:1915  */
+#line 293 "SqlParser_gen.hpp" /* yacc.c:1915  */
 };
 
 typedef union YYSTYPE YYSTYPE;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/LogicalGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/LogicalGenerator.cpp b/query_optimizer/LogicalGenerator.cpp
index abeca53..aaad96a 100644
--- a/query_optimizer/LogicalGenerator.cpp
+++ b/query_optimizer/LogicalGenerator.cpp
@@ -51,9 +51,12 @@ L::LogicalPtr LogicalGenerator::generatePlan(
     const CatalogDatabase &catalog_database,
     const ParseStatement &parse_statement) {
   resolver::Resolver resolver(catalog_database, optimizer_context_);
-  DVLOG(4) << "Parse tree:\n" << parse_statement.toString();
+//  DVLOG(4) << "Parse tree:\n" << parse_statement.toString();
+  std::cerr << "Parse tree:\n" << parse_statement.toString();
   logical_plan_ = resolver.resolve(parse_statement);
-  DVLOG(4) << "Initial logical plan:\n" << logical_plan_->toString();
+//  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/9b23a4d3/query_optimizer/expressions/BinaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/BinaryExpression.cpp b/query_optimizer/expressions/BinaryExpression.cpp
index f49c6a2..24fee40 100644
--- a/query_optimizer/expressions/BinaryExpression.cpp
+++ b/query_optimizer/expressions/BinaryExpression.cpp
@@ -31,8 +31,8 @@
 #include "query_optimizer/expressions/ExprId.hpp"
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/PatternMatcher.hpp"
+#include "query_optimizer/expressions/ScalarLiteral.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "utility/HashPair.hpp"
 
 #include "glog/logging.h"
@@ -44,37 +44,8 @@ class Type;
 namespace optimizer {
 namespace expressions {
 
-BinaryExpression::BinaryExpression(const BinaryOperation &operation,
-                                   const ScalarPtr &left,
-                                   const ScalarPtr &right)
-    : operation_(operation), left_(left), right_(right) {
-  DCHECK(operation_.canApplyToTypes(left_->getValueType(),
-                                    right_->getValueType()))
-      << toString();
-  addChild(left_);
-  addChild(right_);
-}
-
 std::string BinaryExpression::getName() const {
-  switch (operation_.getBinaryOperationID()) {
-    case BinaryOperationID::kAdd:
-      return "Add";
-    case BinaryOperationID::kSubtract:
-      return "Subtract";
-    case BinaryOperationID::kMultiply:
-      return "Multiply";
-    case BinaryOperationID::kDivide:
-      return "Divide";
-    case BinaryOperationID::kModulo:
-      return "Modulo";
-    default:
-      LOG(FATAL) << "Unknown binary operation";
-  }
-}
-
-const Type &BinaryExpression::getValueType() const {
-  return *operation_.resultTypeForArgumentTypes(left_->getValueType(),
-                                                right_->getValueType());
+  return op_signature_->getName();
 }
 
 ExpressionPtr BinaryExpression::copyWithNewChildren(
@@ -83,9 +54,12 @@ ExpressionPtr BinaryExpression::copyWithNewChildren(
   DCHECK(SomeScalar::Matches(new_children[0]));
   DCHECK(SomeScalar::Matches(new_children[1]));
   return BinaryExpression::Create(
+      op_signature_,
       operation_,
       std::static_pointer_cast<const Scalar>(new_children[0]),
-      std::static_pointer_cast<const Scalar>(new_children[1]));
+      std::static_pointer_cast<const Scalar>(new_children[1]),
+      static_arguments_,
+      static_argument_types_);
 }
 
 std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() const {
@@ -102,33 +76,42 @@ std::vector<AttributeReferencePtr> BinaryExpression::getReferencedAttributes() c
 ::quickstep::Scalar *BinaryExpression::concretize(
     const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const {
   return new ::quickstep::ScalarBinaryExpression(
+      op_signature_,
       operation_,
       left_->concretize(substitution_map),
-      right_->concretize(substitution_map));
+      right_->concretize(substitution_map),
+      static_arguments_);
 }
 
 std::size_t BinaryExpression::computeHash() const {
+  std::size_t hash_code = op_signature_->hash();
   std::size_t left_hash = left_->hash();
   std::size_t right_hash = right_->hash();
 
-  if (operation_.isCommutative() && left_hash > right_hash) {
+  if (operation_->isCommutative() && left_hash > right_hash) {
     std::swap(left_hash, right_hash);
   }
+  hash_code = CombineHashes(hash_code, left_hash);
+  hash_code = CombineHashes(hash_code, right_hash);
 
-  return CombineHashes(
-      CombineHashes(static_cast<std::size_t>(ExpressionType::kBinaryExpression),
-                    static_cast<std::size_t>(operation_.getBinaryOperationID())),
-      CombineHashes(left_hash, right_hash));
+  for (const TypedValue &st_arg : *static_arguments_) {
+    if (!st_arg.isNull()) {
+      hash_code = CombineHashes(hash_code, st_arg.getHash());
+    }
+  }
+  return hash_code;
 }
 
 bool BinaryExpression::equals(const ScalarPtr &other) const {
+  // TODO
   BinaryExpressionPtr expr;
   if (SomeBinaryExpression::MatchesWithConditionalCast(other, &expr) &&
-      &operation_ == &expr->operation_) {
+      *op_signature_ == *expr->op_signature_ &&
+      *static_arguments_ == *expr->static_arguments_) {
     ScalarPtr left = left_;
     ScalarPtr right = right_;
 
-    if (operation_.isCommutative()) {
+    if (operation_->isCommutative()) {
       const bool self_order = (left_->hash() < right_->hash());
       const bool other_order = (expr->left_->hash() < expr->right_->hash());
       if (self_order ^ other_order) {
@@ -148,8 +131,26 @@ void BinaryExpression::getFieldStringItems(
     std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
     std::vector<std::string> *container_child_field_names,
     std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const {
-  container_child_field_names->push_back("");
-  container_child_fields->push_back({left_, right_});
+  inline_field_names->emplace_back("op_signature");
+  inline_field_values->emplace_back(op_signature_->toString());
+
+  inline_field_names->emplace_back("result_type");
+  inline_field_values->emplace_back(result_type_.getName());
+
+  non_container_child_field_names->emplace_back("left_operand");
+  non_container_child_fields->emplace_back(left_);
+  non_container_child_field_names->emplace_back("right_operand");
+  non_container_child_fields->emplace_back(right_);
+
+  if (!static_arguments_->empty()) {
+    container_child_field_names->emplace_back("static_arguments");
+    container_child_fields->emplace_back();
+    for (std::size_t i = 0; i < static_arguments_->size(); ++i) {
+      container_child_fields->back().emplace_back(
+          ScalarLiteral::Create(static_arguments_->at(i),
+                                *static_argument_types_->at(i)));
+    }
+  }
 }
 
 }  // namespace expressions

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/expressions/BinaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/BinaryExpression.hpp b/query_optimizer/expressions/BinaryExpression.hpp
index 6a37679..6ee6690 100644
--- a/query_optimizer/expressions/BinaryExpression.hpp
+++ b/query_optimizer/expressions/BinaryExpression.hpp
@@ -31,6 +31,8 @@
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/ExpressionType.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/binary_operations/BinaryOperation.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -61,7 +63,9 @@ class BinaryExpression : public Scalar {
 
   std::string getName() const override;
 
-  const Type& getValueType() const override;
+  const Type& getValueType() const override {
+    return result_type_;
+  }
 
   bool isConstant() const override {
     return left_->isConstant() && right_->isConstant();
@@ -70,7 +74,7 @@ class BinaryExpression : public Scalar {
   /**
    * @return The binary operation.
    */
-  const BinaryOperation& operation() const { return operation_; }
+  const BinaryOperationPtr& operation() const { return operation_; }
 
   /**
    * @return The left operand.
@@ -92,10 +96,34 @@ class BinaryExpression : public Scalar {
 
   bool equals(const ScalarPtr &other) const override;
 
-  static BinaryExpressionPtr Create(const BinaryOperation &operation,
-                                    const ScalarPtr &left,
-                                    const ScalarPtr &right) {
-    return BinaryExpressionPtr(new BinaryExpression(operation, left, right));
+  static BinaryExpressionPtr Create(
+      const OperationSignaturePtr &op_signature,
+      const BinaryOperationPtr &operation,
+      const ScalarPtr &left,
+      const ScalarPtr &right,
+      const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+      const std::shared_ptr<const std::vector<const Type*>> &static_argument_types) {
+    return BinaryExpressionPtr(
+        new BinaryExpression(op_signature,
+                             operation,
+                             left,
+                             right,
+                             static_arguments,
+                             static_argument_types));
+  }
+
+  static BinaryExpressionPtr Create(
+      const OperationSignaturePtr &op_signature,
+      const BinaryOperationPtr &operation,
+      const ScalarPtr &left,
+      const ScalarPtr &right) {
+    return BinaryExpressionPtr(
+        new BinaryExpression(op_signature,
+                             operation,
+                             left,
+                             right,
+                             std::make_shared<const std::vector<TypedValue>>(),
+                             std::make_shared<const std::vector<const Type*>>()));
   }
 
  protected:
@@ -110,14 +138,32 @@ class BinaryExpression : public Scalar {
       std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
 
  private:
-  BinaryExpression(const BinaryOperation &operation,
+  BinaryExpression(const OperationSignaturePtr &op_signature,
+                   const BinaryOperationPtr &operation,
                    const ScalarPtr &left,
-                   const ScalarPtr &right);
-
-  const BinaryOperation &operation_;
+                   const ScalarPtr &right,
+                   const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+                   const std::shared_ptr<const std::vector<const Type*>> &static_argument_types)
+      : op_signature_(op_signature),
+        operation_(operation),
+        left_(left),
+        right_(right),
+        static_arguments_(static_arguments),
+        static_argument_types_(static_argument_types),
+        result_type_(*(operation_->getResultType(left_->getValueType(),
+                                                 right_->getValueType(),
+                                                 *static_arguments))) {
+    addChild(left);
+    addChild(right);
+  }
 
-  ScalarPtr left_;
-  ScalarPtr right_;
+  const OperationSignaturePtr op_signature_;
+  const BinaryOperationPtr operation_;
+  const ScalarPtr left_;
+  const ScalarPtr right_;
+  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_;
+  const std::shared_ptr<const std::vector<const Type*>> static_argument_types_;
+  const Type &result_type_;
 
   DISALLOW_COPY_AND_ASSIGN(BinaryExpression);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/CMakeLists.txt b/query_optimizer/expressions/CMakeLists.txt
index 3e7f8e4..dc722e7 100644
--- a/query_optimizer/expressions/CMakeLists.txt
+++ b/query_optimizer/expressions/CMakeLists.txt
@@ -20,7 +20,6 @@ add_library(quickstep_queryoptimizer_expressions_AggregateFunction AggregateFunc
 add_library(quickstep_queryoptimizer_expressions_Alias Alias.cpp Alias.hpp)
 add_library(quickstep_queryoptimizer_expressions_AttributeReference AttributeReference.cpp AttributeReference.hpp)
 add_library(quickstep_queryoptimizer_expressions_BinaryExpression BinaryExpression.cpp BinaryExpression.hpp)
-add_library(quickstep_queryoptimizer_expressions_Cast Cast.cpp Cast.hpp)
 add_library(quickstep_queryoptimizer_expressions_CommonSubexpression
             CommonSubexpression.cpp
             CommonSubexpression.hpp)
@@ -97,23 +96,9 @@ target_link_libraries(quickstep_queryoptimizer_expressions_BinaryExpression
                       quickstep_queryoptimizer_expressions_ExpressionType
                       quickstep_queryoptimizer_expressions_PatternMatcher
                       quickstep_queryoptimizer_expressions_Scalar
+                      quickstep_queryoptimizer_expressions_ScalarLiteral
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_utility_HashPair
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_queryoptimizer_expressions_Cast
-                      glog
-                      quickstep_expressions_scalar_Scalar
-                      quickstep_expressions_scalar_ScalarUnaryExpression
-                      quickstep_queryoptimizer_OptimizerTree
-                      quickstep_queryoptimizer_expressions_AttributeReference
-                      quickstep_queryoptimizer_expressions_ExprId
-                      quickstep_queryoptimizer_expressions_Expression
-                      quickstep_queryoptimizer_expressions_ExpressionType
-                      quickstep_queryoptimizer_expressions_PatternMatcher
-                      quickstep_queryoptimizer_expressions_Scalar
-                      quickstep_types_Type
-                      quickstep_types_operations_unaryoperations_NumericCastOperation
                       quickstep_utility_HashPair
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_CommonSubexpression
@@ -325,8 +310,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_HashPair
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_expressions_WindowAggregateFunction
@@ -350,7 +336,6 @@ target_link_libraries(quickstep_queryoptimizer_expressions
                       quickstep_queryoptimizer_expressions_Alias
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_BinaryExpression
-                      quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_CommonSubexpression
                       quickstep_queryoptimizer_expressions_ComparisonExpression
                       quickstep_queryoptimizer_expressions_Exists

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/expressions/Cast.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Cast.cpp b/query_optimizer/expressions/Cast.cpp
deleted file mode 100644
index e6eb1bd..0000000
--- a/query_optimizer/expressions/Cast.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "query_optimizer/expressions/Cast.hpp"
-
-#include <cstddef>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "expressions/scalar/Scalar.hpp"
-#include "expressions/scalar/ScalarUnaryExpression.hpp"
-#include "query_optimizer/OptimizerTree.hpp"
-#include "query_optimizer/expressions/AttributeReference.hpp"
-#include "query_optimizer/expressions/ExprId.hpp"
-#include "query_optimizer/expressions/Expression.hpp"
-#include "query_optimizer/expressions/PatternMatcher.hpp"
-#include "query_optimizer/expressions/Scalar.hpp"
-#include "types/Type.hpp"
-#include "types/operations/unary_operations/NumericCastOperation.hpp"
-#include "utility/HashPair.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-namespace optimizer {
-namespace expressions {
-
-ExpressionPtr Cast::copyWithNewChildren(
-    const std::vector<ExpressionPtr> &new_children) const {
-  DCHECK_EQ(getNumChildren(), new_children.size());
-  ScalarPtr scalar;
-  CHECK(SomeScalar::MatchesWithConditionalCast(new_children[0], &scalar))
-      << new_children[0]->toString();
-  return Create(scalar, target_type_);
-}
-
-::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));
-}
-
-std::size_t Cast::computeHash() const {
-  return CombineHashes(
-      CombineHashes(static_cast<std::size_t>(ExpressionType::kCast),
-                    operand_->hash()),
-      static_cast<std::size_t>(target_type_.getTypeID()));
-}
-
-bool Cast::equals(const ScalarPtr &other) const {
-  CastPtr expr;
-  if (SomeCast::MatchesWithConditionalCast(other, &expr)) {
-    return operand_->equals(expr->operand_) && target_type_.equals(expr->target_type_);
-  }
-  return false;
-}
-
-void Cast::getFieldStringItems(
-    std::vector<std::string> *inline_field_names,
-    std::vector<std::string> *inline_field_values,
-    std::vector<std::string> *non_container_child_field_names,
-    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_);
-}
-
-}  // namespace expressions
-}  // namespace optimizer
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/expressions/Cast.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/Cast.hpp b/query_optimizer/expressions/Cast.hpp
deleted file mode 100644
index 11be775..0000000
--- a/query_optimizer/expressions/Cast.hpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * 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_QUERY_OPTIMIZER_EXPRESSIONS_CAST_HPP_
-#define QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_CAST_HPP_
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "query_optimizer/OptimizerTree.hpp"
-#include "query_optimizer/expressions/AttributeReference.hpp"
-#include "query_optimizer/expressions/ExprId.hpp"
-#include "query_optimizer/expressions/Expression.hpp"
-#include "query_optimizer/expressions/ExpressionType.hpp"
-#include "query_optimizer/expressions/Scalar.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-class CatalogAttribute;
-class Type;
-
-namespace optimizer {
-namespace expressions {
-
-/** \addtogroup OptimizerExpressions
- *  @{
- */
-
-class Cast;
-typedef std::shared_ptr<const Cast> CastPtr;
-
-/**
- * @brief Converts a value of a type to another type.
- */
-class Cast : public Scalar {
- public:
-  ExpressionType getExpressionType() const override { return ExpressionType::kCast; }
-
-  std::string getName() const override { return "Cast"; }
-
-  const Type& getValueType() const override { return target_type_; }
-
-  bool isConstant() const override { return operand_->isConstant(); }
-
-  /**
-   * @return The expression to be coerced.
-   */
-  const ScalarPtr& operand() const { return operand_; }
-
-  std::vector<AttributeReferencePtr> getReferencedAttributes() const override {
-    return operand_->getReferencedAttributes();
-  }
-
-  ExpressionPtr copyWithNewChildren(
-      const std::vector<ExpressionPtr> &new_children) const override;
-
-  ::quickstep::Scalar* concretize(
-      const std::unordered_map<ExprId, const CatalogAttribute*> &substitution_map) const override;
-
-  bool equals(const ScalarPtr &other) const override;
-
-  /**
-   * @brief Creates a Cast expression that converts \p operand to \p target_type.
-   *
-   * @param operand The input expression to be coerced.
-   * @param target_type The target type that the expression is converted to.
-   * @return A Cast expression.
-   */
-  static CastPtr Create(const ScalarPtr &operand, const Type &target_type) {
-    return CastPtr(new Cast(operand, target_type));
-  }
-
- protected:
-  std::size_t computeHash() const override;
-
-  void getFieldStringItems(
-      std::vector<std::string> *inline_field_names,
-      std::vector<std::string> *inline_field_values,
-      std::vector<std::string> *non_container_child_field_names,
-      std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
-      std::vector<std::string> *container_child_field_names,
-      std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;
-
- private:
-  Cast(const ScalarPtr &operand, const Type &target_type)
-      : operand_(operand),
-        target_type_(target_type) {
-    addChild(operand);
-    DCHECK(target_type.isCoercibleFrom(operand->getValueType()));
-  }
-
-  ScalarPtr operand_;
-  const Type &target_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(Cast);
-};
-
-/** @} */
-
-}  // namespace expressions
-}  // namespace optimizer
-}  // namespace quickstep
-
-#endif /* QUICKSTEP_QUERY_OPTIMIZER_EXPRESSIONS_CAST_HPP_ */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/expressions/UnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.cpp b/query_optimizer/expressions/UnaryExpression.cpp
index b448553..e1ad014 100644
--- a/query_optimizer/expressions/UnaryExpression.cpp
+++ b/query_optimizer/expressions/UnaryExpression.cpp
@@ -30,8 +30,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 "utility/HashPair.hpp"
 
 #include "glog/logging.h"
@@ -41,7 +41,7 @@ namespace optimizer {
 namespace expressions {
 
 std::string UnaryExpression::getName() const {
-  return operation_.getName();
+  return op_signature_->getName();
 }
 
 ExpressionPtr UnaryExpression::copyWithNewChildren(
@@ -49,26 +49,39 @@ 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_);
 }
 
 std::size_t UnaryExpression::computeHash() const {
-  return CombineHashes(
-      CombineHashes(static_cast<std::size_t>(ExpressionType::kUnaryExpression),
-                    static_cast<std::size_t>(operation_.getUnaryOperationID())),
-      operand_->hash());
+  std::size_t hash_code = CombineHashes(op_signature_->hash(),
+                                        operand_->hash());
+  for (const TypedValue &st_arg : *static_arguments_) {
+    if (!st_arg.isNull()) {
+      hash_code = CombineHashes(hash_code, st_arg.getHash());
+    }
+  }
+  return hash_code;
 }
 
 bool UnaryExpression::equals(const ScalarPtr &other) const {
   UnaryExpressionPtr expr;
   if (SomeUnaryExpression::MatchesWithConditionalCast(other, &expr)) {
-    return &operation_ == &expr->operation_ && operand_->equals(expr->operand_);
+    return *op_signature_ == *expr->op_signature_
+        && operand_->equals(expr->operand_)
+        && *static_arguments_ == *expr->static_arguments_;
   }
   return false;
 }
@@ -80,8 +93,24 @@ 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());
+
+  inline_field_names->emplace_back("result_type");
+  inline_field_values->emplace_back(result_type_.getName());
+
+  non_container_child_field_names->emplace_back("operand");
+  non_container_child_fields->emplace_back(operand_);
+
+  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/9b23a4d3/query_optimizer/expressions/UnaryExpression.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/UnaryExpression.hpp b/query_optimizer/expressions/UnaryExpression.hpp
index 14201ff..bbb1841 100644
--- a/query_optimizer/expressions/UnaryExpression.hpp
+++ b/query_optimizer/expressions/UnaryExpression.hpp
@@ -31,6 +31,7 @@
 #include "query_optimizer/expressions/Expression.hpp"
 #include "query_optimizer/expressions/ExpressionType.hpp"
 #include "query_optimizer/expressions/Scalar.hpp"
+#include "types/operations/OperationSignature.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
 #include "utility/Macros.hpp"
 
@@ -65,7 +66,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.
@@ -73,7 +74,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(
@@ -96,9 +97,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:
@@ -113,15 +123,26 @@ 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_))) {
     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/9b23a4d3/query_optimizer/resolver/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/CMakeLists.txt b/query_optimizer/resolver/CMakeLists.txt
index 6feb1e8..a759ce3 100644
--- a/query_optimizer/resolver/CMakeLists.txt
+++ b/query_optimizer/resolver/CMakeLists.txt
@@ -74,7 +74,6 @@ target_link_libraries(quickstep_queryoptimizer_resolver_Resolver
                       quickstep_queryoptimizer_expressions_Alias
                       quickstep_queryoptimizer_expressions_AttributeReference
                       quickstep_queryoptimizer_expressions_BinaryExpression
-                      quickstep_queryoptimizer_expressions_Cast
                       quickstep_queryoptimizer_expressions_ComparisonExpression
                       quickstep_queryoptimizer_expressions_Exists
                       quickstep_queryoptimizer_expressions_ExprId
@@ -123,14 +122,15 @@ 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_OperationFactory
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID
-                      quickstep_types_operations_unaryoperations_DateExtractOperation
-                      quickstep_types_operations_unaryoperations_SubstringOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_utility_BulkIoConfiguration
                       quickstep_utility_Macros

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 935e235..53fa000 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -70,7 +70,6 @@
 #include "query_optimizer/expressions/Alias.hpp"
 #include "query_optimizer/expressions/AttributeReference.hpp"
 #include "query_optimizer/expressions/BinaryExpression.hpp"
-#include "query_optimizer/expressions/Cast.hpp"
 #include "query_optimizer/expressions/ComparisonExpression.hpp"
 #include "query_optimizer/expressions/Exists.hpp"
 #include "query_optimizer/expressions/ExprId.hpp"
@@ -118,14 +117,15 @@
 #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/OperationFactory.hpp"
+#include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
 #include "types/operations/comparisons/Comparison.hpp"
 #include "types/operations/comparisons/ComparisonFactory.hpp"
 #include "types/operations/comparisons/ComparisonID.hpp"
-#include "types/operations/unary_operations/DateExtractOperation.hpp"
-#include "types/operations/unary_operations/SubstringOperation.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
 #include "utility/BulkIoConfiguration.hpp"
 #include "utility/PtrList.hpp"
@@ -151,16 +151,13 @@ 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;
 }
 
@@ -1021,14 +1018,15 @@ L::LogicalPtr Resolver::resolveInsertSelection(
           selection_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
           destination_type.isSafelyCoercibleFrom(selection_type)) {
         // Add cast operation
-        const E::AttributeReferencePtr attr = selection_attributes[aid];
-        const E::ExpressionPtr cast_expr =
-            E::Cast::Create(attr, destination_type);
-        cast_expressions.emplace_back(
-            E::Alias::Create(context_->nextExprId(),
-                             cast_expr,
-                             attr->attribute_name(),
-                             attr->attribute_alias()));
+//        const E::AttributeReferencePtr attr = selection_attributes[aid];
+//        const E::ExpressionPtr cast_expr =
+//            E::Cast::Create(attr, destination_type);
+//        cast_expressions.emplace_back(
+//            E::Alias::Create(context_->nextExprId(),
+//                             cast_expr,
+//                             attr->attribute_name(),
+//                             attr->attribute_alias()));
+        THROW_SQL_ERROR_AT(insert_statement.relation_name()) << "TODO: not handled";
       } else {
         THROW_SQL_ERROR_AT(insert_statement.relation_name())
             << "The assigned value for the column "
@@ -1166,8 +1164,9 @@ L::LogicalPtr Resolver::resolveUpdate(
     // Coerce the assignment expression if its Type is not equal to that of the
     // assigned attribute.
     if (!assignment_expression->getValueType().equals(attribute->getValueType())) {
-      assignment_expression =
-          E::Cast::Create(assignment_expression, attribute->getValueType());
+//      assignment_expression =
+//          E::Cast::Create(assignment_expression, attribute->getValueType());
+      THROW_SQL_ERROR_AT(&assignment) << "TODO: not handled";
     }
     if (assignee_ids.find(attribute->id()) != assignee_ids.end()) {
       THROW_SQL_ERROR_AT(&assignment) << "Multiple assignments to the column "
@@ -1585,11 +1584,12 @@ L::LogicalPtr Resolver::resolveSetOperations(
       if (possible_type.equals(current_type)) {
         cast_expressions.emplace_back(current_attr);
       } else {
-        cast_expressions.emplace_back(
-            E::Alias::Create(context_->nextExprId(),
-                             E::Cast::Create(current_attr, possible_type),
-                             current_attr->attribute_name(),
-                             current_attr->attribute_alias()));
+//        cast_expressions.emplace_back(
+//            E::Alias::Create(context_->nextExprId(),
+//                             E::Cast::Create(current_attr, possible_type),
+//                             current_attr->attribute_name(),
+//                             current_attr->attribute_alias()));
+        LOG(FATAL) << "TODO: not handled";
       }
     }
     resolved_operations[opid] = L::Project::Create(resolved_operations[opid], cast_expressions);
@@ -2441,109 +2441,6 @@ E::ScalarPtr Resolver::resolveExpression(
           parse_attribute_scalar.attr_name(),
           parse_attribute_scalar.rel_name());
     }
-    case ParseExpression::kBinaryExpression: {
-      const ParseBinaryExpression &parse_binary_scalar =
-          static_cast<const ParseBinaryExpression&>(parse_expression);
-
-      std::pair<const Type*, const Type*> argument_type_hints
-          = parse_binary_scalar.op().pushDownTypeHint(type_hint);
-
-      ExpressionResolutionInfo left_resolution_info(
-          *expression_resolution_info);
-      E::ScalarPtr left_argument = resolveExpression(
-          *parse_binary_scalar.left_operand(),
-           argument_type_hints.first,
-           &left_resolution_info);
-
-      ExpressionResolutionInfo right_resolution_info(
-          *expression_resolution_info);
-      E::ScalarPtr right_argument = resolveExpression(
-          *parse_binary_scalar.right_operand(),
-          argument_type_hints.second,
-          &right_resolution_info);
-
-      if (left_resolution_info.hasAggregate()) {
-        expression_resolution_info->parse_aggregate_expression =
-            left_resolution_info.parse_aggregate_expression;
-      } else if (right_resolution_info.hasAggregate()) {
-        expression_resolution_info->parse_aggregate_expression =
-            right_resolution_info.parse_aggregate_expression;
-      }
-
-      // Check if either argument is a NULL literal of an unknown type.
-      const bool left_is_nulltype = (left_argument->getValueType().getTypeID() == kNullType);
-      const bool right_is_nulltype = (right_argument->getValueType().getTypeID() == kNullType);
-
-      // If either argument is a NULL of unknown type, we try to resolve the
-      // type of this BinaryExpression as follows:
-      //
-      //     1. If there is only one possible result type for the expression
-      //        based on what is known about its argument types, then the
-      //        result is a NULL of that type.
-      //     2. Otherwise, if there is a type hint for the BinaryExpression's
-      //        result, and if it is a plausible result type based on what we
-      //        know about argument types, then the result is a NULL of the
-      //        hint type.
-      //     3. Otherwise, check if the BinaryExpression can plausibly be
-      //        applied to the known argument types at all. If so, then the
-      //        result is a NULL of unknown type (i.e. NullType).
-      //     4. If all of the above steps fail, then the BinaryExpression is
-      //        not possibly applicable to the given arguments.
-      //
-      // NOTE(chasseur): Step #3 above does not completely capture knowledge
-      // about the result type of a BinaryExpression with one or more unknown
-      // arguments. For instance, DivideBinaryOperation can never return a
-      // DateTime or any string type, so even if we do not know its specific
-      // return type, we do know that there are some restrictions on what it
-      // may be. However, NullType is implicitly convertable to ANY Type, so
-      // such restrictions could be violated if a parent node in the expression
-      // tree converts a value of NullType to something that it shouldn't be.
-      if (left_is_nulltype || right_is_nulltype) {
-        const Type *fixed_result_type
-            = parse_binary_scalar.op().resultTypeForPartialArgumentTypes(
-                left_is_nulltype ? nullptr : &(left_argument->getValueType()),
-                right_is_nulltype ? nullptr : &(right_argument->getValueType()));
-        if (fixed_result_type != nullptr) {
-          return E::ScalarLiteral::Create(fixed_result_type->makeNullValue(),
-                                          *fixed_result_type);
-        }
-
-        if (type_hint != nullptr) {
-          const Type &nullable_type_hint = type_hint->getNullableVersion();
-          if (parse_binary_scalar.op().partialTypeSignatureIsPlausible(
-                  &nullable_type_hint,
-                  left_is_nulltype ? nullptr : &(left_argument->getValueType()),
-                  right_is_nulltype ? nullptr : &(right_argument->getValueType()))) {
-            return E::ScalarLiteral::Create(nullable_type_hint.makeNullValue(),
-                                            nullable_type_hint);
-          }
-        }
-
-        if (parse_binary_scalar.op().partialTypeSignatureIsPlausible(
-                nullptr,
-                left_is_nulltype ? nullptr : &(left_argument->getValueType()),
-                right_is_nulltype ? nullptr : &(right_argument->getValueType()))) {
-          const Type &null_type = TypeFactory::GetType(kNullType, true);
-          return E::ScalarLiteral::Create(null_type.makeNullValue(),
-                                          null_type);
-        }
-
-        // If nothing above worked, fall through to canApplyToTypes() below,
-        // which should fail.
-      }
-
-      if (!parse_binary_scalar.op().canApplyToTypes(left_argument->getValueType(),
-                                                    right_argument->getValueType())) {
-        THROW_SQL_ERROR_AT(&parse_binary_scalar)
-            << "Can not apply binary operation \"" << parse_binary_scalar.op().getName()
-            << "\" to arguments of types " << left_argument->getValueType().getName()
-            << " and " << right_argument->getValueType().getName();
-      }
-
-      return E::BinaryExpression::Create(parse_binary_scalar.op(),
-                                         left_argument,
-                                         right_argument);
-    }
     case ParseExpression::kScalarLiteral: {
       const ParseScalarLiteral &parse_literal_scalar =
           static_cast<const ParseScalarLiteral&>(parse_expression);
@@ -2568,57 +2465,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),
@@ -2632,75 +2478,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();
@@ -2794,13 +2571,15 @@ E::ScalarPtr Resolver::resolveSearchedCaseExpression(
   // Cast all the result expressions to the same type.
   for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) {
     if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-      conditional_result_expression =
-          E::Cast::Create(conditional_result_expression, *result_data_type);
+//      conditional_result_expression =
+//          E::Cast::Create(conditional_result_expression, *result_data_type);
+      LOG(FATAL) << "TODO: not handled";
     }
   }
   if (else_result_expression != nullptr
       && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
+//    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
+    LOG(FATAL) << "TODO: not handled";
   }
 
   if (else_result_expression == nullptr) {
@@ -2938,13 +2717,15 @@ E::ScalarPtr Resolver::resolveSimpleCaseExpression(
   // Cast all the result expressions to the same type.
   for (E::ScalarPtr &conditional_result_expression : conditional_result_expressions) {
     if (conditional_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-      conditional_result_expression =
-          E::Cast::Create(conditional_result_expression, *result_data_type);
+//      conditional_result_expression =
+//          E::Cast::Create(conditional_result_expression, *result_data_type);
+      LOG(FATAL) << "TODO: not handled";
     }
   }
   if (else_result_expression != nullptr
       && else_result_expression->getValueType().getTypeID() != result_data_type->getTypeID()) {
-    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
+//    else_result_expression = E::Cast::Create(else_result_expression, *result_data_type);
+    LOG(FATAL) << "TODO: not handled";
   }
 
   if (else_result_expression == nullptr) {
@@ -2960,6 +2741,85 @@ 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::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;
+    }
+    argument_types.emplace_back(&argument->getValueType());
+  }
+
+  std::vector<TypedValue> static_arguments;
+  for (std::size_t i = first_static_argument_position; i < arity; ++i) {
+    static_arguments.emplace_back(
+        std::static_pointer_cast<const E::ScalarLiteral>(
+            resolved_arguments[i])->value());
+    DCHECK(static_arguments.back().getTypeID() == argument_types[i]->getTypeID());
+  }
+
+  std::shared_ptr<const std::vector<const Type*>> coerced_argument_types;
+  std::shared_ptr<const std::vector<TypedValue>> coerced_static_arguments;
+  std::string message;
+  const OperationSignaturePtr op_signature =
+      OperationFactory::Instance().resolveOperation(
+          function_name,
+          std::make_shared<const std::vector<const Type*>>(std::move(argument_types)),
+          std::make_shared<const std::vector<TypedValue>>(std::move(static_arguments)),
+          &coerced_argument_types,
+          &coerced_static_arguments,
+          &message);
+
+  if (op_signature == nullptr) {
+    if (message.empty()) {
+      THROW_SQL_ERROR_AT(&parse_function_call) << message;
+    } else {
+      THROW_SQL_ERROR_AT(&parse_function_call)
+          << "Cannot resolve scalar function " << function_name;
+    }
+  }
+
+  // TODO: add cast if neccessary.
+
+  const auto coerced_static_argument_types =
+      std::make_shared<const std::vector<const Type*>>(
+          coerced_argument_types->begin() + op_signature->getNonStaticArity(),
+          coerced_argument_types->end());
+
+  const OperationPtr operation =
+      OperationFactory::Instance().getOperation(op_signature);
+  switch (operation->getOperationSuperTypeID()) {
+    case Operation::kUnaryOperation:
+      return E::UnaryExpression::Create(
+          op_signature,
+          std::static_pointer_cast<const UnaryOperation>(operation),
+          resolved_arguments[0],
+          coerced_static_arguments,
+          coerced_static_argument_types);
+    case Operation::kBinaryOperation:
+      return E::BinaryExpression::Create(
+          op_signature,
+          std::static_pointer_cast<const BinaryOperation>(operation),
+          resolved_arguments[0],
+          resolved_arguments[1],
+          coerced_static_arguments,
+          coerced_static_argument_types);
+    default: {
+      const auto operation_id =
+         static_cast<std::underlying_type_t<Operation::OperationSuperTypeID>>(
+             operation->getOperationSuperTypeID());
+      LOG(FATAL) << "Unknown opeation super type id: " << operation_id;
+    }
+  }
+}
+
 // 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,
@@ -2980,8 +2840,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;
@@ -2989,7 +2848,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));
@@ -3008,6 +2867,17 @@ E::ScalarPtr Resolver::resolveFunctionCall(
     }
   }
 
+  if (OperationFactory::Instance().hasOperation(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/9b23a4d3/query_optimizer/resolver/Resolver.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.hpp b/query_optimizer/resolver/Resolver.hpp
index 1784782..bb924bb 100644
--- a/query_optimizer/resolver/Resolver.hpp
+++ b/query_optimizer/resolver/Resolver.hpp
@@ -480,9 +480,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
@@ -493,6 +490,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/9b23a4d3/query_optimizer/rules/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/CMakeLists.txt b/query_optimizer/rules/CMakeLists.txt
index 73a80d2..f578bb8 100644
--- a/query_optimizer/rules/CMakeLists.txt
+++ b/query_optimizer/rules/CMakeLists.txt
@@ -296,9 +296,9 @@ target_link_libraries(quickstep_queryoptimizer_rules_ReuseAggregateExpressions
                       quickstep_queryoptimizer_physical_Selection
                       quickstep_queryoptimizer_physical_TopLevelPlan
                       quickstep_queryoptimizer_rules_BottomUpRule
+                      quickstep_types_operations_OperationFactory
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_HashError
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_queryoptimizer_rules_Rule

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/rules/ReuseAggregateExpressions.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/ReuseAggregateExpressions.cpp b/query_optimizer/rules/ReuseAggregateExpressions.cpp
index a7c62c6..d63715a 100644
--- a/query_optimizer/rules/ReuseAggregateExpressions.cpp
+++ b/query_optimizer/rules/ReuseAggregateExpressions.cpp
@@ -44,9 +44,9 @@
 #include "query_optimizer/physical/PhysicalType.hpp"
 #include "query_optimizer/physical/Selection.hpp"
 #include "query_optimizer/physical/TopLevelPlan.hpp"
+#include "types/operations/OperationFactory.hpp"
+#include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "utility/HashError.hpp"
 
 #include "gflags/gflags.h"
@@ -317,12 +317,19 @@ P::PhysicalPtr ReuseAggregateExpressions::applyToNode(
           }
 
           // Obtain AVG by evaluating SUM/COUNT in Selection.
-          const BinaryOperation &divide_op =
-              BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide);
+          const E::AttributeReferencePtr &count_attr = agg_attrs[agg_ref->second_ref];
+          const std::vector<TypeID> operand_tids =
+              { sum_attr->getValueType().getTypeID(), count_attr->getValueType().getTypeID() };
+          const OperationSignaturePtr op_sig =
+              OperationSignature::Create("/", operand_tids, 0);
+
+          const BinaryOperationPtr &divide_op =
+              OperationFactory::Instance().getBinaryOperation(op_sig);
           const E::BinaryExpressionPtr avg_expr =
-              E::BinaryExpression::Create(divide_op,
+              E::BinaryExpression::Create(op_sig,
+                                          divide_op,
                                           sum_attr,
-                                          agg_attrs[agg_ref->second_ref]);
+                                          count_attr);
           new_select_exprs.emplace_back(
               E::Alias::Create(agg_expr->id(),
                                avg_expr,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/rules/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/tests/CMakeLists.txt b/query_optimizer/rules/tests/CMakeLists.txt
index 42fa9c1..170116f 100644
--- a/query_optimizer/rules/tests/CMakeLists.txt
+++ b/query_optimizer/rules/tests/CMakeLists.txt
@@ -87,8 +87,6 @@ target_link_libraries(quickstep_queryoptimizer_rules_tests
                       quickstep_queryoptimizer_rules_tests_PhysicalRuleTest
                       quickstep_queryoptimizer_rules_tests_RuleTest
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/strategy/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/strategy/tests/CMakeLists.txt b/query_optimizer/strategy/tests/CMakeLists.txt
index 97675f0..f502583 100644
--- a/query_optimizer/strategy/tests/CMakeLists.txt
+++ b/query_optimizer/strategy/tests/CMakeLists.txt
@@ -73,8 +73,6 @@ target_link_libraries(quickstep_queryoptimizer_strategy_tests
                       quickstep_queryoptimizer_strategy_tests_StrategyTest
                       quickstep_types_TypeID
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/CMakeLists.txt b/query_optimizer/tests/CMakeLists.txt
index 5ef1d0a..bde0495 100644
--- a/query_optimizer/tests/CMakeLists.txt
+++ b/query_optimizer/tests/CMakeLists.txt
@@ -50,8 +50,6 @@ target_link_libraries(quickstep_queryoptimizer_tests_OptimizerTest
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/query_optimizer/tests/OptimizerTest.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/tests/OptimizerTest.cpp b/query_optimizer/tests/OptimizerTest.cpp
index 7eb7a11..4c94f2d 100644
--- a/query_optimizer/tests/OptimizerTest.cpp
+++ b/query_optimizer/tests/OptimizerTest.cpp
@@ -43,8 +43,6 @@
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "types/operations/comparisons/Comparison.hpp"
 #include "types/operations/comparisons/ComparisonFactory.hpp"
 #include "types/operations/comparisons/ComparisonID.hpp"

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/relational_operators/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/relational_operators/CMakeLists.txt b/relational_operators/CMakeLists.txt
index 7b9ed96..0ce89a1 100644
--- a/relational_operators/CMakeLists.txt
+++ b/relational_operators/CMakeLists.txt
@@ -714,8 +714,6 @@ target_link_libraries(AggregationOperator_unittest
                       quickstep_types_LongType
                       quickstep_types_TypedValue
                       quickstep_types_containers_Tuple
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID
                       quickstep_utility_Macros

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/storage/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/storage/CMakeLists.txt b/storage/CMakeLists.txt
index fb09e49..e061ff7 100644
--- a/storage/CMakeLists.txt
+++ b/storage/CMakeLists.txt
@@ -826,7 +826,7 @@ target_link_libraries(quickstep_storage_PackedPayloadHashTable
                       quickstep_utility_HashPair
                       quickstep_utility_Macros
                       quickstep_utility_PrimeNumber
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Dispatchers)
 target_link_libraries(quickstep_storage_PartitionedHashTablePool
                       glog
                       quickstep_storage_HashTableBase
@@ -870,9 +870,8 @@ target_link_libraries(quickstep_storage_SMAIndexSubBlock
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
+                      quickstep_types_operations_OperationFactory
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/storage/PackedPayloadHashTable.cpp
----------------------------------------------------------------------
diff --git a/storage/PackedPayloadHashTable.cpp b/storage/PackedPayloadHashTable.cpp
index 1df20d0..77f512b 100644
--- a/storage/PackedPayloadHashTable.cpp
+++ b/storage/PackedPayloadHashTable.cpp
@@ -40,7 +40,7 @@
 #include "utility/Alignment.hpp"
 #include "utility/Macros.hpp"
 #include "utility/PrimeNumber.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Dispatchers.hpp"
 
 #include "glog/logging.h"
 
@@ -246,7 +246,7 @@ bool PackedPayloadHashTable::upsertValueAccessorCompositeKey(
     derived_accessor->beginIterationVirtual();
   }
 
-  return InvokeOnBools(
+  return meta::InvokeOnBools(
       handles_.empty(),
       !all_keys_inline_,
       [&](auto key_only,  // NOLINT(build/c++11)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/storage/SMAIndexSubBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/SMAIndexSubBlock.cpp b/storage/SMAIndexSubBlock.cpp
index 81cf6c0..96a744e 100644
--- a/storage/SMAIndexSubBlock.cpp
+++ b/storage/SMAIndexSubBlock.cpp
@@ -44,9 +44,8 @@
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
+#include "types/operations/OperationFactory.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "types/operations/comparisons/Comparison.hpp"
 #include "types/operations/comparisons/ComparisonFactory.hpp"
 #include "types/operations/comparisons/ComparisonID.hpp"
@@ -359,9 +358,10 @@ SMAIndexSubBlock::SMAIndexSubBlock(const TupleStorageSubBlock &tuple_store,
       TypeID attr_sum_typeid = sma_internal::getTypeForSum(attr_typeid);
       if (add_operations_.elementIsNullAt(attr_typeid)) {
         add_operations_.replaceElement(attr_typeid,
-          BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-              .makeUncheckedBinaryOperatorForTypes(TypeFactory::GetType(attr_typeid),
-                                                   TypeFactory::GetType(attr_sum_typeid)));
+            OperationFactory::Instance().getBinaryOperation(
+                "+", {attr_typeid, attr_sum_typeid})
+                    ->makeUncheckedBinaryOperator(TypeFactory::GetType(attr_typeid),
+                                                  TypeFactory::GetType(attr_sum_typeid)));
       }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/AsciiStringSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp
new file mode 100644
index 0000000..959c288
--- /dev/null
+++ b/types/AsciiStringSuperType.hpp
@@ -0,0 +1,78 @@
+/**
+ * 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_ASCII_STRING_SUPER_TYPE_HPP_
+#define QUICKSTEP_TYPES_ASCII_STRING_SUPER_TYPE_HPP_
+
+#include <cstddef>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief A superclass for ASCII string types.
+ **/
+template <TypeID type_id>
+class AsciiStringSuperType : public TypeSynthesizer<type_id> {
+ public:
+  bool isCoercibleFrom(const Type &original_type) const override {
+    if (original_type.isNullable() && !this->nullable_) {
+      return false;
+    }
+    return (original_type.getSuperTypeID() == Type::kAsciiString)
+           || (original_type.getTypeID() == kNullType);
+  }
+
+  /**
+   * @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 bool nullable,
+                       const std::size_t minimum_byte_length,
+                       const std::size_t maximum_byte_length,
+                       const std::size_t string_length)
+      : TypeSynthesizer<type_id>(
+            nullable, minimum_byte_length, maximum_byte_length, string_length),
+        length_(string_length) {
+  }
+
+  const std::size_t length_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AsciiStringSuperType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_ASCII_STRING_SUPER_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/BoolType.cpp
----------------------------------------------------------------------
diff --git a/types/BoolType.cpp b/types/BoolType.cpp
new file mode 100644
index 0000000..83cf060
--- /dev/null
+++ b/types/BoolType.cpp
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/BoolType.hpp"
+
+#include <cstdio>
+#include <string>
+
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "utility/StringUtil.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+std::string BoolType::printValueToString(const TypedValue &value) const {
+  DCHECK(!value.isNull());
+
+  return value.getLiteral<bool>() ? "true" : "false";
+}
+
+void BoolType::printValueToFile(const TypedValue &value,
+                                FILE *file,
+                                const int padding) const {
+  DCHECK(!value.isNull());
+
+  std::fprintf(file,
+               "%*s",
+               static_cast<int>(padding),
+               value.getLiteral<bool>() ? "true" : "false");
+}
+
+bool BoolType::parseValueFromString(const std::string &value_string,
+                                    TypedValue *value) const {
+  const std::string lo_value = ToLower(value_string);
+  if (lo_value == "true") {
+    *value = TypedValue(true);
+    return true;
+  } else if (lo_value == "false") {
+    *value = TypedValue(false);
+    return true;
+  }
+  return false;
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/BoolType.hpp
----------------------------------------------------------------------
diff --git a/types/BoolType.hpp b/types/BoolType.hpp
new file mode 100644
index 0000000..f149e76
--- /dev/null
+++ b/types/BoolType.hpp
@@ -0,0 +1,73 @@
+/**
+ * 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_BOOL_TYPE_HPP_
+#define QUICKSTEP_TYPES_BOOL_TYPE_HPP_
+
+#include <array>
+#include <cstdio>
+#include <limits>
+#include <string>
+
+#include "types/NumericSuperType.hpp"
+#include "types/TypeID.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+class Type;
+class TypedValue;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief A type representing a 8-bit bool.
+ **/
+class BoolType : public NumericSuperType<kBool> {
+ public:
+  int getPrintWidth() const override {
+    // "true" or "false"
+    return 5;
+  }
+
+  std::string printValueToString(const TypedValue &value) const override;
+
+  void printValueToFile(const TypedValue &value,
+                        FILE *file,
+                        const int padding = 0) const override;
+
+  bool parseValueFromString(const std::string &value_string,
+                            TypedValue *value) const override;
+
+ private:
+  explicit BoolType(const bool nullable)
+      : NumericSuperType<kBool>(nullable) {}
+
+  template <typename, bool> friend class TypeInstance;
+
+  DISALLOW_COPY_AND_ASSIGN(BoolType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_BOOL_TYPE_HPP_


[10/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/BinaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationWrapper.hpp b/types/operations/binary_operations/BinaryOperationWrapper.hpp
new file mode 100644
index 0000000..98c2e8d
--- /dev/null
+++ b/types/operations/binary_operations/BinaryOperationWrapper.hpp
@@ -0,0 +1,629 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_WRAPPER_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_WRAPPER_HPP_
+
+#include <cstddef>
+#include <list>
+#include <string>
+#include <tuple>
+#include <type_traits>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "storage/ValueAccessor.hpp"
+#include "storage/ValueAccessorUtil.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/binary_operations/BinaryOperation.hpp"
+#include "utility/Macros.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename LeftArgumentT, typename RightArgumentT, typename ResultT>
+struct BinaryFunctor {
+  typedef LeftArgumentT LeftArgumentType;
+  typedef RightArgumentT RightArgumentType;
+  typedef ResultT ResultType;
+
+  static constexpr Operation
+      ::OperationSuperTypeID kOperationSuperTypeID = Operation::kBinaryOperation;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+class UncheckedBinaryOperatorWrapperCodegen : public UncheckedBinaryOperator {
+ public:
+  template <typename ...ConstructorArgs>
+  UncheckedBinaryOperatorWrapperCodegen(const Type &left_type,
+                                        const Type &right_type,
+                                        const Type &result_type,
+                                        ConstructorArgs &&...args)
+      : functor_(std::forward<ConstructorArgs>(args)...),
+        impl_(functor_, left_type, right_type, result_type) {}
+
+  TypedValue applyToTypedValues(const TypedValue &left,
+                                const TypedValue &right) const override {
+    return impl_.applyToTypedValues(left, right);
+  }
+
+  ColumnVector* applyToColumnVectors(const ColumnVector &left,
+                                     const ColumnVector &right) const override {
+    using LeftCVT = typename LeftGen::ColumnVectorType;
+    DCHECK_EQ(left.isNative(), LeftCVT::kNative);
+    using LeftAccessorT = ColumnVectorValueAccessor<LeftCVT>;
+    LeftAccessorT left_accessor(static_cast<const LeftCVT&>(left));
+
+    using RightCVT = typename RightGen::ColumnVectorType;
+    DCHECK_EQ(right.isNative(), RightCVT::kNative);
+    using RightAccessorT = ColumnVectorValueAccessor<RightCVT>;
+    RightAccessorT right_accessor(static_cast<const RightCVT&>(right));
+
+    const std::size_t num_tuples = left_accessor.getNumTuples();
+    DCHECK_EQ(num_tuples, right_accessor.getNumTuples());
+
+    return impl_.applyToValueAccessors(num_tuples,
+                                       &left_accessor, kInvalidAttributeID,
+                                       &right_accessor, kInvalidAttributeID);
+  }
+
+  ColumnVector* applyToColumnVectorAndStaticValue(
+      const ColumnVector &left,
+      const TypedValue &right) const override {
+    using LeftCVT = typename LeftGen::ColumnVectorType;
+    DCHECK_EQ(left.isNative(), LeftCVT::kNative);
+
+    using LeftAccessorT = ColumnVectorValueAccessor<LeftCVT>;
+    LeftAccessorT accessor(static_cast<const LeftCVT&>(left));
+    return impl_.applyToValueAccessorAndStaticValue(&accessor, 0, right);
+  }
+
+  ColumnVector* applyToStaticValueAndColumnVector(
+      const TypedValue &left,
+      const ColumnVector &right) const override {
+    using RightCVT = typename RightGen::ColumnVectorType;
+    DCHECK_EQ(right.isNative(), RightCVT::kNative);
+
+    using RightAccessorT = ColumnVectorValueAccessor<RightCVT>;
+    RightAccessorT accessor(static_cast<const RightCVT&>(right));
+    return impl_.applyToStaticValueAndValueAccessor(left, &accessor, 0);
+  }
+
+  ColumnVector* applyToSingleValueAccessor(
+      ValueAccessor *accessor,
+      const attribute_id left_id,
+      const attribute_id right_id) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToSingleValueAccessor(accessor, left_id, right_id);
+    });
+  }
+
+  ColumnVector* applyToValueAccessorAndStaticValue(
+      ValueAccessor *left_accessor,
+      const attribute_id left_id,
+      const TypedValue &right) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        left_accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToValueAccessorAndStaticValue(accessor, left_id, right);
+    });
+  }
+
+  ColumnVector* applyToStaticValueAndValueAccessor(
+      const TypedValue &left,
+      ValueAccessor *right_accessor,
+      const attribute_id right_id) const override {
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        right_accessor,
+        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      return impl_.applyToStaticValueAndValueAccessor(left, accessor, right_id);
+    });
+  }
+
+  ColumnVector* applyToColumnVectorAndValueAccessor(
+      const ColumnVector &left,
+      ValueAccessor *right_accessor,
+      const attribute_id right_id) const override {
+    using LeftCVT = typename LeftGen::ColumnVectorType;
+    DCHECK_EQ(left.isNative(), LeftCVT::kNative);
+    using LeftAccessorT = ColumnVectorValueAccessor<LeftCVT>;
+    LeftAccessorT left_accessor(static_cast<const LeftCVT&>(left));
+
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        right_accessor,
+        [&](auto *right_accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+    const std::size_t num_tuples = left_accessor.getNumTuples();
+    DCHECK_EQ(num_tuples, right_accessor->getNumTuples());
+
+    return impl_.applyToValueAccessors(num_tuples,
+                                       &left_accessor, kInvalidAttributeID,
+                                       right_accessor, right_id);
+    });
+  }
+
+  ColumnVector* applyToValueAccessorAndColumnVector(
+      ValueAccessor *left_accessor,
+      const attribute_id left_id,
+      const ColumnVector &right) const override {
+    using RightCVT = typename RightGen::ColumnVectorType;
+    DCHECK_EQ(right.isNative(), RightCVT::kNative);
+    using RightAccessorT = ColumnVectorValueAccessor<RightCVT>;
+    RightAccessorT right_accessor(static_cast<const RightCVT&>(right));
+
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        left_accessor,
+        [&](auto *left_accessor) -> ColumnVector* {  // NOLINT(build/c++11)
+      const std::size_t num_tuples = right_accessor.getNumTuples();
+      DCHECK_EQ(num_tuples, left_accessor->getNumTuples());
+
+      return impl_.applyToValueAccessors(num_tuples,
+                                         left_accessor, left_id,
+                                         &right_accessor, kInvalidAttributeID);
+    });
+  }
+
+  TypedValue accumulateColumnVector(
+      const TypedValue &current,
+      const ColumnVector &column_vector,
+      std::size_t *num_tuples_applied) const override {
+    constexpr bool is_supported =
+        LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
+        (LeftType::kLayout == kNativeEmbedded || LeftType::kLayout == kNativeInline) &&
+        std::is_copy_assignable<typename LeftType::cpptype>::value;
+
+    using RightCVT = typename RightGen::ColumnVectorType;
+    DCHECK_EQ(column_vector.isNative(), RightCVT::kNative);
+    using RightAccessorT = ColumnVectorValueAccessor<RightCVT>;
+    RightAccessorT accessor(static_cast<const RightCVT&>(column_vector));
+
+    return impl_.template accumulateValueAccessor<is_supported>(
+        current,
+        &accessor,
+        kInvalidAttributeID,
+        num_tuples_applied);
+  }
+
+  TypedValue accumulateValueAccessor(
+      const TypedValue &current,
+      ValueAccessor *accessor,
+      const attribute_id value_accessor_id,
+      std::size_t *num_tuples_applied) const override {
+    constexpr bool is_supported =
+        LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
+        (LeftType::kLayout == kNativeEmbedded || LeftType::kLayout == kNativeInline) &&
+        std::is_copy_assignable<typename LeftType::cpptype>::value;
+
+    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
+        accessor,
+        [&](auto *accessor) -> TypedValue {  // NOLINT(build/c++11)
+      return impl_.template accumulateValueAccessor<is_supported>(
+          current,
+          accessor,
+          value_accessor_id,
+          num_tuples_applied);
+    });
+  }
+
+ private:
+  using LeftType = typename FunctorT::LeftArgumentType;
+  using RightType = typename FunctorT::RightArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
+  using LeftGen = Codegen<FuncSpec, LeftType>;
+  using RightGen = Codegen<FuncSpec, RightType>;
+  using ResultGen = Codegen<FuncSpec, ResultType>;
+
+  template <bool left_nullable, bool right_nullable>
+  struct Implementation;
+
+  const FunctorT functor_;
+  const Implementation<false, false> impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(UncheckedBinaryOperatorWrapperCodegen);
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool left_nullable, bool right_nullable>
+struct UncheckedBinaryOperatorWrapperCodegen<FunctorT, SpecArgs...>
+    ::Implementation {
+  Implementation(const FunctorT &functor_in,
+                 const Type &left_type_in,
+                 const Type &right_type_in,
+                 const Type &result_type_in)
+      : functor(functor_in),
+        left_type(left_type_in),
+        right_type(right_type_in),
+        result_type(result_type_in) {}
+
+  inline TypedValue applyToTypedValues(const TypedValue &left,
+                                       const TypedValue &right) const {
+    if ((left_nullable && left.isNull()) || (right_nullable && right.isNull())) {
+      return TypedValue(ResultType::kStaticTypeID);
+    }
+
+    return ResultGen::template ApplyBinaryTypedValue<LeftGen, RightGen>(
+        LeftGen::ToNativeValueConst(left),
+        RightGen::ToNativeValueConst(right),
+        result_type,
+        functor);
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToValueAccessorAndStaticValue(
+      AccessorT *accessor,
+      const attribute_id attr_id,
+      const TypedValue &static_value) const {
+    using AccessorGen = LeftGen;
+    using StaticValueGen = RightGen;
+
+    constexpr bool accessor_nullable = left_nullable;
+    constexpr bool static_value_nullable = right_nullable;
+
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    if (static_value_nullable && static_value.isNull()) {
+      result_cv->fillWithNulls();
+      return result_cv;
+    }
+
+    typename StaticValueGen::NativeTypeConst literal =
+        StaticValueGen::ToNativeValueConst(static_value);
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename AccessorGen::NativeTypeConstPtr arg_value =
+          AccessorGen::template GetValuePtr<
+              accessor_nullable, AccessorT>(accessor, attr_id);
+      if (accessor_nullable && AccessorGen::IsNull(arg_value)) {
+        result_cv->appendNullValue();
+      } else {
+        ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
+            AccessorGen::Dereference(arg_value), literal, functor, result_cv);
+      }
+    }
+    return result_cv;
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToStaticValueAndValueAccessor(
+      const TypedValue &static_value,
+      AccessorT *accessor,
+      const attribute_id attr_id) const {
+    using AccessorGen = RightGen;
+    using StaticValueGen = LeftGen;
+
+    constexpr bool accessor_nullable = right_nullable;
+    constexpr bool static_value_nullable = left_nullable;
+
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    if (static_value_nullable && static_value.isNull()) {
+      result_cv->fillWithNulls();
+      return result_cv;
+    }
+
+    typename StaticValueGen::NativeTypeConst literal =
+        StaticValueGen::ToNativeValueConst(static_value);
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename AccessorGen::NativeTypeConstPtr arg_value =
+          AccessorGen::template GetValuePtr<
+              accessor_nullable, AccessorT>(accessor, attr_id);
+      if (accessor_nullable && AccessorGen::IsNull(arg_value)) {
+        result_cv->appendNullValue();
+      } else {
+        ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
+            literal, AccessorGen::Dereference(arg_value), functor, result_cv);
+      }
+    }
+    return result_cv;
+  }
+
+  template <typename AccessorT>
+  inline ColumnVector* applyToSingleValueAccessor(
+      AccessorT *accessor,
+      const attribute_id left_id,
+      const attribute_id right_id) const {
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, accessor->getNumTuples());
+
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename LeftGen::NativeTypeConstPtr left_value =
+          LeftGen::template GetValuePtr<
+              left_nullable, AccessorT>(accessor, left_id);
+      if (left_nullable && LeftGen::IsNull(left_value)) {
+        result_cv->appendNullValue();
+        continue;
+      }
+      typename RightGen::NativeTypeConstPtr right_value =
+          RightGen::template GetValuePtr<
+              right_nullable, AccessorT>(accessor, right_id);
+      if (right_nullable && RightGen::IsNull(right_value)) {
+        result_cv->appendNullValue();
+        continue;
+      }
+      ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
+          LeftGen::Dereference(left_value),
+          RightGen::Dereference(right_value),
+          functor,
+          result_cv);
+    }
+    return result_cv;
+  }
+
+  template <typename LeftAccessorT, typename RightAccessorT>
+  inline ColumnVector* applyToValueAccessors(const std::size_t num_tuples,
+                                             LeftAccessorT *left_accessor,
+                                             const attribute_id left_id,
+                                             RightAccessorT *right_accessor,
+                                             const attribute_id right_id) const {
+    DCHECK_EQ(num_tuples, left_accessor->getNumTuples());
+    DCHECK_EQ(num_tuples, right_accessor->getNumTuples());
+
+    using ResultCVT = typename ResultGen::ColumnVectorType;
+    ResultCVT *result_cv = new ResultCVT(result_type, num_tuples);
+
+    left_accessor->beginIteration();
+    right_accessor->beginIteration();
+    while (left_accessor->next()) {
+      right_accessor->next();
+      typename LeftGen::NativeTypeConstPtr left_value =
+          LeftGen::template GetValuePtr<
+              left_nullable, LeftAccessorT>(left_accessor, left_id);
+      if (left_nullable && LeftGen::IsNull(left_value)) {
+        result_cv->appendNullValue();
+        continue;
+      }
+      typename RightGen::NativeTypeConstPtr right_value =
+          RightGen::template GetValuePtr<
+              right_nullable, RightAccessorT>(right_accessor, right_id);
+      if (right_nullable && RightGen::IsNull(right_value)) {
+        result_cv->appendNullValue();
+        continue;
+      }
+      ResultGen::template ApplyBinaryColumnVector<LeftGen, RightGen>(
+          LeftGen::Dereference(left_value),
+          RightGen::Dereference(right_value),
+          functor,
+          result_cv);
+    }
+    return result_cv;
+  }
+
+  template <bool supported, typename AccessorT>
+  inline TypedValue accumulateValueAccessor(const TypedValue &current,
+                                            AccessorT *accessor,
+                                            const attribute_id attr_id,
+                                            std::size_t *num_tuples_applied,
+                                            std::enable_if_t<supported>* = 0) const {
+    DCHECK(num_tuples_applied);
+
+    *num_tuples_applied = 0;
+    if (left_nullable && current.isNull()) {
+      return result_type.makeNullValue();
+    }
+
+    using LeftCppType = typename LeftType::cpptype;
+    using ResultCppType = typename ResultType::cpptype;
+    ResultCppType accumulated = current.getLiteral<LeftCppType>();
+
+    accessor->beginIteration();
+    while (accessor->next()) {
+      typename RightGen::NativeTypeConstPtr right_value =
+          RightGen::template GetValuePtr<
+              right_nullable, AccessorT>(accessor, attr_id);
+      if (right_nullable && RightGen::IsNull(right_value)) {
+        continue;
+      }
+
+      accumulated =
+          ResultGen::FunctorSpecializer::Invoke(
+              functor, accumulated, RightGen::Dereference(right_value));
+      ++(*num_tuples_applied);
+    }
+
+    return TypedValue(accumulated);
+  }
+
+  template <bool supported, typename AccessorT>
+  inline TypedValue accumulateValueAccessor(const TypedValue &current,
+                                            AccessorT *accessor,
+                                            const attribute_id attr_id,
+                                            std::size_t *num_tuples_applied,
+                                            std::enable_if_t<!supported>* = 0) const {
+    LOG(FATAL) << "Unimplemented method UncheckedBinaryOperatorWrapperCodegen"
+               << "::accumulateValueAccessor() because ResultType and LeftType "
+               << "are not same or not native types.";
+  }
+
+  const FunctorT &functor;
+  const Type &left_type;
+  const Type &right_type;
+  const Type &result_type;
+};
+
+template <typename FunctorT>
+class BinaryOperationWrapper : public BinaryOperation {
+ public:
+  BinaryOperationWrapper()
+      : BinaryOperation(),
+        operation_name_(FunctorT::GetName()) {}
+
+  std::string getName() const override {
+    return operation_name_;
+  }
+
+  std::string getShortName() const override {
+    return getName();
+  }
+
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    return {
+        OperationSignature::Create(
+            getName(), {LeftType::kStaticTypeID, RightType::kStaticTypeID}, 0)
+    };
+  }
+
+  bool canApplyTo(const Type &left,
+                  const Type &right,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
+    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return true;
+  }
+
+  const Type* getResultType(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
+    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return getResultTypeImpl<ResultType::kParameterized>(
+        left, right, static_arguments);
+  }
+
+  UncheckedBinaryOperator* makeUncheckedBinaryOperator(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
+    DCHECK(right.getTypeID() == RightType::kStaticTypeID);
+    DCHECK(static_arguments.empty());
+    return makeUncheckedBinaryOperatorImpl<
+        std::is_default_constructible<FunctorT>::value>(
+            left, right, static_arguments);
+  }
+
+ private:
+  using LeftType = typename FunctorT::LeftArgumentType;
+  using RightType = typename FunctorT::RightArgumentType;
+  using ResultType = typename FunctorT::ResultType;
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedBinaryOperator* makeUncheckedBinaryOperatorImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<functor_use_default_constructor>* = 0) const {
+    return new UncheckedBinaryOperatorWrapperCodegen<FunctorT>(
+        left, right, *getResultType(left, right, static_arguments));
+  }
+
+  template <bool functor_use_default_constructor>
+  inline UncheckedBinaryOperator* makeUncheckedBinaryOperatorImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!functor_use_default_constructor>* = 0) const {
+    return new UncheckedBinaryOperatorWrapperCodegen<FunctorT>(
+        left, right, *getResultType(left, right, static_arguments),
+        static_cast<const LeftType&>(left),
+        static_cast<const RightType&>(right));
+  }
+
+  template <bool result_type_has_parameter>
+  inline const Type* getResultTypeImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<!result_type_has_parameter>* = 0) const {
+    return &TypeFactory::GetType(
+        ResultType::kStaticTypeID,
+        left.isNullable() || right.isNullable());
+  }
+
+  template <bool result_type_has_parameter>
+  inline const Type* getResultTypeImpl(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments,
+      std::enable_if_t<result_type_has_parameter>* = 0) const {
+    return FunctorT::GetResultType(left, right);
+  }
+
+  const std::string operation_name_;
+
+  DISALLOW_COPY_AND_ASSIGN(BinaryOperationWrapper);
+};
+
+template <typename LeftPack, typename RightPack,
+          template <typename LeftT,
+                    typename RightT,
+                    typename ResultT> class FunctorT,
+          template <typename LeftT,
+                    typename RightT> class ResultGenerator>
+struct BinaryFunctorCrossProductPack {
+  template <std::size_t l, std::size_t r>
+  inline static OperationPtr GenerateInner() {
+    using LeftType = std::tuple_element_t<l, LeftPack>;
+    using RightType = std::tuple_element_t<r, RightPack>;
+    using ResultType = typename ResultGenerator<LeftType, RightType>::type;
+
+    return std::make_shared<
+        const BinaryOperationWrapper<
+            FunctorT<LeftType, RightType, ResultType>>>();
+  }
+
+  template <std::size_t l, std::size_t ...Rs>
+  inline static std::list<OperationPtr> GenerateRightHelper() {
+    return { GenerateInner<l, Rs>()... };
+  }
+
+  template <std::size_t ...Ls, std::size_t ...Rs>
+  inline static std::vector<std::list<OperationPtr>> GenerateLeftHelper(
+      meta::IntegerSequence<Ls...> &&l_seq, meta::IntegerSequence<Rs...> &&r_seq) {
+    return { GenerateRightHelper<Ls, Rs...>()... };
+  }
+
+  template <typename Dispatcher>
+  inline static std::list<OperationPtr> GenerateOperations() {
+    std::vector<std::list<OperationPtr>> op_list_groups =
+        GenerateLeftHelper(typename meta::MakeSequence<std::tuple_size<LeftPack>::value>::type(),
+                           typename meta::MakeSequence<std::tuple_size<RightPack>::value>::type());
+
+    std::list<OperationPtr> operations;
+    for (std::list<OperationPtr> &op_list : op_list_groups) {
+      operations.splice(operations.end(), std::move(op_list));
+    }
+    return operations;
+  }
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_UNARY_OPERATION_WRAPPER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMakeLists.txt b/types/operations/binary_operations/CMakeLists.txt
index 4d26b75..09566aa 100644
--- a/types/operations/binary_operations/CMakeLists.txt
+++ b/types/operations/binary_operations/CMakeLists.txt
@@ -16,185 +16,97 @@
 # under the License.
 
 # Declare micro-libs:
-add_library(quickstep_types_operations_binaryoperations_AddBinaryOperation
-            AddBinaryOperation.cpp
-            AddBinaryOperation.hpp)
-add_library(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
+add_library(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
             ../../../empty_src.cpp
-            ArithmeticBinaryOperation.hpp)
-add_library(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperators
+            ArithmeticBinaryOperations.hpp)
+add_library(quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
             ../../../empty_src.cpp
-            ArithmeticBinaryOperators.hpp)
+            ArithmeticBinaryFunctorOverloads.hpp)
+add_library(quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
+            ../../../empty_src.cpp
+            AsciiStringBinaryOperations.hpp)
 add_library(quickstep_types_operations_binaryoperations_BinaryOperation
             BinaryOperation.cpp
             BinaryOperation.hpp)
-add_library(quickstep_types_operations_binaryoperations_BinaryOperationFactory
-            BinaryOperationFactory.cpp
-            BinaryOperationFactory.hpp)
-add_library(quickstep_types_operations_binaryoperations_BinaryOperationID
-            BinaryOperationID.cpp
-            BinaryOperationID.hpp)
-add_library(quickstep_types_operations_binaryoperations_DivideBinaryOperation
-            DivideBinaryOperation.cpp
-            DivideBinaryOperation.hpp)
-add_library(quickstep_types_operations_binaryoperations_ModuloBinaryOperation
-            ModuloBinaryOperation.cpp
-            ModuloBinaryOperation.hpp)
-add_library(quickstep_types_operations_binaryoperations_MultiplyBinaryOperation
-            MultiplyBinaryOperation.cpp
-            MultiplyBinaryOperation.hpp)
-add_library(quickstep_types_operations_binaryoperations_SubtractBinaryOperation
-            SubtractBinaryOperation.cpp
-            SubtractBinaryOperation.hpp)
+add_library(quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+            ../../../empty_src.cpp
+            BinaryOperationWrapper.hpp)
+add_library(quickstep_types_operations_binaryoperations_CMathBinaryOperations
+            ../../../empty_src.cpp
+            CMathBinaryOperations.hpp)
 
 # Link dependencies:
-target_link_libraries(quickstep_types_operations_binaryoperations_AddBinaryOperation
-                      glog
+target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
                       quickstep_types_DateOperatorOverloads
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
                       quickstep_types_DateType
                       quickstep_types_DatetimeIntervalType
                       quickstep_types_DatetimeLit
                       quickstep_types_DatetimeType
                       quickstep_types_IntervalLit
+                      quickstep_types_NumericTypeUnifier
                       quickstep_types_Type
                       quickstep_types_TypeErrors
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperators
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_utility_EqualsAnyConstant
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
+                      quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
+                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
                       glog
-                      quickstep_types_DoubleType
-                      quickstep_types_FloatType
+                      quickstep_types_CharType
                       quickstep_types_IntType
-                      quickstep_types_LongType
-                      quickstep_types_NumericTypeUnifier
                       quickstep_types_Type
-                      quickstep_types_TypeErrors
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
-                      quickstep_types_TypedValue
-                      quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperators
-                      glog
-                      quickstep_catalog_CatalogTypedefs
-                      quickstep_storage_StorageBlockInfo
-                      quickstep_storage_ValueAccessor
-                      quickstep_storage_ValueAccessorUtil
-                      quickstep_types_TypedValue
-                      quickstep_types_containers_ColumnVector
-                      quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_utility_Macros)
+                      quickstep_types_VarCharType
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_port_strnlen)
 target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_StorageBlockInfo
                       quickstep_types_TypedValue
                       quickstep_types_operations_Operation
-                      quickstep_types_operations_Operation_proto
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      glog
-                      quickstep_types_operations_Operation_proto
-                      quickstep_types_operations_binaryoperations_AddBinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_types_operations_binaryoperations_DivideBinaryOperation
-                      quickstep_types_operations_binaryoperations_ModuloBinaryOperation
-                      quickstep_types_operations_binaryoperations_MultiplyBinaryOperation
-                      quickstep_types_operations_binaryoperations_SubtractBinaryOperation
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_binaryoperations_DivideBinaryOperation
-                      glog
-                      quickstep_types_DateOperatorOverloads
-                      quickstep_types_DatetimeIntervalType
-                      quickstep_types_DoubleType
-                      quickstep_types_FloatType
-                      quickstep_types_IntType
-                      quickstep_types_IntervalLit
-                      quickstep_types_LongType
-                      quickstep_types_Type
-                      quickstep_types_TypeErrors
-                      quickstep_types_TypeFactory
-                      quickstep_types_TypeID
-                      quickstep_types_TypedValue
-                      quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperators
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_utility_EqualsAnyConstant
+                      quickstep_types_operations_OperationSignature
                       quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_binaryoperations_ModuloBinaryOperation
+target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperationWrapper
                       glog
+                      quickstep_catalog_CatalogTypedefs
+                      quickstep_storage_ValueAccessor
+                      quickstep_storage_ValueAccessorUtil
                       quickstep_types_Type
-                      quickstep_types_TypeErrors
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperators
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_utility_EqualsAnyConstant
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_binaryoperations_MultiplyBinaryOperation
-                      glog
-                      quickstep_types_DateOperatorOverloads
-                      quickstep_types_DatetimeIntervalType
+                      quickstep_types_containers_ColumnVector
+                      quickstep_types_operations_OperationSignature
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_binaryoperations_BinaryOperation
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_operations_binaryoperations_CMathBinaryOperations
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
                       quickstep_types_IntType
-                      quickstep_types_IntervalLit
                       quickstep_types_LongType
-                      quickstep_types_Type
-                      quickstep_types_TypeErrors
-                      quickstep_types_TypeFactory
-                      quickstep_types_TypeID
-                      quickstep_types_TypedValue
-                      quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperators
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_utility_EqualsAnyConstant
-                      quickstep_utility_Macros)
-target_link_libraries(quickstep_types_operations_binaryoperations_SubtractBinaryOperation
-                      glog
-                      quickstep_types_DateOperatorOverloads
-                      quickstep_types_DateType
-                      quickstep_types_DatetimeIntervalType
-                      quickstep_types_DatetimeLit
-                      quickstep_types_DatetimeType
-                      quickstep_types_IntervalLit
-                      quickstep_types_Type
-                      quickstep_types_TypeErrors
-                      quickstep_types_TypeFactory
-                      quickstep_types_TypeID
-                      quickstep_types_TypedValue
-                      quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperators
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_utility_EqualsAnyConstant
-                      quickstep_utility_Macros)
+                      quickstep_types_operations_OperationUtil
+                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_utility_meta_Common)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_binaryoperations ../../../empty_src.cpp)
 target_link_libraries(quickstep_types_operations_binaryoperations
                       quickstep_types_operations_binaryoperations_AddBinaryOperation
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperators
+                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
+                      quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
+                      quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_types_operations_binaryoperations_DivideBinaryOperation
-                      quickstep_types_operations_binaryoperations_ModuloBinaryOperation
-                      quickstep_types_operations_binaryoperations_MultiplyBinaryOperation
-                      quickstep_types_operations_binaryoperations_SubtractBinaryOperation)
+                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_types_operations_binaryoperations_CMathBinaryOperations)
 
 # Tests:
 add_library(quickstep_types_operations_binaryoperations_tests_BinaryOperationTestUtil
@@ -228,14 +140,7 @@ target_link_libraries(BinaryOperation_tests
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_types_operations_Operation_proto
-                      quickstep_types_operations_binaryoperations_AddBinaryOperation
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_types_operations_binaryoperations_DivideBinaryOperation
-                      quickstep_types_operations_binaryoperations_ModuloBinaryOperation
-                      quickstep_types_operations_binaryoperations_MultiplyBinaryOperation
-                      quickstep_types_operations_binaryoperations_SubtractBinaryOperation
                       quickstep_types_operations_binaryoperations_tests_BinaryOperationTestUtil
                       quickstep_utility_Macros)
 add_test(BinaryOperation_tests BinaryOperation_tests)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/CMathBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMathBinaryOperations.hpp b/types/operations/binary_operations/CMathBinaryOperations.hpp
new file mode 100644
index 0000000..9a90a12
--- /dev/null
+++ b/types/operations/binary_operations/CMathBinaryOperations.hpp
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_CMATH_BINARY_OPERATIONS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_CMATH_BINARY_OPERATIONS_HPP_
+
+#include <cmath>
+#include <string>
+
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename LeftT, typename RightT, typename ResultT,
+          typename ResultT::cpptype f(typename LeftT::cpptype,
+                                      typename RightT::cpptype),
+          typename FunctorNameT>
+struct CMathBinaryFunctorWrapper {
+  struct Implemenation : public BinaryFunctor<LeftT, RightT, ResultT> {
+    inline typename ResultT::cpptype apply(
+        const typename LeftT::cpptype &left,
+        const typename RightT::cpptype &right) const {
+      return f(left, right);
+    }
+    inline static std::string GetName() {
+      return FunctorNameT::ToString();
+    }
+  };
+
+  typedef Implemenation type;
+};
+
+template <typename LeftT, typename RightT, typename ResultT,
+          typename ResultT::cpptype f(typename LeftT::cpptype,
+                                      typename RightT::cpptype),
+          typename FunctorNameT>
+using CMathBinaryFunctor =
+    typename CMathBinaryFunctorWrapper<LeftT, RightT, ResultT, f, FunctorNameT>::type;
+
+using CMathBinaryFunctorPack = FunctorPack<
+// pow
+    CMathBinaryFunctor<FloatType, FloatType, FloatType,
+                       std::pow, meta::StringLiteral<'p','o','w'>>,
+    CMathBinaryFunctor<DoubleType, DoubleType, DoubleType,
+                       std::pow, meta::StringLiteral<'p','o','w'>>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/DivideBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/DivideBinaryOperation.cpp b/types/operations/binary_operations/DivideBinaryOperation.cpp
deleted file mode 100644
index 59dcb3e..0000000
--- a/types/operations/binary_operations/DivideBinaryOperation.cpp
+++ /dev/null
@@ -1,391 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/binary_operations/DivideBinaryOperation.hpp"
-
-#include <string>
-#include <utility>
-
-#include "types/DateOperatorOverloads.hpp"
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/IntervalLit.hpp"
-#include "types/LongType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperators.hpp"
-#include "utility/EqualsAnyConstant.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool DivideBinaryOperation::canApplyToTypes(const Type &left, const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kDatetimeInterval:
-    case kYearMonthInterval: {
-      return (right.getSuperTypeID() == Type::kNumeric);
-    }
-    default:
-      return false;
-  }
-}
-
-const Type* DivideBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const {
-  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-    return TypeFactory::GetUnifyingType(left, right);
-  } else if (left.getTypeID() == kDatetimeInterval && right.getSuperTypeID() == Type::kNumeric) {
-    return &(DatetimeIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kYearMonthInterval && right.getSuperTypeID() == Type::kNumeric) {
-    return &(YearMonthIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else {
-    return nullptr;
-  }
-}
-
-const Type* DivideBinaryOperation::resultTypeForPartialArgumentTypes(
-    const Type *left,
-    const Type *right) const {
-  if (left == nullptr) {
-    // Can't determine result type just based on right (divisor) type.
-    return nullptr;
-  } else if (right == nullptr) {
-    switch (left->getTypeID()) {
-      case kDouble:
-        // Double has highest precedence of numeric types.
-        return &TypeFactory::GetType(kDouble, true);
-      case kDatetimeInterval:
-        return &TypeFactory::GetType(kDatetimeInterval, true);
-      case kYearMonthInterval:
-        return &TypeFactory::GetType(kYearMonthInterval, true);
-      default:
-        // Ambiguous or inapplicable.
-        return nullptr;
-    }
-  } else {
-    return resultTypeForArgumentTypes(*left, *right);
-  }
-}
-
-bool DivideBinaryOperation::partialTypeSignatureIsPlausible(
-    const Type *result_type,
-    const Type *left_argument_type,
-    const Type *right_argument_type) const {
-  // Early check: if either argument type is nullable or unknown, result type
-  // must also be nullable.
-  if ((left_argument_type == nullptr)
-      || left_argument_type->isNullable()
-      || (right_argument_type == nullptr)
-      || right_argument_type->isNullable()) {
-    if ((result_type != nullptr) && (!result_type->isNullable())) {
-      return false;
-    }
-  }
-
-  if (left_argument_type == nullptr) {
-    if (right_argument_type == nullptr) {
-      if (result_type == nullptr) {
-        // All types unknown.
-        return true;
-      } else {
-        // Only result type is known, just check that it is one of the types
-        // that can possibly be returned.
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-      }
-    }
-
-    if (result_type == nullptr) {
-      // Right (divisor) argument type is known, left (dividend) argument and
-      // result types are unknown. Just check that it is possible to divide by
-      // the right (divisor) type.
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          right_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble);
-    }
-
-    // Return type and right (divisor) argument type are known, left (dividend)
-    // argument type is unknown. Check that result and divisor are compatible.
-    switch (right_argument_type->getTypeID()) {
-      case kInt:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-      case kLong:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kLong, kDouble, kDatetimeInterval, kYearMonthInterval);
-      case kFloat:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-      case kDouble:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kDouble, kDatetimeInterval, kYearMonthInterval);
-      default:
-        return false;
-    }
-  } else {  // left_argument_type != nullptr
-    if (right_argument_type == nullptr) {
-      if (result_type == nullptr) {
-        // Left (dividend) argument type is known, right (divisor) argument
-        // type and result type are unknown. Just check that the left
-        // (dividend) type can be divided.
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            left_argument_type->getTypeID(),
-            kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
-      }
-
-      // Result type and left (dividend) argument type are known, but right
-      // (divisor) argument type is unknown. Check that result and dividend are
-      // compatible.
-      switch (left_argument_type->getTypeID()) {
-        case kInt:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kInt, kLong, kFloat, kDouble);
-        case kLong:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kLong, kDouble);
-        case kFloat:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kFloat, kDouble);
-        case kDouble:
-          return (result_type->getTypeID() == kDouble);
-        case kDatetimeInterval:
-          return (result_type->getTypeID() == kDatetimeInterval);
-        case kYearMonthInterval:
-          return (result_type->getTypeID() == kYearMonthInterval);
-        default:
-          return false;
-      }
-    }
-
-    // Left and right (dividend and divisor) argument types are both known.
-    const Type *actual_result_type = resultTypeForArgumentTypes(*left_argument_type,
-                                                                *right_argument_type);
-    if (actual_result_type == nullptr) {
-      // Both argument Types are known, but this operation is NOT applicable to
-      // them. No matter what the result_type is, the signature is not
-      // plausible.
-      return false;
-    } else if (result_type == nullptr) {
-      return true;
-    } else {
-      // Check if result type matches.
-      return result_type->equals(*actual_result_type);
-    }
-  }
-}
-
-std::pair<const Type*, const Type*> DivideBinaryOperation::pushDownTypeHint(
-    const Type *result_type_hint) const {
-  if (result_type_hint == nullptr) {
-    return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-
-  switch (result_type_hint->getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-      return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint);
-    case kDatetimeInterval:
-    case kYearMonthInterval:
-      // Left (dividend) should be the same kind of interval as '*type_hint',
-      // right (divisor) can be any numeric type.
-      return std::pair<const Type*, const Type*>(result_type_hint, nullptr);
-    default:
-      // Inapplicable.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-}
-
-TypedValue DivideBinaryOperation::applyToChecked(const TypedValue &left,
-                                                 const Type &left_type,
-                                                 const TypedValue &right,
-                                                 const Type &right_type) const {
-  switch (left_type.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedNumericHelper<DivideFunctor>(left, left_type,
-                                                          right, right_type);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      switch (right_type.getTypeID()) {
-        case kInt:
-          if (left.isNull() || right.isNull()) {
-            return TypedValue(kDatetimeInterval);
-          }
-
-          return TypedValue(left.getLiteral<DatetimeIntervalLit>() / right.getLiteral<IntType::cpptype>());
-        case kLong:
-          if (left.isNull() || right.isNull()) {
-            return TypedValue(kDatetimeInterval);
-          }
-
-          return TypedValue(left.getLiteral<DatetimeIntervalLit>() / right.getLiteral<LongType::cpptype>());
-        case kFloat:
-          if (left.isNull() || right.isNull()) {
-            return TypedValue(kDatetimeInterval);
-          }
-
-          return TypedValue(left.getLiteral<DatetimeIntervalLit>() / right.getLiteral<FloatType::cpptype>());
-        case kDouble:
-          if (left.isNull() || right.isNull()) {
-            return TypedValue(kDatetimeInterval);
-          }
-
-          return TypedValue(left.getLiteral<DatetimeIntervalLit>() / right.getLiteral<DoubleType::cpptype>());
-        default:
-          break;
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      switch (right_type.getTypeID()) {
-        case kInt:
-          if (left.isNull() || right.isNull()) {
-            return TypedValue(kYearMonthInterval);
-          }
-
-          return TypedValue(left.getLiteral<YearMonthIntervalLit>() / right.getLiteral<IntType::cpptype>());
-        case kLong:
-          if (left.isNull() || right.isNull()) {
-            return TypedValue(kYearMonthInterval);
-          }
-
-          return TypedValue(left.getLiteral<YearMonthIntervalLit>() / right.getLiteral<LongType::cpptype>());
-        case kFloat:
-          if (left.isNull() || right.isNull()) {
-            return TypedValue(kYearMonthInterval);
-          }
-
-          return TypedValue(left.getLiteral<YearMonthIntervalLit>() / right.getLiteral<FloatType::cpptype>());
-        case kDouble:
-          if (left.isNull() || right.isNull()) {
-            return TypedValue(kYearMonthInterval);
-          }
-
-          return TypedValue(left.getLiteral<YearMonthIntervalLit>() / right.getLiteral<DoubleType::cpptype>());
-        default:
-          break;
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-             << left_type.getName() << " and " << right_type.getName();
-}
-
-UncheckedBinaryOperator* DivideBinaryOperation::makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                                                    const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator>(left, right);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      switch (right.getTypeID()) {
-        case kInt: {
-          return makeDateBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, IntType::cpptype>(left, right);
-        }
-        case kLong: {
-          return makeDateBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, LongType::cpptype>(left, right);
-        }
-        case kFloat: {
-          return makeDateBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, FloatType::cpptype>(left, right);
-        }
-        case kDouble: {
-          return makeDateBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator,
-                                                   DatetimeIntervalType,
-                                                   DatetimeIntervalLit, DoubleType::cpptype>(left, right);
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      switch (right.getTypeID()) {
-        case kInt: {
-          return makeDateBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, IntType::cpptype>(left, right);
-        }
-        case kLong: {
-          return makeDateBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, LongType::cpptype>(left, right);
-        }
-        case kFloat: {
-          return makeDateBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, FloatType::cpptype>(left, right);
-        }
-        case kDouble: {
-          return makeDateBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator,
-                                                   YearMonthIntervalType,
-                                                   YearMonthIntervalLit, DoubleType::cpptype>(left, right);
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/DivideBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/DivideBinaryOperation.hpp b/types/operations/binary_operations/DivideBinaryOperation.hpp
deleted file mode 100644
index 3ab7aa1..0000000
--- a/types/operations/binary_operations/DivideBinaryOperation.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_DIVIDE_BINARY_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_DIVIDE_BINARY_OPERATION_HPP_
-
-#include <utility>
-
-#include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-class UncheckedBinaryOperator;
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief The BinaryOperation for division.
- *
- * @note DivideBinaryOperation is not commutative: the left argument is the
- *       dividend and the right argument is the divisor.
- **/
-class DivideBinaryOperation : public ArithmeticBinaryOperation {
- public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const DivideBinaryOperation& Instance() {
-    static DivideBinaryOperation instance;
-    return instance;
-  }
-
-  bool canApplyToTypes(const Type &left,
-                       const Type &right) const override;
-
-  const Type* resultTypeForArgumentTypes(const Type &left,
-                                         const Type &right) const override;
-
-  const Type* resultTypeForPartialArgumentTypes(const Type *left,
-                                                const Type *right) const override;
-
-  bool partialTypeSignatureIsPlausible(const Type *result_type,
-                                       const Type *left_argument_type,
-                                       const Type *right_argument_type) const override;
-
-  std::pair<const Type*, const Type*> pushDownTypeHint(
-      const Type *result_type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &left,
-                            const Type &left_type,
-                            const TypedValue &right,
-                            const Type &right_type) const override;
-
-  UncheckedBinaryOperator* makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                               const Type &right) const override;
-
- private:
-  DivideBinaryOperation()
-      : ArithmeticBinaryOperation(BinaryOperationID::kDivide) {
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(DivideBinaryOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_DIVIDE_BINARY_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/ModuloBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ModuloBinaryOperation.cpp b/types/operations/binary_operations/ModuloBinaryOperation.cpp
deleted file mode 100644
index 917c6c9..0000000
--- a/types/operations/binary_operations/ModuloBinaryOperation.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/binary_operations/ModuloBinaryOperation.hpp"
-
-#include <string>
-#include <utility>
-
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperators.hpp"
-#include "utility/EqualsAnyConstant.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool ModuloBinaryOperation::canApplyToTypes(const Type &left, const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:  // Fall through
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      return (right.getSuperTypeID() == Type::kNumeric);
-    }
-    // TODO(jianqiao): Extend modulo operator to be applicable to DatetimeInterval
-    // and YearMonthInterval.
-    default:
-      return false;
-  }
-}
-
-const Type* ModuloBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const {
-  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-    return TypeFactory::GetUnifyingType(left, right);
-  } else {
-    return nullptr;
-  }
-}
-
-const Type* ModuloBinaryOperation::resultTypeForPartialArgumentTypes(
-    const Type *left,
-    const Type *right) const {
-  if (left == nullptr) {
-    // Can't determine result type just based on right (divisor) type.
-    return nullptr;
-  } else if (right == nullptr) {
-    switch (left->getTypeID()) {
-      case kDouble:
-        // Double has highest precedence of numeric types.
-        return &TypeFactory::GetType(kDouble, true);
-      default:
-        // Ambiguous or inapplicable.
-        return nullptr;
-    }
-  } else {
-    return resultTypeForArgumentTypes(*left, *right);
-  }
-}
-
-bool ModuloBinaryOperation::partialTypeSignatureIsPlausible(
-    const Type *result_type,
-    const Type *left_argument_type,
-    const Type *right_argument_type) const {
-  // Early check: if either argument type is nullable or unknown, result type
-  // must also be nullable.
-  if ((left_argument_type == nullptr)
-      || left_argument_type->isNullable()
-      || (right_argument_type == nullptr)
-      || right_argument_type->isNullable()) {
-    if ((result_type != nullptr) && (!result_type->isNullable())) {
-      return false;
-    }
-  }
-
-  if (left_argument_type == nullptr) {
-    if (right_argument_type == nullptr) {
-      if (result_type == nullptr) {
-        // All types unknown.
-        return true;
-      } else {
-        // Only result type is known, just check that it is one of the types
-        // that can possibly be returned.
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kInt, kLong, kFloat, kDouble);
-      }
-    }
-
-    if (result_type == nullptr) {
-      // Right (divisor) argument type is known, left (dividend) argument and
-      // result types are unknown. Just check that it is possible to divide by
-      // the right (divisor) type.
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          right_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble);
-    }
-
-    // Return type and right (divisor) argument type are known, left (dividend)
-    // argument type is unknown. Check that result and divisor are compatible.
-    switch (right_argument_type->getTypeID()) {
-      case kInt:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kInt, kLong, kFloat, kDouble);
-      case kLong:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kLong, kDouble);
-      case kFloat:
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            result_type->getTypeID(),
-            kFloat, kDouble);
-      case kDouble:
-        return (result_type->getTypeID() == kDouble);
-      default:
-        return false;
-    }
-  } else {  // left_argument_type != nullptr
-    if (right_argument_type == nullptr) {
-      if (result_type == nullptr) {
-        // Left (dividend) argument type is known, right (divisor) argument
-        // type and result type are unknown. Just check that the left
-        // (dividend) type can be divided.
-        return QUICKSTEP_EQUALS_ANY_CONSTANT(
-            left_argument_type->getTypeID(),
-            kInt, kLong, kFloat, kDouble);
-      }
-
-      // Result type and left (dividend) argument type are known, but right
-      // (divisor) argument type is unknown. Check that result and dividend are
-      // compatible.
-      switch (left_argument_type->getTypeID()) {
-        case kInt:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kInt, kLong, kFloat, kDouble);
-        case kLong:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kLong, kDouble);
-        case kFloat:
-          return QUICKSTEP_EQUALS_ANY_CONSTANT(
-              result_type->getTypeID(),
-              kFloat, kDouble);
-        case kDouble:
-          return (result_type->getTypeID() == kDouble);
-        default:
-          return false;
-      }
-    }
-
-    // Left and right (dividend and divisor) argument types are both known.
-    const Type *actual_result_type = resultTypeForArgumentTypes(*left_argument_type,
-                                                                *right_argument_type);
-    if (actual_result_type == nullptr) {
-      // Both argument Types are known, but this operation is NOT applicable to
-      // them. No matter what the result_type is, the signature is not
-      // plausible.
-      return false;
-    } else if (result_type == nullptr) {
-      return true;
-    } else {
-      // Check if result type matches.
-      return result_type->equals(*actual_result_type);
-    }
-  }
-}
-
-std::pair<const Type*, const Type*> ModuloBinaryOperation::pushDownTypeHint(
-    const Type *result_type_hint) const {
-  if (result_type_hint == nullptr) {
-    return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-
-  switch (result_type_hint->getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-      return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint);
-    default:
-      // Inapplicable.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-}
-
-TypedValue ModuloBinaryOperation::applyToChecked(const TypedValue &left,
-                                                 const Type &left_type,
-                                                 const TypedValue &right,
-                                                 const Type &right_type) const {
-  switch (left_type.getTypeID()) {
-    case kInt:
-    case kLong: {
-      if (right_type.getTypeID() == TypeID::kInt
-          || right_type.getTypeID() == TypeID::kLong) {
-        return applyToCheckedIntegerHelper<IntegerModuloFunctor>(left, left_type,
-                                                                 right, right_type);
-      }
-    }  // Fall through
-    case kFloat:
-    case kDouble: {
-      if (right_type.getSuperTypeID() == Type::kNumeric) {
-        return applyToCheckedNumericHelper<FloatModuloFunctor>(left, left_type,
-                                                               right, right_type);
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-             << left_type.getName() << " and " << right_type.getName();
-}
-
-UncheckedBinaryOperator* ModuloBinaryOperation::makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                                                    const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong: {
-      if (right.getTypeID() == TypeID::kInt
-          || right.getTypeID() == TypeID::kLong) {
-        return makeIntegerBinaryOperatorOuterHelper<IntegerModuloArithmeticUncheckedBinaryOperator>(left, right);
-      }
-    }  // Fall through
-    case kFloat:
-    case kDouble: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<FloatModuloArithmeticUncheckedBinaryOperator>(left, right);
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/ModuloBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ModuloBinaryOperation.hpp b/types/operations/binary_operations/ModuloBinaryOperation.hpp
deleted file mode 100644
index 1d47a45..0000000
--- a/types/operations/binary_operations/ModuloBinaryOperation.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_MODULO_BINARY_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_MODULO_BINARY_OPERATION_HPP_
-
-#include <utility>
-
-#include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-class UncheckedBinaryOperator;
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief The BinaryOperation for modulo.
- *
- * @note ModuloBinaryOperation is not commutative: the left argument is the
- *       dividend and the right argument is the divisor.
- **/
-class ModuloBinaryOperation : public ArithmeticBinaryOperation {
- public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const ModuloBinaryOperation& Instance() {
-    static ModuloBinaryOperation instance;
-    return instance;
-  }
-
-  bool canApplyToTypes(const Type &left,
-                       const Type &right) const override;
-
-  const Type* resultTypeForArgumentTypes(const Type &left,
-                                         const Type &right) const override;
-
-  const Type* resultTypeForPartialArgumentTypes(const Type *left,
-                                                const Type *right) const override;
-
-  bool partialTypeSignatureIsPlausible(const Type *result_type,
-                                       const Type *left_argument_type,
-                                       const Type *right_argument_type) const override;
-
-  std::pair<const Type*, const Type*> pushDownTypeHint(
-      const Type *result_type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &left,
-                            const Type &left_type,
-                            const TypedValue &right,
-                            const Type &right_type) const override;
-
-  UncheckedBinaryOperator* makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                               const Type &right) const override;
-
- private:
-  ModuloBinaryOperation()
-      : ArithmeticBinaryOperation(BinaryOperationID::kModulo) {
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(ModuloBinaryOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_MODULO_BINARY_OPERATION_HPP_


[33/38] incubator-quickstep git commit: More updates, refactor names

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMakeLists.txt b/types/operations/binary_operations/CMakeLists.txt
index 09566aa..c6fd4e2 100644
--- a/types/operations/binary_operations/CMakeLists.txt
+++ b/types/operations/binary_operations/CMakeLists.txt
@@ -16,30 +16,30 @@
 # under the License.
 
 # Declare micro-libs:
-add_library(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
+add_library(quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctors
             ../../../empty_src.cpp
-            ArithmeticBinaryOperations.hpp)
+            ArithmeticBinaryFunctors.hpp)
 add_library(quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
             ../../../empty_src.cpp
             ArithmeticBinaryFunctorOverloads.hpp)
-add_library(quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
+add_library(quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors
             ../../../empty_src.cpp
-            AsciiStringBinaryOperations.hpp)
+            AsciiStringBinaryFunctors.hpp)
 add_library(quickstep_types_operations_binaryoperations_BinaryOperation
             BinaryOperation.cpp
             BinaryOperation.hpp)
 add_library(quickstep_types_operations_binaryoperations_BinaryOperationWrapper
             ../../../empty_src.cpp
             BinaryOperationWrapper.hpp)
-add_library(quickstep_types_operations_binaryoperations_CMathBinaryOperations
+add_library(quickstep_types_operations_binaryoperations_CMathBinaryFunctors
             ../../../empty_src.cpp
-            CMathBinaryOperations.hpp)
+            CMathBinaryFunctors.hpp)
 
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
                       quickstep_types_DateOperatorOverloads
                       quickstep_utility_meta_Common)
-target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
+target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctors
                       quickstep_types_DateType
                       quickstep_types_DatetimeIntervalType
                       quickstep_types_DatetimeLit
@@ -55,7 +55,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBina
                       quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
                       quickstep_types_operations_binaryoperations_BinaryOperationWrapper
                       quickstep_utility_meta_Common)
-target_link_libraries(quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
+target_link_libraries(quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors
                       glog
                       quickstep_types_CharType
                       quickstep_types_IntType
@@ -63,8 +63,8 @@ target_link_libraries(quickstep_types_operations_binaryoperations_AsciiStringBin
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_VarCharType
-                      quickstep_types_operations_OperationUtil
                       quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_types_port_strnlen)
 target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_catalog_CatalogTypedefs
@@ -84,29 +84,29 @@ target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperatio
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVector
                       quickstep_types_operations_OperationSignature
-                      quickstep_types_operations_OperationUtil
                       quickstep_types_operations_binaryoperations_BinaryOperation
+                      quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_utility_Macros
                       quickstep_utility_meta_Common)
-target_link_libraries(quickstep_types_operations_binaryoperations_CMathBinaryOperations
+target_link_libraries(quickstep_types_operations_binaryoperations_CMathBinaryFunctors
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
-                      quickstep_types_operations_OperationUtil
                       quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_utility_meta_Common)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_binaryoperations ../../../empty_src.cpp)
 target_link_libraries(quickstep_types_operations_binaryoperations
                       quickstep_types_operations_binaryoperations_AddBinaryOperation
-                      quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
+                      quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctors
                       quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
-                      quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
+                      quickstep_types_operations_binaryoperations_AsciiStringBinaryFunctors
                       quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_types_operations_binaryoperations_BinaryOperationWrapper
-                      quickstep_types_operations_binaryoperations_CMathBinaryOperations)
+                      quickstep_types_operations_binaryoperations_CMathBinaryFunctors)
 
 # Tests:
 add_library(quickstep_types_operations_binaryoperations_tests_BinaryOperationTestUtil

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/CMathBinaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMathBinaryFunctors.hpp b/types/operations/binary_operations/CMathBinaryFunctors.hpp
new file mode 100644
index 0000000..c6fff3b
--- /dev/null
+++ b/types/operations/binary_operations/CMathBinaryFunctors.hpp
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_CMATH_BINARY_FUNCTORS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_CMATH_BINARY_FUNCTORS_HPP_
+
+#include <cmath>
+#include <string>
+
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename LeftT, typename RightT, typename ResultT,
+          typename ResultT::cpptype f(typename LeftT::cpptype,
+                                      typename RightT::cpptype),
+          typename FunctorNameT>
+struct CMathBinaryFunctorWrapper {
+  struct Implemenation : public BinaryFunctor<LeftT, RightT, ResultT> {
+    inline typename ResultT::cpptype apply(
+        const typename LeftT::cpptype &left,
+        const typename RightT::cpptype &right) const {
+      return f(left, right);
+    }
+    inline static std::string GetName() {
+      return FunctorNameT::ToString();
+    }
+  };
+
+  typedef Implemenation type;
+};
+
+template <typename LeftT, typename RightT, typename ResultT,
+          typename ResultT::cpptype f(typename LeftT::cpptype,
+                                      typename RightT::cpptype),
+          typename FunctorNameT>
+using CMathBinaryFunctor =
+    typename CMathBinaryFunctorWrapper<LeftT, RightT, ResultT, f, FunctorNameT>::type;
+
+using CMathBinaryFunctorPack = FunctorPack<
+// pow
+    CMathBinaryFunctor<FloatType, FloatType, FloatType,
+                       std::pow, meta::StringLiteral<'p','o','w'>>,
+    CMathBinaryFunctor<DoubleType, DoubleType, DoubleType,
+                       std::pow, meta::StringLiteral<'p','o','w'>>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_CMATH_BINARY_FUNCTORS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/CMathBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMathBinaryOperations.hpp b/types/operations/binary_operations/CMathBinaryOperations.hpp
deleted file mode 100644
index 9a90a12..0000000
--- a/types/operations/binary_operations/CMathBinaryOperations.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_CMATH_BINARY_OPERATIONS_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_CMATH_BINARY_OPERATIONS_HPP_
-
-#include <cmath>
-#include <string>
-
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
-#include "types/operations/OperationUtil.hpp"
-#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
-#include "utility/meta/Common.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename LeftT, typename RightT, typename ResultT,
-          typename ResultT::cpptype f(typename LeftT::cpptype,
-                                      typename RightT::cpptype),
-          typename FunctorNameT>
-struct CMathBinaryFunctorWrapper {
-  struct Implemenation : public BinaryFunctor<LeftT, RightT, ResultT> {
-    inline typename ResultT::cpptype apply(
-        const typename LeftT::cpptype &left,
-        const typename RightT::cpptype &right) const {
-      return f(left, right);
-    }
-    inline static std::string GetName() {
-      return FunctorNameT::ToString();
-    }
-  };
-
-  typedef Implemenation type;
-};
-
-template <typename LeftT, typename RightT, typename ResultT,
-          typename ResultT::cpptype f(typename LeftT::cpptype,
-                                      typename RightT::cpptype),
-          typename FunctorNameT>
-using CMathBinaryFunctor =
-    typename CMathBinaryFunctorWrapper<LeftT, RightT, ResultT, f, FunctorNameT>::type;
-
-using CMathBinaryFunctorPack = FunctorPack<
-// pow
-    CMathBinaryFunctor<FloatType, FloatType, FloatType,
-                       std::pow, meta::StringLiteral<'p','o','w'>>,
-    CMathBinaryFunctor<DoubleType, DoubleType, DoubleType,
-                       std::pow, meta::StringLiteral<'p','o','w'>>
->;
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/binary_operations/MultiplyBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/MultiplyBinaryOperation.hpp b/types/operations/binary_operations/MultiplyBinaryOperation.hpp
deleted file mode 100644
index cc005e2..0000000
--- a/types/operations/binary_operations/MultiplyBinaryOperation.hpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_MULTIPLY_BINARY_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_MULTIPLY_BINARY_OPERATION_HPP_
-
-#include <utility>
-
-#include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class Type;
-class UncheckedBinaryOperator;
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief The BinaryOperation for multiplication.
- **/
-class MultiplyBinaryOperation : public ArithmeticBinaryOperation {
- public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const MultiplyBinaryOperation& Instance() {
-    static MultiplyBinaryOperation instance;
-    return instance;
-  }
-
-  bool isCommutative() const override {
-    return true;
-  }
-
-  bool canApplyToTypes(const Type &left,
-                       const Type &right) const override;
-
-  const Type* resultTypeForArgumentTypes(const Type &left,
-                                         const Type &right) const override;
-
-  const Type* resultTypeForPartialArgumentTypes(const Type *left,
-                                                const Type *right) const override;
-
-  bool partialTypeSignatureIsPlausible(const Type *result_type,
-                                       const Type *left_argument_type,
-                                       const Type *right_argument_type) const override;
-
-  std::pair<const Type*, const Type*> pushDownTypeHint(
-      const Type *result_type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &left,
-                            const Type &left_type,
-                            const TypedValue &right,
-                            const Type &right_type) const override;
-
-  UncheckedBinaryOperator* makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                               const Type &right) const override;
-
- private:
-  MultiplyBinaryOperation()
-      : ArithmeticBinaryOperation(BinaryOperationID::kMultiply) {
-  }
-
-  // NOTE(zuyu): left is an Interval TypedValue, either DatetimeInterval
-  // or YearMonthInterval, while right is a Numeric.
-  template <typename IntervalType>
-  TypedValue applyToCheckedIntervalMultiplyNumericHelper(const TypedValue &left,
-                                                         const Type &left_type,
-                                                         const TypedValue &right,
-                                                         const Type &right_type) const;
-
-  DISALLOW_COPY_AND_ASSIGN(MultiplyBinaryOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_MULTIPLY_BINARY_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp b/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp
new file mode 100644
index 0000000..ad45535
--- /dev/null
+++ b/types/operations/unary_operations/ArithmeticUnaryFunctors.hpp
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_FUNCTORS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_FUNCTORS_HPP_
+
+#include <string>
+
+#include "types/DatetimeIntervalType.hpp"
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/YearMonthIntervalType.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename T>
+struct NegateFunctor : public UnaryFunctor<T, T> {
+  inline typename T::cpptype apply(const typename T::cpptype &argument) const {
+    return -argument;
+  }
+  inline static std::string GetName() {
+    return "-";
+  }
+};
+
+template <typename ArgumentT>
+struct SgnFunctor : public UnaryFunctor<ArgumentT, IntType> {
+  inline int apply(const typename ArgumentT::cpptype &argument) const {
+    return (argument > 0) - (argument < 0);
+  }
+  inline static std::string GetName() {
+    return "Sgn";
+  }
+};
+
+using ArithmeticUnaryFunctorPack = FunctorPack<
+// negate
+  NegateFunctor<IntType>,
+  NegateFunctor<LongType>,
+  NegateFunctor<FloatType>,
+  NegateFunctor<DoubleType>,
+  NegateFunctor<DatetimeIntervalType>,
+  NegateFunctor<YearMonthIntervalType>,
+
+// sgn (Sign of a numeric value)
+  SgnFunctor<IntType>,
+  SgnFunctor<LongType>,
+  SgnFunctor<FloatType>,
+  SgnFunctor<DoubleType>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_FUNCTORS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/ArithmeticUnaryOperations.hpp b/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
deleted file mode 100644
index 4c212c0..0000000
--- a/types/operations/unary_operations/ArithmeticUnaryOperations.hpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_OPERATIONS_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_OPERATIONS_HPP_
-
-#include <string>
-
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/OperationUtil.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename ArgumentT, typename ResultT>
-struct NegateFunctor : public UnaryFunctor<ArgumentT, ResultT> {
-  inline typename ResultT::cpptype apply(
-      const typename ArgumentT::cpptype &argument) const {
-    return -argument;
-  }
-  inline static std::string GetName() {
-    return "-";
-  }
-};
-
-template <typename ArgumentT>
-struct SgnFunctor : public UnaryFunctor<ArgumentT, IntType> {
-  inline int apply(const typename ArgumentT::cpptype &argument) const {
-    return (argument > 0) - (argument < 0);
-  }
-  inline static std::string GetName() {
-    return "Sgn";
-  }
-};
-
-using ArithmeticUnaryFunctorPack = FunctorPack<
-// negate
-  NegateFunctor<IntType, IntType>,
-  NegateFunctor<LongType, LongType>,
-  NegateFunctor<FloatType, FloatType>,
-  NegateFunctor<DoubleType, DoubleType>,
-  NegateFunctor<DatetimeIntervalType, DatetimeIntervalType>,
-  NegateFunctor<YearMonthIntervalType, YearMonthIntervalType>,
-
-// sgn (Sign of a numeric value)
-  SgnFunctor<IntType>,
-  SgnFunctor<LongType>,
-  SgnFunctor<FloatType>,
-  SgnFunctor<DoubleType>
->;
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ARITHMETIC_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/AsciiStringUnaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/AsciiStringUnaryFunctors.hpp b/types/operations/unary_operations/AsciiStringUnaryFunctors.hpp
new file mode 100644
index 0000000..34a78ab
--- /dev/null
+++ b/types/operations/unary_operations/AsciiStringUnaryFunctors.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_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_FUNCTORS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_FUNCTORS_HPP_
+
+#include <cctype>
+#include <cstring>
+#include <string>
+
+#include "types/CharType.hpp"
+#include "types/IntType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/VarCharType.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
+#include "types/port/strnlen.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT>
+struct AsciiStringLengthFunctor : public UnaryFunctor<ArgumentT, IntType> {
+  explicit AsciiStringLengthFunctor(const ArgumentT &argument_type)
+      : max_string_length_(argument_type.getStringLength()) {}
+  inline int apply(const void *argument) const {
+    return strnlen(static_cast<const char*>(argument), max_string_length_);
+  }
+  inline int apply(const TypedValue &argument) const {
+    DCHECK(argument.getTypeID() == kVarChar);
+    return std::strlen(static_cast<const char*>(argument.getOutOfLineData()));
+  }
+  inline static std::string GetName() {
+    return "length";
+  }
+  const std::size_t max_string_length_;
+};
+
+template <typename ArgumentT, int transform(int), typename FunctorNameT>
+struct AsciiStringTranformFunctor : public UnaryFunctor<ArgumentT, ArgumentT> {
+  explicit AsciiStringTranformFunctor(const ArgumentT &argument_type)
+      : max_string_length_(argument_type.getStringLength()) {}
+  inline void apply(const void *argument, void *result) const {
+    DCHECK(ArgumentT::kStaticTypeID == kChar);
+    const char *argument_str = static_cast<const char*>(argument);
+    char *result_str = static_cast<char*>(result);
+    for (std::size_t i = 0; i < max_string_length_; ++i) {
+      if ((result_str[i] = transform(argument_str[i])) == 0) {
+        break;
+      }
+    }
+  }
+  inline TypedValue apply(const TypedValue &argument) const {
+    DCHECK(argument.getTypeID() == kVarChar);
+    const char *argument_str = static_cast<const char*>(argument.getOutOfLineData());
+    const std::size_t length = argument.getDataSize();
+    char *buf = static_cast<char*>(std::malloc(length));
+
+    for (std::size_t i = 0; i < length; ++i) {
+      buf[i] = transform(argument_str[i]);
+    }
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, length);
+  }
+  inline static std::string GetName() {
+    return FunctorNameT::ToString();
+  }
+  inline static const Type* GetResultType(const Type &argument_type) {
+    DCHECK(argument_type.getTypeID() == ArgumentT::kStaticTypeID);
+    return &argument_type;
+  }
+  const std::size_t max_string_length_;
+};
+
+template <typename ArgumentT>
+using AsciiStringToLowerCaseFunctor =
+    AsciiStringTranformFunctor<ArgumentT, std::tolower,
+                               meta::StringLiteral<'t', 'o', 'l', 'o', 'w', 'e', 'r'>>;
+
+template <typename ArgumentT>
+using AsciiStringToUpperCaseFunctor =
+    AsciiStringTranformFunctor<ArgumentT, std::toupper,
+                               meta::StringLiteral<'t', 'o', 'u', 'p', 'p', 'e', 'r'>>;
+
+using AsciiStringUnaryFunctorPack = FunctorPack<
+// length
+    AsciiStringLengthFunctor<CharType>,
+    AsciiStringLengthFunctor<VarCharType>,
+// tolower
+    AsciiStringToLowerCaseFunctor<CharType>,
+    AsciiStringToLowerCaseFunctor<VarCharType>,
+// toupper
+    AsciiStringToUpperCaseFunctor<CharType>,
+    AsciiStringToUpperCaseFunctor<VarCharType>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_FUNCTORS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/AsciiStringUnaryOperations.hpp b/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
deleted file mode 100644
index 1ee1867..0000000
--- a/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_OPERATIONS_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_OPERATIONS_HPP_
-
-#include <cctype>
-#include <cstring>
-#include <string>
-
-#include "types/CharType.hpp"
-#include "types/IntType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/VarCharType.hpp"
-#include "types/operations/OperationUtil.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
-#include "types/port/strnlen.hpp"
-#include "utility/meta/Common.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename ArgumentT>
-struct AsciiStringLengthFunctor : public UnaryFunctor<ArgumentT, IntType> {
-  explicit AsciiStringLengthFunctor(const ArgumentT &argument_type)
-      : max_string_length_(argument_type.getStringLength()) {}
-  inline int apply(const void *argument) const {
-    return strnlen(static_cast<const char*>(argument), max_string_length_);
-  }
-  inline int apply(const TypedValue &argument) const {
-    DCHECK(argument.getTypeID() == kVarChar);
-    return std::strlen(static_cast<const char*>(argument.getOutOfLineData()));
-  }
-  inline static std::string GetName() {
-    return "length";
-  }
-  const std::size_t max_string_length_;
-};
-
-template <typename ArgumentT, int transform(int), typename FunctorNameT>
-struct AsciiStringTranformFunctor : public UnaryFunctor<ArgumentT, ArgumentT> {
-  explicit AsciiStringTranformFunctor(const ArgumentT &argument_type)
-      : max_string_length_(argument_type.getStringLength()) {}
-  inline void apply(const void *argument, void *result) const {
-    DCHECK(ArgumentT::kStaticTypeID == kChar);
-    const char *argument_str = static_cast<const char*>(argument);
-    char *result_str = static_cast<char*>(result);
-    for (std::size_t i = 0; i < max_string_length_; ++i) {
-      if ((result_str[i] = transform(argument_str[i])) == 0) {
-        break;
-      }
-    }
-  }
-  inline TypedValue apply(const TypedValue &argument) const {
-    DCHECK(argument.getTypeID() == kVarChar);
-    const char *argument_str = static_cast<const char*>(argument.getOutOfLineData());
-    const std::size_t length = argument.getDataSize();
-    char *buf = static_cast<char*>(std::malloc(length));
-
-    for (std::size_t i = 0; i < length; ++i) {
-      buf[i] = transform(argument_str[i]);
-    }
-    return TypedValue::CreateWithOwnedData(kVarChar, buf, length);
-  }
-  inline static std::string GetName() {
-    return FunctorNameT::ToString();
-  }
-  inline static const Type* GetResultType(const Type &argument_type) {
-    DCHECK(argument_type.getTypeID() == ArgumentT::kStaticTypeID);
-    return &argument_type;
-  }
-  const std::size_t max_string_length_;
-};
-
-template <typename ArgumentT>
-using AsciiStringToLowerCaseFunctor =
-    AsciiStringTranformFunctor<ArgumentT, std::tolower,
-                               meta::StringLiteral<'t', 'o', 'l', 'o', 'w', 'e', 'r'>>;
-
-template <typename ArgumentT>
-using AsciiStringToUpperCaseFunctor =
-    AsciiStringTranformFunctor<ArgumentT, std::toupper,
-                               meta::StringLiteral<'t', 'o', 'u', 'p', 'p', 'e', 'r'>>;
-
-using AsciiStringUnaryFunctorPack = FunctorPack<
-// length
-    AsciiStringLengthFunctor<CharType>,
-    AsciiStringLengthFunctor<VarCharType>,
-// tolower
-    AsciiStringToLowerCaseFunctor<CharType>,
-    AsciiStringToLowerCaseFunctor<VarCharType>,
-// toupper
-    AsciiStringToUpperCaseFunctor<CharType>,
-    AsciiStringToUpperCaseFunctor<VarCharType>
->;
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index bcd756e..fbfd091 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -16,15 +16,18 @@
 # under the License.
 
 # Declare micro-libs:
-add_library(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+add_library(quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
             ../../../empty_src.cpp
-            ArithmeticUnaryOperations.hpp)
-add_library(quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+            ArithmeticUnaryFunctors.hpp)
+add_library(quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors
             ../../../empty_src.cpp
-            AsciiStringUnaryOperations.hpp)
-add_library(quickstep_types_operations_unaryoperations_CMathUnaryOperations
+            AsciiStringUnaryFunctors.hpp)
+add_library(quickstep_types_operations_unaryoperations_CMathUnaryFunctors
             ../../../empty_src.cpp
-            CMathUnaryOperations.hpp)
+            CMathUnaryFunctors.hpp)
+add_library(quickstep_types_operations_unaryoperations_CastFunctorOverloads
+            ../../../empty_src.cpp
+            CastFunctorOverloads.hpp)
 add_library(quickstep_types_operations_unaryoperations_CastOperation CastOperation.cpp CastOperation.hpp)
 add_library(quickstep_types_operations_unaryoperations_DateExtractOperation
             DateExtractOperation.cpp
@@ -38,7 +41,7 @@ add_library(quickstep_types_operations_unaryoperations_UnaryOperationWrapper
             UnaryOperationWrapper.hpp)
 
 # Link dependencies:
-target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
                       glog
                       quickstep_types_DatetimeIntervalType
                       quickstep_types_DoubleType
@@ -46,26 +49,26 @@ target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnary
                       quickstep_types_IntType
                       quickstep_types_LongType
                       quickstep_types_YearMonthIntervalType
-                      quickstep_types_operations_OperationUtil
-                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper)
-target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+                      quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_utility_OperationSynthesizeUtil)
+target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors
                       quickstep_types_CharType
                       quickstep_types_IntType
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_VarCharType
-                      quickstep_types_operations_OperationUtil
                       quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_types_port_strnlen
                       quickstep_utility_meta_Common)
-target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryOperations
+target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryFunctors
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
                       quickstep_types_IntType
                       quickstep_types_LongType
-                      quickstep_types_operations_OperationUtil
                       quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+                      quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_unaryoperations_CastOperation
                       glog
@@ -134,16 +137,17 @@ target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperationW
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVector
                       quickstep_types_operations_OperationSignature
-                      quickstep_types_operations_OperationUtil
                       quickstep_types_operations_unaryoperations_UnaryOperation
+                      quickstep_types_operations_utility_OperationSynthesizeUtil
                       quickstep_utility_Macros)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_unaryoperations ../../../empty_src.cpp)
 target_link_libraries(quickstep_types_operations_unaryoperations
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
-                      quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
-                      quickstep_types_operations_unaryoperations_CMathUnaryOperations
+                      quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
+                      quickstep_types_operations_unaryoperations_AsciiStringUnaryFunctors
+                      quickstep_types_operations_unaryoperations_CMathUnaryFunctors
+                      quickstep_types_operations_unaryoperations_CastFunctorOverloads
                       quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_SubstringOperation
@@ -172,7 +176,7 @@ target_link_libraries(UnaryOperation_tests
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVector
                       quickstep_types_operations_Operation_proto
-                      quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+                      quickstep_types_operations_unaryoperations_ArithmeticUnaryFunctors
                       quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_DateExtractOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/CMathUnaryFunctors.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryFunctors.hpp b/types/operations/unary_operations/CMathUnaryFunctors.hpp
new file mode 100644
index 0000000..5ed8b50
--- /dev/null
+++ b/types/operations/unary_operations/CMathUnaryFunctors.hpp
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_FUNCTORS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_FUNCTORS_HPP_
+
+#include <cmath>
+#include <string>
+
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT, typename ResultT,
+          typename ResultT::cpptype f(typename ArgumentT::cpptype),
+          typename FunctorNameT>
+struct CMathUnaryFunctorWrapper {
+  struct Implemenation : public UnaryFunctor<ArgumentT, ResultT> {
+    inline typename ResultT::cpptype apply(
+        const typename ArgumentT::cpptype &argument) const {
+      return f(argument);
+    }
+    inline static std::string GetName() {
+      return FunctorNameT::ToString();
+    }
+  };
+
+  typedef Implemenation type;
+};
+
+template <typename ArgumentT, typename ResultT,
+          typename ResultT::cpptype f(typename ArgumentT::cpptype),
+          typename FunctorNameT>
+using CMathUnaryFunctor =
+    typename CMathUnaryFunctorWrapper<ArgumentT, ResultT, f, FunctorNameT>::type;
+
+inline std::int64_t CMathRound(const float arg) {
+  return std::llround(arg);
+}
+inline std::int64_t CMathRound(const double arg) {
+  return std::llround(arg);
+}
+
+using CMathUnaryFunctorPack = FunctorPack<
+// abs
+    CMathUnaryFunctor<IntType, IntType,
+                      std::abs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<LongType, LongType,
+                      std::abs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::fabs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::fabs, meta::StringLiteral<'a','b','s'>>,
+// sqrt
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
+// exp
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::exp, meta::StringLiteral<'e','x','p'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::exp, meta::StringLiteral<'e','x','p'>>,
+// log
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::log, meta::StringLiteral<'l','o','g'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::log, meta::StringLiteral<'l','o','g'>>,
+// ceil
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
+// floor
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
+// round
+    CMathUnaryFunctor<FloatType, LongType,
+                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>,
+    CMathUnaryFunctor<DoubleType, LongType,
+                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_FUNCTORS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/CMathUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryOperations.hpp b/types/operations/unary_operations/CMathUnaryOperations.hpp
deleted file mode 100644
index 7a372e0..0000000
--- a/types/operations/unary_operations/CMathUnaryOperations.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_
-
-#include <cmath>
-#include <string>
-
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
-#include "types/operations/OperationUtil.hpp"
-#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
-#include "utility/meta/Common.hpp"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-template <typename ArgumentT, typename ResultT,
-          typename ResultT::cpptype f(typename ArgumentT::cpptype),
-          typename FunctorNameT>
-struct CMathUnaryFunctorWrapper {
-  struct Implemenation : public UnaryFunctor<ArgumentT, ResultT> {
-    inline typename ResultT::cpptype apply(
-        const typename ArgumentT::cpptype &argument) const {
-      return f(argument);
-    }
-    inline static std::string GetName() {
-      return FunctorNameT::ToString();
-    }
-  };
-
-  typedef Implemenation type;
-};
-
-template <typename ArgumentT, typename ResultT,
-          typename ResultT::cpptype f(typename ArgumentT::cpptype),
-          typename FunctorNameT>
-using CMathUnaryFunctor =
-    typename CMathUnaryFunctorWrapper<ArgumentT, ResultT, f, FunctorNameT>::type;
-
-inline std::int64_t CMathRound(const float arg) {
-  return std::llround(arg);
-}
-inline std::int64_t CMathRound(const double arg) {
-  return std::llround(arg);
-}
-
-using CMathUnaryFunctorPack = FunctorPack<
-// abs
-    CMathUnaryFunctor<IntType, IntType,
-                      std::abs, meta::StringLiteral<'a','b','s'>>,
-    CMathUnaryFunctor<LongType, LongType,
-                      std::abs, meta::StringLiteral<'a','b','s'>>,
-    CMathUnaryFunctor<FloatType, FloatType,
-                      std::fabs, meta::StringLiteral<'a','b','s'>>,
-    CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::fabs, meta::StringLiteral<'a','b','s'>>,
-// sqrt
-    CMathUnaryFunctor<FloatType, FloatType,
-                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
-    CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
-// exp
-    CMathUnaryFunctor<FloatType, FloatType,
-                      std::exp, meta::StringLiteral<'e','x','p'>>,
-    CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::exp, meta::StringLiteral<'e','x','p'>>,
-// log
-    CMathUnaryFunctor<FloatType, FloatType,
-                      std::log, meta::StringLiteral<'l','o','g'>>,
-    CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::log, meta::StringLiteral<'l','o','g'>>,
-// ceil
-    CMathUnaryFunctor<FloatType, FloatType,
-                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
-    CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
-// floor
-    CMathUnaryFunctor<FloatType, FloatType,
-                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
-    CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
-// round
-    CMathUnaryFunctor<FloatType, LongType,
-                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>,
-    CMathUnaryFunctor<DoubleType, LongType,
-                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>
->;
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/CastFunctorOverloads.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastFunctorOverloads.hpp b/types/operations/unary_operations/CastFunctorOverloads.hpp
new file mode 100644
index 0000000..940cab6
--- /dev/null
+++ b/types/operations/unary_operations/CastFunctorOverloads.hpp
@@ -0,0 +1,183 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CAST_FUNCTOR_OVERLOADS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CAST_FUNCTOR_OVERLOADS_HPP_
+
+#include <algorithm>
+#include <cstdint>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "types/TypeRegistrar.hpp"
+#include "types/TypedValue.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "utility/meta/TypeList.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename SourceType, typename TargetType, typename Enable = void>
+struct CastFunctor;
+
+// ----------------------------------------------------------------------------
+// Implementations of numeric to numeric casts.
+
+using NumericTypes = meta::TypeList<BoolType, IntType, LongType, FloatType, DoubleType>;
+using NumericCastOverloads = NumericTypes::cartesian_product<NumericTypes>;
+
+template <typename SourceType, typename TargetType>
+struct CastFunctor<
+    SourceType, TargetType,
+    std::enable_if_t<
+        NumericCastOverloads::contains<meta::TypeList<SourceType, TargetType>>::value>>
+    : public UnaryFunctor<SourceType, TargetType> {
+  inline typename TargetType::cpptype apply(
+      const typename SourceType::cpptype &argument) const {
+    return static_cast<typename TargetType::cpptype>(argument);
+  }
+};
+
+
+// ----------------------------------------------------------------------------
+// Implementations of any type to ascii string casts.
+
+template <typename SourceType>
+struct CastFunctor<SourceType, CharType,
+                   std::enable_if_t<SourceType::kStaticSuperTypeID == SuperTypeID::kNumeric>>
+    : public UnaryFunctor<SourceType, CharType> {
+  explicit CastFunctor(const SourceType &source_type_in,
+                       const CharType &target_type_in)
+      : source_type(source_type_in),
+        max_string_length(target_type_in.getStringLength()) {}
+  inline void apply(const typename SourceType::cpptype &argument, void *result) const {
+    std::string str = source_type.printValueToString(&argument);
+    const std::size_t str_len = str.length();
+    if (str_len < max_string_length) {
+      std::memcpy(result, str.c_str(), str_len);
+      static_cast<char *>(result)[str_len] = 0;
+    } else {
+      std::memcpy(result, str.c_str(), max_string_length);
+    }
+  }
+  const SourceType &source_type;
+  const std::size_t max_string_length;
+};
+
+template <typename SourceType>
+struct CastFunctor<SourceType, VarCharType,
+                   std::enable_if_t<SourceType::kStaticSuperTypeID == SuperTypeID::kNumeric>>
+    : public UnaryFunctor<SourceType, VarCharType> {
+  explicit CastFunctor(const SourceType &source_type_in,
+                       const VarCharType &target_type_in)
+      : source_type(source_type_in),
+        max_string_length(target_type_in.getStringLength()) {}
+  inline TypedValue apply(const typename SourceType::cpptype &argument) const {
+    std::string str = source_type.printValueToString(&argument);
+    const std::size_t len = std::min(str.length(), max_string_length);
+    const std::size_t buf_len = len + 1;
+    char *buf = static_cast<char *>(std::malloc(buf_len));
+    std::memcpy(buf, str.c_str(), len);
+    buf[len] = 0;
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+  const SourceType &source_type;
+  const std::size_t max_string_length;
+};
+
+//template <typename SourceType>
+//struct CastFunctor<SourceType, TextType>
+//    : public UnaryFunctor<SourceType, TextType> {
+//  explicit CastFunctor(const SourceType &source_type_in,
+//                       const TextType &target_type_in)
+//      : source_type(source_type_in) {}
+//  inline std::string apply(const typename SourceType::cpptype &argument) const {
+//    return source_type.printValueToString(&argument);
+//  }
+//  const SourceType &source_type;
+//};
+//
+//
+//// ----------------------------------------------------------------------------
+//// Implementations of ascii string to numeric casts.
+//
+//template <typename T>
+//T CastStringToNumericOverload(const char *str);
+//
+//template <>
+//bool CastStringToNumericOverload(const char *str) {
+//  return ToLower(str) == "true";
+//}
+//template <>
+//int CastStringToNumericOverload(const char *str) {
+//  return std::atoi(str);
+//}
+//template <>
+//float CastStringToNumericOverload(const char *str) {
+//  return static_cast<float>(std::atof(str));
+//}
+//template <>
+//std::int64_t CastStringToNumericOverload(const char *str) {
+//  return std::atoll(str);
+//}
+//template <>
+//double CastStringToNumericOverload(const char *str) {
+//  return std::atof(str);
+//}
+//
+//template <typename TargetType>
+//struct CastFunctor<CharType, TargetType,
+//                   std::enable_if_t<NumericTypes::contains<TargetType>::value>>
+//    : public UnaryFunctor<CharType, TargetType> {
+//  explicit CastFunctor(const CharType &source_type_in,
+//                       const TargetType &target_type_in)
+//      : max_string_length(source_type_in.getStringLength()) {}
+//  inline typename TargetType::cpptype apply(const void *argument) const {
+//    const char *str = static_cast<const char*>(argument);
+//    const std::string value(str, strnlen(str, max_string_length));
+//    return CastStringToNumericOverload<typename TargetType::cpptype>(value.c_str());
+//  }
+//  const std::size_t max_string_length;
+//};
+//
+//
+//template <typename TargetType>
+//struct CastFunctor<VarCharType, TargetType,
+//                   std::enable_if_t<NumericTypes::contains<TargetType>::value>>
+//    : public UnaryFunctor<VarCharType, TargetType> {
+//  explicit CastFunctor(const VarCharType &source_type_in,
+//                       const TargetType &target_type_in)
+//      : max_string_length(source_type_in.getStringLength()) {}
+//  inline typename TargetType::cpptype apply(const TypedValue &argument) const {
+//    return CastStringToNumericOverload<typename TargetType::cpptype>(
+//        static_cast<const char*>(argument.getDataPtr()));
+//  }
+//  const std::size_t max_string_length;
+//};
+
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CAST_FUNCTOR_OVERLOADS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp
index 8e0db55..8f725e2 100644
--- a/types/operations/unary_operations/CastOperation.cpp
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -29,169 +29,105 @@
 #include "types/CharType.hpp"
 #include "types/DoubleType.hpp"
 #include "types/FloatType.hpp"
+#include "types/GenericValue.hpp"
 #include "types/IntType.hpp"
 #include "types/LongType.hpp"
+#include "types/MetaType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeUtil.hpp"
 #include "types/TypedValue.hpp"
 #include "types/VarCharType.hpp"
+#include "types/operations/unary_operations/CastFunctorOverloads.hpp"
 #include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
 #include "types/port/strnlen.hpp"
 #include "utility/EqualsAnyConstant.hpp"
 #include "utility/StringUtil.hpp"
+#include "utility/meta/Common.hpp"
 
 namespace quickstep {
 
 namespace {
 
-template <typename ArgumentT, typename ResultT>
-struct NumericCastToNumericFunctor
-    : public UnaryFunctor<ArgumentT, ResultT> {
-  inline typename ResultT::cpptype apply(
-      const typename ArgumentT::cpptype &argument) const {
-    return static_cast<typename ResultT::cpptype>(argument);
-  }
-};
-
-template <typename ArgumentT, typename ResultT>
-class CastToAsciiStringFunctor : public UnaryFunctor<ArgumentT, ResultT> {
- public:
-  explicit CastToAsciiStringFunctor(const ArgumentT &argument_type,
-                                    const std::size_t max_string_length)
-      : argument_type_(argument_type),
-        max_string_length_(max_string_length) {}
-
-  inline void apply(const typename ArgumentT::cpptype &argument, void *result) const {
-    std::string str = argument_type_.printValueToString(&argument);
-    const std::size_t str_len = str.length();
-
-    if (str_len < max_string_length_) {
-      std::memcpy(result, str.c_str(), str_len);
-      static_cast<char *>(result)[str_len] = 0;
-    } else {
-      std::memcpy(result, str.c_str(), max_string_length_);
-    }
-  }
-
-  inline TypedValue apply(const typename ArgumentT::cpptype &argument) const {
-    std::string str = argument_type_.printValueToString(&argument);
-    const std::size_t len = std::min(str.length(), max_string_length_);
-    const std::size_t buf_len = len + 1;
-
-    char *buf = static_cast<char *>(std::malloc(buf_len));
-    std::memcpy(buf, str.c_str(), len);
-    buf[len] = 0;
-    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
-  }
-
- private:
-  const ArgumentT &argument_type_;
-  const std::size_t max_string_length_;
-};
-
-template <typename ResultCppType>
-ResultCppType CastStringToNumericImpl(const char *str);
-
-template <>
-bool CastStringToNumericImpl(const char *str) {
-  const std::string lo_str = ToLower(str);
-  if (lo_str == "true") {
-    return true;
-  } else {
-    return false;
-  }
-}
-template <>
-int CastStringToNumericImpl(const char *str) {
-  return std::atoi(str);
-}
-template <>
-float CastStringToNumericImpl(const char *str) {
-  return static_cast<float>(std::atof(str));
-}
-template <>
-std::int64_t CastStringToNumericImpl(const char *str) {
-  return std::atoll(str);
-}
-template <>
-double CastStringToNumericImpl(const char *str) {
-  return std::atof(str);
+template <typename SourceType, typename TargetType>
+UncheckedUnaryOperator* MakeUncheckedCastOperatorConstructorSpec(
+    const SourceType &source_type,
+    const TargetType &target_type,
+    decltype(new CastFunctor<SourceType, TargetType>()) * = 0) {
+  return new UncheckedUnaryOperatorWrapperCodegen<
+      CastFunctor<SourceType, TargetType>>(
+          source_type, target_type);
 }
 
-template <typename ArgumentT, typename ResultT,
-          typename ResultT::cpptype f(const char*)>
-struct AsciiStringCastToNumericFunctor
-    : public UnaryFunctor<ArgumentT, ResultT> {
-  explicit AsciiStringCastToNumericFunctor(const std::size_t max_string_length)
-      : max_string_length_(max_string_length) {}
-
-  inline typename ResultT::cpptype apply(const TypedValue &argument) const {
-    return f(static_cast<const char*>(argument.getDataPtr()));
-  }
+template <typename SourceType, typename TargetType>
+UncheckedUnaryOperator* MakeUncheckedCastOperatorConstructorSpec(
+    const SourceType &source_type,
+    const TargetType &target_type,
+    decltype(new CastFunctor<SourceType, TargetType>(source_type, target_type)) * = 0) {
+  return new UncheckedUnaryOperatorWrapperCodegen<
+      CastFunctor<SourceType, TargetType>>(
+          source_type, target_type, source_type, target_type);
+}
 
-  inline typename ResultT::cpptype apply(const void *argument) const {
-    const char *str = static_cast<const char*>(argument);
-    const std::string value(str, strnlen(str, max_string_length_));
-    return f(value.c_str());
-  }
+template <typename SourceType, typename TargetType>
+UncheckedUnaryOperator* MakeUncheckedCastOperator(
+    const Type &source_type,
+    const Type &target_type,
+    std::enable_if_t<meta::IsCompleteType<CastFunctor<SourceType, TargetType>>::value> * = 0) {
+  return MakeUncheckedCastOperatorConstructorSpec(
+      static_cast<const SourceType&>(source_type),
+      static_cast<const TargetType&>(target_type));
+}
 
- private:
-  const std::size_t max_string_length_;
-};
+template <typename SourceType, typename TargetType>
+UncheckedUnaryOperator* MakeUncheckedCastOperator(
+    const Type &source_type,
+    const Type &target_type,
+    std::enable_if_t<!meta::IsCompleteType<CastFunctor<SourceType, TargetType>>::value> * = 0) {
+  LOG(FATAL) << "Unsupported cast from type " << source_type.getName()
+             << " to type " << target_type.getName();
+}
 
-template <typename ArgumentT, typename ResultT>
-struct AsciiStringCastToAsciiStringFunctor
-    : public UnaryFunctor<ArgumentT, ResultT> {
-  explicit AsciiStringCastToAsciiStringFunctor(const std::size_t max_string_length)
-      : max_string_length_(max_string_length) {}
+}  // namespace
 
-  inline void apply(const void *argument, void *result) const {
-    std::memcpy(result, argument, max_string_length_);
+const Type* CastOperation::ExtractTargetType(
+    const Type &type,
+    const std::vector<TypedValue> &static_arguments) {
+  if (static_arguments.size() != 1) {
+    return nullptr;
   }
-
-  inline void apply(const TypedValue &argument, void *result) const {
-    std::memcpy(result,
-                argument.getOutOfLineData(),
-                std::min(argument.getDataSize(), max_string_length_));
+  const GenericValue meta_type_value =
+      GenericValue::CreateWithTypedValue(MetaType::InstanceNonNullable(),
+                                         static_arguments.front());
+  if (meta_type_value.isNull() || meta_type_value.getTypeID() != kMetaType) {
+    return nullptr;
   }
+  return meta_type_value.getLiteral<kMetaType>();
+}
 
-  inline TypedValue apply(const void *argument) const {
-    const std::size_t len =
-        strnlen(static_cast<const char*>(argument), max_string_length_);
-
-    char *buf = static_cast<char *>(std::malloc(len+1));
-    std::memcpy(buf, argument, len);
-    buf[len] = 0;
-    return TypedValue::CreateWithOwnedData(kVarChar, buf, len+1);
+bool CastOperation::canApplyTo(
+    const Type &type,
+    const std::vector<TypedValue> &static_arguments,
+    std::string *message) const {
+  const Type *target_type = ExtractTargetType(type, static_arguments);
+  if (target_type == nullptr) {
+    *message = "Invalid target type";
+    return false;
   }
-
-  inline TypedValue apply(const TypedValue &argument) const {
-    const std::size_t len =
-        std::min(argument.getDataSize() - 1, max_string_length_);
-
-    char *buf = static_cast<char *>(std::malloc(len+1));
-    std::memcpy(buf, argument.getDataPtr(), len);
-    buf[len] = 0;
-    return TypedValue::CreateWithOwnedData(kVarChar, buf, len+1);
+  if (!target_type->isCoercibleFrom(type)) {
+    *message = "Unsupported cast from " + type.getName() +
+               " to " + target_type->getName();
+    return false;
   }
+  return true;
+}
 
- private:
-  const std::size_t max_string_length_;
-};
-
-}  // namespace
-
-const re2::RE2 CastOperation::kTypePattern("([a-z]+)(\\(([0-9]+)\\))?");
-
-const std::map<std::string, TypeID> CastOperation::kNameToTypeIDMap = {
-    { "bool",    kBool },
-    { "int",     kInt },
-    { "long",    kLong },
-    { "float",   kFloat },
-    { "double",  kDouble },
-    { "char",    kChar },
-    { "varchar", kVarChar }
-};
+const Type* CastOperation::getResultType(
+    const Type &type,
+    const std::vector<TypedValue> &static_arguments) const {
+  const Type *target_type = ExtractTargetType(type, static_arguments);
+  DCHECK(target_type != nullptr);
+  return target_type;
+}
 
 UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
     const Type &type,
@@ -199,100 +135,20 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
   const Type *result_type = getResultType(type, static_arguments);
   DCHECK(result_type != nullptr);
 
-  const TypeID argument_type_id = type.getTypeID();
-  const TypeID result_type_id = result_type->getTypeID();
-
-  if (QUICKSTEP_EQUALS_ANY_CONSTANT(argument_type_id, kBool, kInt, kLong, kFloat, kDouble)) {
-    return InvokeOnTypeID<TypeIDSelectorNumeric>(
-        argument_type_id,
-        [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-      using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
-
-      switch (result_type_id) {
-        case kBool:  // Fall through
-        case kInt:
-        case kLong:
-        case kFloat:
-        case kDouble: {
-          return InvokeOnTypeID<TypeIDSelectorNumeric>(
-              result_type_id,
-              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
-
-            return new UncheckedUnaryOperatorWrapperCodegen<
-                NumericCastToNumericFunctor<ArgumentT, ResultT>>(type, *result_type);
-          });
-        }
-        case kChar:  // Fall through
-        case kVarChar: {
-          return InvokeOnTypeID<TypeIDSelector<kChar, kVarChar>>(
-              result_type_id,
-              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
-
-            return new UncheckedUnaryOperatorWrapperCodegen<
-                 CastToAsciiStringFunctor<ArgumentT, ResultT>>(
-                     type, *result_type,
-                     static_cast<const ArgumentT&>(type),
-                     static_cast<const ResultT*>(result_type)->getStringLength());
-          });
-        }
-        default:
-          LOG(FATAL) << "Unexpected result type " << result_type->getName()
-                     << " in CastOperation::makeUncheckedUnaryOperator "
-                     << "for argument type " << type.getName();
-      }
+  const TypeID source_type_id = type.getTypeID();
+  const TypeID target_type_id = result_type->getTypeID();
+
+  return InvokeOnTypeID(
+      source_type_id,
+      [&](auto source) -> UncheckedUnaryOperator* {
+    return InvokeOnTypeID(
+        target_type_id,
+        [&](auto target) -> UncheckedUnaryOperator* {
+      return MakeUncheckedCastOperator<
+          typename TypeIDTrait<decltype(source)::value>::TypeClass,
+          typename TypeIDTrait<decltype(target)::value>::TypeClass>(type, *result_type);
     });
-  } else if (QUICKSTEP_EQUALS_ANY_CONSTANT(argument_type_id, kChar, kVarChar)) {
-    return InvokeOnTypeID<TypeIDSelector<kChar, kVarChar>>(
-        argument_type_id,
-        [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-      using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
-
-      switch (result_type_id) {
-        case kBool:  // Fall through
-        case kInt:
-        case kLong:
-        case kFloat:
-        case kDouble: {
-          return InvokeOnTypeID<TypeIDSelectorNumeric>(
-              result_type_id,
-              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
-
-            return new UncheckedUnaryOperatorWrapperCodegen<
-                AsciiStringCastToNumericFunctor<
-                    ArgumentT, ResultT,
-                    CastStringToNumericImpl<typename ResultT::cpptype>>>(
-                        type, *result_type,
-                        static_cast<const ArgumentT&>(type).getStringLength());
-          });
-        }
-        case kChar:  // Fall through
-        case kVarChar: {
-          return InvokeOnTypeID<TypeIDSelector<kChar, kVarChar>>(
-              result_type_id,
-              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
-
-            return new UncheckedUnaryOperatorWrapperCodegen<
-                 AsciiStringCastToAsciiStringFunctor<ArgumentT, ResultT>>(
-                     type, *result_type,
-                     std::min(static_cast<const ArgumentT&>(type).getStringLength(),
-                              static_cast<const ResultT*>(result_type)->getStringLength()));
-          });
-        }
-        default:
-          LOG(FATAL) << "Unexpected result type " << result_type->getName()
-                     << " in CastOperation::makeUncheckedUnaryOperator "
-                     << "for argument type " << type.getName();
-      }
-    });
-  }
-
-  LOG(FATAL) << "Unexpected argument type in "
-             << "CastOperation::makeUncheckedUnaryOperator: "
-             << result_type->getName();
+  });
 }
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/CastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp
index c0d3357..b8750c0 100644
--- a/types/operations/unary_operations/CastOperation.hpp
+++ b/types/operations/unary_operations/CastOperation.hpp
@@ -64,7 +64,7 @@ class CastOperation : public UnaryOperation {
   std::vector<OperationSignaturePtr> getSignatures() const override {
     const std::vector<TypeID> source_type_ids =
         { kBool, kInt, kLong, kFloat, kDouble, kChar, kVarChar };
-    const std::vector<TypeID> target_type_carrier = { kVarChar };
+    const std::vector<TypeID> target_type_carrier = { kMetaType };
 
     std::vector<OperationSignaturePtr> signatures;
     for (const TypeID source_type_id : source_type_ids) {
@@ -76,68 +76,20 @@ class CastOperation : public UnaryOperation {
 
   bool canApplyTo(const Type &type,
                   const std::vector<TypedValue> &static_arguments,
-                  std::string *message) const override {
-    DCHECK_EQ(1u, static_arguments.size());
-    if (getResultTypeInternal(type, static_arguments.front()) == nullptr) {
-      *message = "Invalid target type for CAST";
-      return false;
-    }
-    return true;
-  }
+                  std::string *message) const override;
 
   const Type* getResultType(
       const Type &type,
-      const std::vector<TypedValue> &static_arguments) const override {
-    DCHECK_EQ(1u, static_arguments.size());
-    const Type *target_type =
-        getResultTypeInternal(type, static_arguments.front());
-    DCHECK(target_type != nullptr);
-    return target_type;
-  }
+      const std::vector<TypedValue> &static_arguments) const override;
 
   UncheckedUnaryOperator* makeUncheckedUnaryOperator(
       const Type &type,
       const std::vector<TypedValue> &static_arguments) const override;
 
  private:
-  static const Type* getResultTypeInternal(const Type &type,
-                                           const TypedValue &type_arg) {
-    DCHECK(type_arg.getTypeID() == kVarChar);
-    const std::string type_str =
-        ToLower(std::string(static_cast<const char*>(type_arg.getOutOfLineData())));
-
-    const re2::StringPiece type_piece(type_str);
-    std::string type_name;
-    std::string length_str;
-    if (!re2::RE2::FullMatch(type_piece,
-                             kTypePattern,
-                             &type_name,
-                             static_cast<void *>(nullptr),
-                             &length_str)) {
-      return nullptr;
-    }
-
-    auto it = kNameToTypeIDMap.find(type_name);
-    if (it == kNameToTypeIDMap.end()) {
-      return nullptr;
-    }
-
-    if (length_str.empty()) {
-      return &TypeFactory::GetType(it->second);
-    } else {
-      TypedValue length_value;
-      if (IntType::InstanceNonNullable().parseTypedValueFromString(length_str, &length_value)) {
-        return &TypeFactory::GetType(
-            it->second,
-            static_cast<std::size_t>(length_value.getLiteral<int>()),
-            type.isNullable());
-      }
-    }
-    return nullptr;
-  }
-
-  static const re2::RE2 kTypePattern;
-  static const std::map<std::string, TypeID> kNameToTypeIDMap;
+  static const Type* ExtractTargetType(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments);
 
   DISALLOW_COPY_AND_ASSIGN(CastOperation);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/unary_operations/UnaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp
index 00562a6..78285fa 100644
--- a/types/operations/unary_operations/UnaryOperationWrapper.hpp
+++ b/types/operations/unary_operations/UnaryOperationWrapper.hpp
@@ -33,8 +33,8 @@
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVector.hpp"
 #include "types/operations/OperationSignature.hpp"
-#include "types/operations/OperationUtil.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "types/operations/utility/OperationSynthesizeUtil.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -89,8 +89,8 @@ class UncheckedUnaryOperatorWrapperCodegen : public UncheckedUnaryOperator {
   using ResultType = typename FunctorT::ResultType;
 
   using FuncSpec = typename FunctorSpecializer<FunctorT, SpecArgs...>::type;
-  using ArgumentGen = Codegen<FuncSpec, ArgumentType>;
-  using ResultGen = Codegen<FuncSpec, ResultType>;
+  using ArgumentGen = OperationCodegen<FuncSpec, ArgumentType>;
+  using ResultGen = OperationCodegen<FuncSpec, ResultType>;
 
   template <bool argument_nullable>
   struct Implementation;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/utility/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/utility/CMakeLists.txt b/types/operations/utility/CMakeLists.txt
new file mode 100644
index 0000000..89b1dc6
--- /dev/null
+++ b/types/operations/utility/CMakeLists.txt
@@ -0,0 +1,37 @@
+# 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.
+
+# Declare micro-libs:
+add_library(quickstep_types_operations_utility_CastUtil CastUtil.cpp CastUtil.hpp)
+add_library(quickstep_types_operations_utility_OperationSynthesizeUtil
+            ../../../empty_src.cpp
+            OperationSynthesizeUtil.hpp)
+
+# Link dependencies:
+target_link_libraries(quickstep_types_operations_utility_CastUtil
+                      glog)
+target_link_libraries(quickstep_types_operations_utility_OperationSynthesizeUtil
+                      quickstep_catalog_CatalogTypedefs
+                      quickstep_types_Type
+                      quickstep_types_TypedValue
+                      quickstep_types_containers_ColumnVector)
+
+# Module all-in-one library:
+add_library(quickstep_types_operations_utility ../../../empty_src.cpp)
+target_link_libraries(quickstep_types_operations_utility
+                      quickstep_types_operations_utility_CastUtil
+                      quickstep_types_operations_utility_OperationSynthesizeUtil)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/utility/CastUtil.cpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/CastUtil.cpp b/types/operations/utility/CastUtil.cpp
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/utility/CastUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/CastUtil.hpp b/types/operations/utility/CastUtil.hpp
new file mode 100644
index 0000000..e69de29


[11/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/ArithmeticBinaryOperators.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryOperators.hpp b/types/operations/binary_operations/ArithmeticBinaryOperators.hpp
deleted file mode 100644
index 7224a0c..0000000
--- a/types/operations/binary_operations/ArithmeticBinaryOperators.hpp
+++ /dev/null
@@ -1,848 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATORS_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATORS_HPP_
-
-#include <cmath>
-#include <cstddef>
-#include <cstdint>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/StorageBlockInfo.hpp"
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-// We use these functors instead of the standard-library ones, because the
-// standard-library functors in <functional> have to be instantiated for the
-// most specific argument type, which would unnecessisarily introduce
-// multiple copies of distinct template instantiations of operators.
-template <typename LeftArgument, typename RightArgument> struct AddFunctor {
-  inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left + right) {
-    return left + right;
-  }
-};
-
-// NOTE(zuyu): The C++ compiler in general converts all integers to floats
-//             when doing the following operations,
-//             but we could like to return double instead.
-template <>
-struct AddFunctor<std::int64_t, float> {
-  inline double operator() (const std::int64_t &left, const float &right) const {
-    return static_cast<double>(left) + static_cast<double>(right);
-  }
-};
-
-template <>
-struct AddFunctor<float, std::int64_t> {
-  inline double operator() (const float &left, const std::int64_t &right) const {
-    return static_cast<double>(left) + static_cast<double>(right);
-  }
-};
-
-template <typename LeftArgument, typename RightArgument> struct SubtractFunctor {
-  inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left - right) {
-    return left - right;
-  }
-};
-
-// NOTE(zuyu): The C++ compiler in general converts all integers to floats
-//             when doing the following operations,
-//             but we could like to return double instead.
-template <>
-struct SubtractFunctor<std::int64_t, float> {
-  inline double operator() (const std::int64_t &left, const float &right) const {
-    return static_cast<double>(left) - static_cast<double>(right);
-  }
-};
-
-template <>
-struct SubtractFunctor<float, std::int64_t> {
-  inline double operator() (const float &left, const std::int64_t &right) const {
-    return static_cast<double>(left) - static_cast<double>(right);
-  }
-};
-
-template <typename LeftArgument, typename RightArgument> struct MultiplyFunctor {
-  inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left * right) {
-    return left * right;
-  }
-};
-
-// NOTE(zuyu): The C++ compiler in general converts all integers to floats
-//             when doing the following operations,
-//             but we could like to return double instead.
-template <>
-struct MultiplyFunctor<std::int64_t, float> {
-  inline double operator() (const std::int64_t &left, const float &right) const {
-    return static_cast<double>(left) * static_cast<double>(right);
-  }
-};
-
-template <>
-struct MultiplyFunctor<float, std::int64_t> {
-  inline double operator() (const float &left, const std::int64_t &right) const {
-    return static_cast<double>(left) * static_cast<double>(right);
-  }
-};
-
-template <typename LeftArgument, typename RightArgument> struct DivideFunctor {
-  inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left / right) {
-    return left / right;
-  }
-};
-
-// NOTE(zuyu): The C++ compiler in general converts all integers to floats
-//             when doing the following operations,
-//             but we could like to return double instead.
-template <>
-struct DivideFunctor<std::int64_t, float> {
-  inline double operator() (const std::int64_t &left, const float &right) const {
-    return static_cast<double>(left) / static_cast<double>(right);
-  }
-};
-
-template <>
-struct DivideFunctor<float, std::int64_t> {
-  inline double operator() (const float &left, const std::int64_t &right) const {
-    return static_cast<double>(left) / static_cast<double>(right);
-  }
-};
-
-template <typename LeftArgument, typename RightArgument> struct IntegerModuloFunctor {
-  inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left % right) {
-    return left % right;
-  }
-};
-
-// NOTE(jianqiao): The C++11 standard specifies the following type signatures for fmod:
-// (1) (double, double) -> double
-// (2) (float, float) -> float
-// (3) (long double, long double) -> long double
-// (3) (Arithmetic, Arithmetic) -> double
-template <typename LeftArgument, typename RightArgument> struct FloatModuloFunctor {
-  inline auto operator() (const LeftArgument &left, const RightArgument &right) const
-      -> decltype(std::fmod(left, right)) {
-    return std::fmod(left, right);
-  }
-};
-
-template <template <typename LeftCppType, typename RightCppType> class OpFunctor,
-          typename ResultType,
-          typename LeftCppType, bool left_nullable,
-          typename RightCppType, bool right_nullable>
-class ArithmeticUncheckedBinaryOperator : public UncheckedBinaryOperator {
- public:
-  ArithmeticUncheckedBinaryOperator() = default;
-  ArithmeticUncheckedBinaryOperator(const ArithmeticUncheckedBinaryOperator &orig) = default;
-  ~ArithmeticUncheckedBinaryOperator() = default;
-
-  inline TypedValue applyToTypedValues(const TypedValue &left,
-                                       const TypedValue &right) const override {
-    return applyToTypedValuesInl(left, right);
-  }
-
-  // NOTE(chasseur): This inline version does NOT override a virtual in the
-  // base class. g++ (and probably other compilers) will not inline a method
-  // that overrides a virtual, so we use this instead when we cast to a
-  // specific subclass so that we can actually inline the call.
-  inline TypedValue applyToTypedValuesInl(const TypedValue &left,
-                                          const TypedValue &right) const {
-    if ((left_nullable && left.isNull()) || (right_nullable && right.isNull())) {
-      return TypedValue(ResultType::kStaticTypeID);
-    }
-    return TypedValue(op_functor_(left.getLiteral<LeftCppType>(),
-                                  right.getLiteral<RightCppType>()));
-  }
-
-  inline TypedValue applyToDataPtrs(const void *left, const void *right) const override {
-    return applyToDataPtrsInl(left, right);
-  }
-
-  // See above note about inlines.
-  inline TypedValue applyToDataPtrsInl(const void *left, const void *right) const {
-    if ((left_nullable && (left == nullptr)) || (right_nullable && (right == nullptr))) {
-      return TypedValue(ResultType::kStaticTypeID);
-    }
-
-    return TypedValue(op_functor_(*static_cast<const LeftCppType*>(left),
-                                  *static_cast<const RightCppType*>(right)));
-  }
-
-  ColumnVector* applyToColumnVectors(
-      const ColumnVector &left,
-      const ColumnVector &right) const override {
-    DCHECK(NativeColumnVector::UsableForType(
-        ResultType::Instance(left_nullable || right_nullable)));
-    // All arithmetic types (numbers, datetime, and intervals) are usable with
-    // NativeColumnVector, so 'left' and 'right' should always be native.
-    DCHECK(left.isNative());
-    DCHECK(right.isNative());
-
-    const NativeColumnVector &left_native = static_cast<const NativeColumnVector&>(left);
-    const NativeColumnVector &right_native = static_cast<const NativeColumnVector&>(right);
-
-    DCHECK_EQ(left_native.size(), right_native.size());
-    NativeColumnVector *result = new NativeColumnVector(
-        ResultType::Instance(left_nullable || right_nullable),
-        left_native.size());
-    for (std::size_t pos = 0;
-         pos < left_native.size();
-         ++pos) {
-      const LeftCppType *left_value
-          = static_cast<const LeftCppType*>(
-              left_native.getUntypedValue<left_nullable>(pos));
-      if (left_nullable && (left_value == nullptr)) {
-        result->appendNullValue();
-        continue;
-      }
-      const RightCppType *right_value
-          = static_cast<const RightCppType*>(
-              right_native.getUntypedValue<right_nullable>(pos));
-      if (right_nullable && (right_value == nullptr)) {
-        result->appendNullValue();
-        continue;
-      }
-      *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-          = op_functor_(*left_value, *right_value);
-    }
-    return result;
-  }
-
-  ColumnVector* applyToColumnVectorAndStaticValue(
-      const ColumnVector &left,
-      const TypedValue &right) const override {
-    return applyToColumnVectorAndStaticValueHelper<true>(left, right);
-  }
-
-  ColumnVector* applyToStaticValueAndColumnVector(
-      const TypedValue &left,
-      const ColumnVector &right) const override {
-    return applyToColumnVectorAndStaticValueHelper<false>(right, left);
-  }
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  ColumnVector* applyToSingleValueAccessor(
-      ValueAccessor *accessor,
-      const attribute_id left_id,
-      const attribute_id right_id) const override {
-    DCHECK(NativeColumnVector::UsableForType(
-        ResultType::Instance(left_nullable || right_nullable)));
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      NativeColumnVector *result = new NativeColumnVector(
-          ResultType::Instance(left_nullable || right_nullable),
-          accessor->getNumTuples());
-      accessor->beginIteration();
-      while (accessor->next()) {
-        const LeftCppType *left_value = static_cast<const LeftCppType*>(
-            accessor->template getUntypedValue<left_nullable>(left_id));
-        if (left_nullable && (left_value == nullptr)) {
-          result->appendNullValue();
-          continue;
-        }
-        const RightCppType *right_value = static_cast<const RightCppType*>(
-            accessor->template getUntypedValue<right_nullable>(right_id));
-        if (right_nullable && (right_value == nullptr)) {
-          result->appendNullValue();
-          continue;
-        }
-        *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-            = op_functor_(*left_value, *right_value);
-      }
-      return result;
-    });
-  }
-
-  ColumnVector* applyToValueAccessorAndStaticValue(
-      ValueAccessor *left_accessor,
-      const attribute_id left_id,
-      const TypedValue &right) const override {
-    return applyToValueAccessorAndStaticValueHelper<true>(left_accessor, left_id, right);
-  }
-
-  ColumnVector* applyToStaticValueAndValueAccessor(
-      const TypedValue &left,
-      ValueAccessor *right_accessor,
-      const attribute_id right_id) const override {
-    return applyToValueAccessorAndStaticValueHelper<false>(right_accessor, right_id, left);
-  }
-
-  ColumnVector* applyToColumnVectorAndValueAccessor(
-      const ColumnVector &left,
-      ValueAccessor *right_accessor,
-      const attribute_id right_id) const override {
-    return applyToColumnVectorAndValueAccessorHelper<true>(left, right_accessor, right_id);
-  }
-
-  ColumnVector* applyToValueAccessorAndColumnVector(
-      ValueAccessor *left_accessor,
-      const attribute_id left_id,
-      const ColumnVector &right) const override {
-    return applyToColumnVectorAndValueAccessorHelper<false>(right, left_accessor, left_id);
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  ColumnVector* applyToValueAccessorAndStaticValueForJoin(
-      ValueAccessor *left_accessor,
-      const bool left_accessor_is_left_relation,
-      const attribute_id left_id,
-      const TypedValue &right,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
-    return applyToValueAccessorAndStaticValueForJoinHelper<true>(left_accessor,
-                                                                 left_accessor_is_left_relation,
-                                                                 left_id,
-                                                                 right,
-                                                                 joined_tuple_ids);
-  }
-
-  ColumnVector* applyToStaticValueAndValueAccessorForJoin(
-      const TypedValue &left,
-      ValueAccessor *right_accessor,
-      const bool right_accessor_is_left_relation,
-      const attribute_id right_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
-    return applyToValueAccessorAndStaticValueForJoinHelper<false>(right_accessor,
-                                                                  right_accessor_is_left_relation,
-                                                                  right_id,
-                                                                  left,
-                                                                  joined_tuple_ids);
-  }
-
-  ColumnVector* applyToColumnVectorAndValueAccessorForJoin(
-      const ColumnVector &left,
-      ValueAccessor *right_accessor,
-      const bool right_accessor_is_left_relation,
-      const attribute_id right_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
-    return applyToColumnVectorAndValueAccessorForJoinHelper<true>(left,
-                                                                  right_accessor,
-                                                                  right_accessor_is_left_relation,
-                                                                  right_id,
-                                                                  joined_tuple_ids);
-  }
-
-  ColumnVector* applyToValueAccessorAndColumnVectorForJoin(
-      ValueAccessor *left_accessor,
-      const bool left_accessor_is_left_relation,
-      const attribute_id left_id,
-      const ColumnVector &right,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
-    return applyToColumnVectorAndValueAccessorForJoinHelper<false>(right,
-                                                                   left_accessor,
-                                                                   left_accessor_is_left_relation,
-                                                                   left_id,
-                                                                   joined_tuple_ids);
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN_WITH_BINARY_EXPRESSIONS
-  ColumnVector* applyToValueAccessorsForJoin(
-      ValueAccessor *left_accessor,
-      const bool left_accessor_is_left_relation,
-      const attribute_id left_id,
-      ValueAccessor *right_accessor,
-      const bool right_accessor_is_left_relation,
-      const attribute_id right_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
-    DCHECK(NativeColumnVector::UsableForType(
-        ResultType::Instance(left_nullable || right_nullable)));
-    NativeColumnVector *result = new NativeColumnVector(
-        ResultType::Instance(left_nullable || right_nullable),
-        joined_tuple_ids.size());
-    InvokeOnValueAccessorNotAdapter(
-        left_accessor,
-        [&](auto *left_accessor) -> void {  // NOLINT(build/c++11)
-      InvokeOnValueAccessorNotAdapter(
-          right_accessor,
-          [&](auto *right_accessor) -> void {  // NOLINT(build/c++11)
-        for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-          const LeftCppType *left_value = static_cast<const LeftCppType*>(
-              left_accessor->template getUntypedValueAtAbsolutePosition<left_nullable>(
-                  left_id,
-                  left_accessor_is_left_relation ? joined_pair.first
-                                                 : joined_pair.second));
-          if (left_nullable && (left_value == nullptr)) {
-            result->appendNullValue();
-            continue;
-          }
-          const RightCppType *right_value = static_cast<const RightCppType*>(
-              right_accessor->template getUntypedValueAtAbsolutePosition<right_nullable>(
-                  right_id,
-                  right_accessor_is_left_relation ? joined_pair.first
-                                                  : joined_pair.second));
-          if (right_nullable && (right_value == nullptr)) {
-            result->appendNullValue();
-            continue;
-          }
-          *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-              = op_functor_(*left_value, *right_value);
-        }
-      });
-    });
-    return result;
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN_WITH_BINARY_EXPRESSIONS
-
-  TypedValue accumulateColumnVector(
-      const TypedValue &current,
-      const ColumnVector &column_vector,
-      std::size_t *num_tuples_applied) const override {
-    return accumulateColumnVectorHelper(
-        current,
-        column_vector,
-        num_tuples_applied,
-        std::is_same<LeftCppType, typename ResultType::cpptype>());
-  }
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  TypedValue accumulateValueAccessor(
-      const TypedValue &current,
-      ValueAccessor *accessor,
-      const attribute_id value_accessor_id,
-      std::size_t *num_tuples_applied) const override {
-    return accumulateValueAccessorHelper(
-        current,
-        accessor,
-        value_accessor_id,
-        num_tuples_applied,
-        std::is_same<LeftCppType, typename ResultType::cpptype>());
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
- private:
-  template <bool column_vector_on_left>
-  ColumnVector* applyToColumnVectorAndStaticValueHelper(
-      const ColumnVector &column_vector,
-      const TypedValue &static_value) const {
-    typedef typename std::conditional<column_vector_on_left,
-                                      RightCppType,
-                                      LeftCppType>::type
-        StaticValueCppType;
-
-    constexpr bool cv_nullable = column_vector_on_left ? left_nullable : right_nullable;
-    constexpr bool static_value_nullable = column_vector_on_left ? right_nullable : left_nullable;
-
-    DCHECK(column_vector.isNative());
-    const NativeColumnVector &native_column_vector = static_cast<const NativeColumnVector&>(column_vector);
-
-    DCHECK(NativeColumnVector::UsableForType(
-        ResultType::Instance(left_nullable || right_nullable)));
-
-    NativeColumnVector *result = new NativeColumnVector(
-        ResultType::Instance(left_nullable || right_nullable),
-        native_column_vector.size());
-    if (static_value_nullable && static_value.isNull()) {
-      result->fillWithNulls();
-      return result;
-    }
-    const StaticValueCppType literal = static_value.getLiteral<StaticValueCppType>();
-    for (std::size_t pos = 0;
-         pos < native_column_vector.size();
-         ++pos) {
-      const void* cv_value = native_column_vector.getUntypedValue<cv_nullable>(pos);
-      if (cv_nullable && (cv_value == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-            = castAndApply<column_vector_on_left>(cv_value, &literal);
-      }
-    }
-    return result;
-  }
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  template <bool value_accessor_on_left>
-  ColumnVector* applyToValueAccessorAndStaticValueHelper(
-      ValueAccessor *value_accessor,
-      const attribute_id value_accessor_attr_id,
-      const TypedValue &static_value) const {
-    DCHECK(NativeColumnVector::UsableForType(
-        ResultType::Instance(left_nullable || right_nullable)));
-
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        value_accessor,
-        [&](auto *value_accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      typedef typename std::conditional<value_accessor_on_left,
-                                        RightCppType,
-                                        LeftCppType>::type
-          StaticValueCppType;
-
-      constexpr bool va_nullable = value_accessor_on_left ? left_nullable : right_nullable;
-      constexpr bool static_value_nullable = value_accessor_on_left ? right_nullable : left_nullable;
-
-      NativeColumnVector *result = new NativeColumnVector(
-          ResultType::Instance(left_nullable || right_nullable),
-          value_accessor->getNumTuples());
-      if (static_value_nullable && static_value.isNull()) {
-        result->fillWithNulls();
-        return result;
-      }
-      const StaticValueCppType literal = static_value.getLiteral<StaticValueCppType>();
-      value_accessor->beginIteration();
-      while (value_accessor->next()) {
-        const void* va_value
-            = value_accessor->template getUntypedValue<va_nullable>(value_accessor_attr_id);
-        if (va_nullable && (va_value == nullptr)) {
-          result->appendNullValue();
-        } else {
-          *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-              = this->castAndApply<value_accessor_on_left>(va_value, &literal);
-        }
-      }
-      return result;
-    });
-  }
-
-  template <bool column_vector_on_left>
-  ColumnVector* applyToColumnVectorAndValueAccessorHelper(
-      const ColumnVector &column_vector,
-      ValueAccessor *value_accessor,
-      const attribute_id value_accessor_attr_id) const {
-    DCHECK(column_vector.isNative());
-    const NativeColumnVector &native_column_vector = static_cast<const NativeColumnVector&>(column_vector);
-
-    DCHECK(NativeColumnVector::UsableForType(
-        ResultType::Instance(left_nullable || right_nullable)));
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        value_accessor,
-        [&](auto *value_accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      constexpr bool cv_nullable = column_vector_on_left ? left_nullable : right_nullable;
-      constexpr bool va_nullable = column_vector_on_left ? right_nullable : left_nullable;
-
-      DCHECK_EQ(native_column_vector.size(),
-                static_cast<std::size_t>(value_accessor->getNumTuples()));
-      NativeColumnVector *result = new NativeColumnVector(
-          ResultType::Instance(left_nullable || right_nullable),
-          native_column_vector.size());
-      std::size_t cv_pos = 0;
-      value_accessor->beginIteration();
-      while (value_accessor->next()) {
-        const void *cv_value = native_column_vector.getUntypedValue<cv_nullable>(cv_pos);
-        if (cv_nullable && (cv_value == nullptr)) {
-          result->appendNullValue();
-          ++cv_pos;
-          continue;
-        }
-        const void *va_value
-            = value_accessor->template getUntypedValue<va_nullable>(value_accessor_attr_id);
-        if (va_nullable && (va_value == nullptr)) {
-          result->appendNullValue();
-          ++cv_pos;
-          continue;
-        }
-        *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-            = this->castAndApply<column_vector_on_left>(cv_value, va_value);
-        ++cv_pos;
-      }
-      return result;
-    });
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  template <bool value_accessor_on_left>
-  ColumnVector* applyToValueAccessorAndStaticValueForJoinHelper(
-      ValueAccessor *value_accessor,
-      const bool accessor_is_left_relation,
-      const attribute_id value_accessor_attr_id,
-      const TypedValue &static_value,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
-    typedef typename std::conditional<value_accessor_on_left,
-                                      RightCppType,
-                                      LeftCppType>::type
-        StaticValueCppType;
-
-    constexpr bool static_value_nullable = value_accessor_on_left ? right_nullable : left_nullable;
-
-    DCHECK(NativeColumnVector::UsableForType(
-        ResultType::Instance(left_nullable || right_nullable)));
-    NativeColumnVector *result = new NativeColumnVector(
-        ResultType::Instance(left_nullable || right_nullable),
-        joined_tuple_ids.size());
-    if (static_value_nullable && static_value.isNull()) {
-      result->fillWithNulls();
-      return result;
-    }
-
-    const StaticValueCppType literal = static_value.getLiteral<StaticValueCppType>();
-
-    InvokeOnValueAccessorNotAdapter(
-        value_accessor,
-        [&](auto *value_accessor) -> void {  // NOLINT(build/c++11)
-      constexpr bool va_nullable = value_accessor_on_left ? left_nullable : right_nullable;
-
-      for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-        const void* va_value
-            = value_accessor->template getUntypedValueAtAbsolutePosition<va_nullable>(
-                value_accessor_attr_id,
-                accessor_is_left_relation ? joined_pair.first : joined_pair.second);
-        if (va_nullable && (va_value == nullptr)) {
-          result->appendNullValue();
-        } else {
-          *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-              = this->castAndApply<value_accessor_on_left>(va_value, &literal);
-        }
-      }
-    });
-    return result;
-  }
-
-  template <bool column_vector_on_left>
-  ColumnVector* applyToColumnVectorAndValueAccessorForJoinHelper(
-      const ColumnVector &column_vector,
-      ValueAccessor *value_accessor,
-      const bool accessor_is_left_relation,
-      const attribute_id value_accessor_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
-    DCHECK(column_vector.isNative());
-    const NativeColumnVector &native_column_vector = static_cast<const NativeColumnVector&>(column_vector);
-    DCHECK_EQ(native_column_vector.size(), joined_tuple_ids.size());
-
-    DCHECK(NativeColumnVector::UsableForType(
-        ResultType::Instance(left_nullable || right_nullable)));
-    NativeColumnVector *result = new NativeColumnVector(
-        ResultType::Instance(left_nullable || right_nullable),
-        native_column_vector.size());
-    InvokeOnValueAccessorNotAdapter(
-        value_accessor,
-        [&](auto *value_accessor) -> void {  // NOLINT(build/c++11)
-      constexpr bool cv_nullable = column_vector_on_left ? left_nullable : right_nullable;
-      constexpr bool va_nullable = column_vector_on_left ? right_nullable : left_nullable;
-
-      for (std::size_t pos = 0; pos < native_column_vector.size(); ++pos) {
-        const void *cv_value = native_column_vector.getUntypedValue<cv_nullable>(pos);
-        if (cv_nullable && (cv_value == nullptr)) {
-          result->appendNullValue();
-          continue;
-        }
-        const void *va_value
-            = value_accessor->template getUntypedValueAtAbsolutePosition<va_nullable>(
-                value_accessor_attr_id,
-                accessor_is_left_relation ? joined_tuple_ids[pos].first
-                                          : joined_tuple_ids[pos].second);
-        if (va_nullable && (va_value == nullptr)) {
-          result->appendNullValue();
-          continue;
-        }
-        *static_cast<typename ResultType::cpptype*>(result->getPtrForDirectWrite())
-            = this->castAndApply<column_vector_on_left>(cv_value, va_value);
-      }
-    });
-    return result;
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-  // Actual implementation of accumulator.
-  TypedValue accumulateColumnVectorHelper(
-      const TypedValue &current,
-      const ColumnVector &column_vector,
-      std::size_t *num_tuples_applied,
-      std::true_type) const {
-    DCHECK(num_tuples_applied);
-
-    *num_tuples_applied = 0;
-    if (left_nullable && current.isNull()) {
-      return ResultType::Instance(left_nullable).makeNullValue();
-    }
-
-    LeftCppType accumulated = current.getLiteral<LeftCppType>();
-
-    DCHECK(column_vector.isNative());
-    const NativeColumnVector &native_column_vector = static_cast<const NativeColumnVector&>(column_vector);
-    for (std::size_t pos = 0;
-         pos < native_column_vector.size();
-         ++pos) {
-      const RightCppType *value = static_cast<const RightCppType *>(
-        native_column_vector.getUntypedValue<right_nullable>(pos));
-      if ((right_nullable && value) || !right_nullable) {
-        accumulated = op_functor_(accumulated, *value);
-        ++(*num_tuples_applied);
-      }
-    }
-
-    // Note ResultType::cpptype and LeftCppType are same here.
-    return TypedValue(accumulated);
-  }
-
-  // Unimplemented version of accumlator for use when the result type and left
-  // operand type are not same.
-  TypedValue accumulateColumnVectorHelper(
-      const TypedValue &current,
-      const ColumnVector &column_vector,
-      std::size_t *num_tuples_applied,
-      std::false_type) const {
-    FATAL_ERROR("Unimplemented method UncheckedBinaryOperator::accumulateColumnVectorHelper() "
-        "because ResultType::cpptype and LeftCppType are not same.");
-  }
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  // Actual implementation of accumlator.
-  TypedValue accumulateValueAccessorHelper(
-      const TypedValue &current,
-      ValueAccessor *accessor,
-      const attribute_id value_accessor_id,
-      std::size_t *num_tuples_applied,
-      std::true_type) const {
-    DCHECK(num_tuples_applied);
-
-    *num_tuples_applied = 0;
-    if (left_nullable && current.isNull()) {
-      return ResultType::Instance(left_nullable).makeNullValue();
-    }
-
-    LeftCppType accumulated = current.getLiteral<LeftCppType>();
-    InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> void {  // NOLINT(build/c++11)
-      accessor->beginIteration();
-      while (accessor->next()) {
-        const RightCppType *value = static_cast<const RightCppType *>(
-          accessor->template getUntypedValue<right_nullable>(value_accessor_id));
-        if ((right_nullable && value) || !right_nullable) {
-          accumulated = op_functor_(accumulated, *value);
-          ++(*num_tuples_applied);
-        }
-      }
-    });
-
-    // Note ResultType::cpptype and LeftCppType are same here.
-    return TypedValue(accumulated);
-  }
-
-  // Unimplemented version of accumlator for use when the result type and left
-  // operand type are not same.
-  TypedValue accumulateValueAccessorHelper(
-      const TypedValue &current,
-      ValueAccessor *accessor,
-      const attribute_id value_accessor_id,
-      std::size_t *num_tuples_applied,
-      std::false_type) const {
-    FATAL_ERROR("Unimplemented method UncheckedBinaryOperator::accumulateValueAccessorHelper() "
-        "because ResultType::cpptype and LeftCppType are not same.");
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-  template <bool arguments_in_order>
-  inline typename ResultType::cpptype castAndApply(const void *left, const void *right) const {
-    return op_functor_(*static_cast<const LeftCppType*>(arguments_in_order ? left : right),
-                       *static_cast<const RightCppType*>(arguments_in_order ? right : left));
-  }
-
-  OpFunctor<LeftCppType, RightCppType> op_functor_;
-};
-
-/**
- * @brief The UncheckedBinaryOperator for addition.
- **/
-template <typename ResultType,
-          typename LeftCppType, bool left_nullable,
-          typename RightCppType, bool right_nullable>
-using AddArithmeticUncheckedBinaryOperator
-    = ArithmeticUncheckedBinaryOperator<AddFunctor,
-                                        ResultType,
-                                        LeftCppType, left_nullable,
-                                        RightCppType, right_nullable>;
-
-/**
- * @brief The UncheckedBinaryOperator for subtraction.
- **/
-template <typename ResultType,
-          typename LeftCppType, bool left_nullable,
-          typename RightCppType, bool right_nullable>
-using SubtractArithmeticUncheckedBinaryOperator
-    = ArithmeticUncheckedBinaryOperator<SubtractFunctor,
-                                        ResultType,
-                                        LeftCppType, left_nullable,
-                                        RightCppType, right_nullable>;
-
-/**
- * @brief The UncheckedBinaryOperator for multiplication.
- **/
-template <typename ResultType,
-          typename LeftCppType, bool left_nullable,
-          typename RightCppType, bool right_nullable>
-using MultiplyArithmeticUncheckedBinaryOperator
-    = ArithmeticUncheckedBinaryOperator<MultiplyFunctor,
-                                        ResultType,
-                                        LeftCppType, left_nullable,
-                                        RightCppType, right_nullable>;
-
-/**
- * @brief The UncheckedBinaryOperator for division.
- **/
-template <typename ResultType,
-          typename LeftCppType, bool left_nullable,
-          typename RightCppType, bool right_nullable>
-using DivideArithmeticUncheckedBinaryOperator
-    = ArithmeticUncheckedBinaryOperator<DivideFunctor,
-                                        ResultType,
-                                        LeftCppType, left_nullable,
-                                        RightCppType, right_nullable>;
-
-/**
- * @brief The UncheckedBinaryOperator for integer modulo.
- **/
-template <typename ResultType,
-          typename LeftCppType, bool left_nullable,
-          typename RightCppType, bool right_nullable>
-using IntegerModuloArithmeticUncheckedBinaryOperator
-    = ArithmeticUncheckedBinaryOperator<IntegerModuloFunctor,
-                                        ResultType,
-                                        LeftCppType, left_nullable,
-                                        RightCppType, right_nullable>;
-
-/**
- * @brief The UncheckedBinaryOperator for real number modulo.
- **/
-template <typename ResultType,
-          typename LeftCppType, bool left_nullable,
-          typename RightCppType, bool right_nullable>
-using FloatModuloArithmeticUncheckedBinaryOperator
-    = ArithmeticUncheckedBinaryOperator<FloatModuloFunctor,
-                                        ResultType,
-                                        LeftCppType, left_nullable,
-                                        RightCppType, right_nullable>;
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATORS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/AsciiStringBinaryOperations.hpp b/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
new file mode 100644
index 0000000..7181bc6
--- /dev/null
+++ b/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
@@ -0,0 +1,130 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_OPERATIONS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_OPERATIONS_HPP_
+
+#include <cctype>
+#include <cstring>
+#include <string>
+
+#include "types/CharType.hpp"
+#include "types/IntType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/VarCharType.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/port/strnlen.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename LeftT, typename RightT, typename ResultT>
+struct AsciiStringConcatFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
+  explicit AsciiStringConcatFunctor(const LeftT &left, const RightT &right)
+      : left_max_(left.getStringLength()),
+        right_max_(right.getStringLength()),
+        result_max_(left_max_ + right_max_) {}
+  inline void concat(const void *left, const std::size_t l_len,
+                     const void *right, const std::size_t r_len,
+                     void *result) const {
+    char *result_str = static_cast<char*>(result);
+    std::memcpy(result_str, left, l_len);
+    std::memcpy(result_str + l_len, right, r_len);
+
+    const std::size_t result_len = l_len + r_len;
+    if (ResultT::kStaticTypeID == kVarChar || result_len < result_max_) {
+      result_str[result_len] = 0;
+    }
+  }
+  inline void apply(const void *left, const void *right, void *result) const {
+    concat(left, strnlen(static_cast<const char*>(left), left_max_),
+           right, strnlen(static_cast<const char*>(right), right_max_),
+           result);
+  }
+  inline TypedValue apply(const void *left, const TypedValue &right) const {
+    const std::size_t l_len =
+        strnlen(static_cast<const char*>(left), left_max_);
+    const std::size_t r_len =
+        std::strlen(static_cast<const char*>(right.getOutOfLineData()));
+    const std::size_t buf_len = l_len + r_len + 1;
+    char *buf = static_cast<char*>(std::malloc(buf_len));
+    concat(left, l_len, right.getOutOfLineData(), r_len, buf);
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+  inline TypedValue apply(const TypedValue &left, const void *right) const {
+    const std::size_t l_len =
+        std::strlen(static_cast<const char*>(left.getOutOfLineData()));
+    const std::size_t r_len =
+        strnlen(static_cast<const char*>(right), right_max_);;
+    const std::size_t buf_len = l_len + r_len + 1;
+    char *buf = static_cast<char*>(std::malloc(buf_len));
+    concat(left.getOutOfLineData(), l_len, right, r_len, buf);
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+  inline TypedValue apply(const TypedValue &left, const TypedValue &right) const {
+    const std::size_t l_len =
+        std::strlen(static_cast<const char*>(left.getOutOfLineData()));
+    const std::size_t r_len =
+        std::strlen(static_cast<const char*>(right.getOutOfLineData()));
+    const std::size_t buf_len = l_len + r_len + 1;
+    char *buf = static_cast<char*>(std::malloc(buf_len));
+    concat(left.getOutOfLineData(), l_len, right.getOutOfLineData(), r_len, buf);
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+  inline static std::string GetName() {
+    return "+";
+  }
+  inline static const Type* GetResultType(const Type &left, const Type &right) {
+    DCHECK(left.getTypeID() == LeftT::kStaticTypeID);
+    DCHECK(right.getTypeID() == RightT::kStaticTypeID);
+    const std::size_t result_len =
+        static_cast<const LeftT&>(left).getStringLength() +
+            static_cast<const RightT&>(right).getStringLength();
+    const bool is_nullable = left.isNullable() || right.isNullable();
+    if (LeftT::kStaticTypeID == kChar && RightT::kStaticTypeID == kChar) {
+      return &TypeFactory::GetType(kChar, result_len, is_nullable);
+    } else {
+      return &TypeFactory::GetType(kVarChar, result_len, is_nullable);
+    }
+  }
+  const std::size_t left_max_;
+  const std::size_t right_max_;
+  const std::size_t result_max_;
+};
+
+
+using AsciiStringBinaryFunctorPack = FunctorPack<
+// concat
+    AsciiStringConcatFunctor<CharType, CharType, CharType>,
+    AsciiStringConcatFunctor<CharType, VarCharType, VarCharType>,
+    AsciiStringConcatFunctor<VarCharType, CharType, VarCharType>,
+    AsciiStringConcatFunctor<VarCharType, VarCharType, VarCharType>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_ASCII_STRING_BINARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/BinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperation.cpp b/types/operations/binary_operations/BinaryOperation.cpp
index 436086f..4f97710 100644
--- a/types/operations/binary_operations/BinaryOperation.cpp
+++ b/types/operations/binary_operations/BinaryOperation.cpp
@@ -19,35 +19,6 @@
 
 #include "types/operations/binary_operations/BinaryOperation.hpp"
 
-#include "types/operations/Operation.pb.h"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
 namespace quickstep {
 
-serialization::BinaryOperation BinaryOperation::getProto() const {
-  serialization::BinaryOperation proto;
-  switch (operation_id_) {
-    case BinaryOperationID::kAdd:
-      proto.set_operation_id(serialization::BinaryOperation::ADD);
-      break;
-    case BinaryOperationID::kSubtract:
-      proto.set_operation_id(serialization::BinaryOperation::SUBTRACT);
-      break;
-    case BinaryOperationID::kMultiply:
-      proto.set_operation_id(serialization::BinaryOperation::MULTIPLY);
-      break;
-    case BinaryOperationID::kDivide:
-      proto.set_operation_id(serialization::BinaryOperation::DIVIDE);
-      break;
-    case BinaryOperationID::kModulo:
-      proto.set_operation_id(serialization::BinaryOperation::MODULO);
-      break;
-    default:
-      FATAL_ERROR("Unrecognized BinaryOperationID");
-  }
-
-  return proto;
-}
-
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/BinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperation.hpp b/types/operations/binary_operations/BinaryOperation.hpp
index bc8a083..e818634 100644
--- a/types/operations/binary_operations/BinaryOperation.hpp
+++ b/types/operations/binary_operations/BinaryOperation.hpp
@@ -30,8 +30,7 @@
 #include "storage/StorageBlockInfo.hpp"
 #include "types/TypedValue.hpp"
 #include "types/operations/Operation.hpp"
-#include "types/operations/Operation.pb.h"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
+#include "types/operations/OperationSignature.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -44,6 +43,9 @@ class ValueAccessor;
  *  @{
  */
 
+class BinaryOperation;
+typedef std::shared_ptr<const BinaryOperation> BinaryOperationPtr;
+
 /**
  * @brief A binary operator which can be quickly applied to data items WITHOUT
  *        checking their types.
@@ -67,16 +69,6 @@ class UncheckedBinaryOperator {
                                         const TypedValue &right) const = 0;
 
   /**
-   * @brief Apply to two data items via pointers without type-checking.
-   *
-   * @param left The left argument data item to apply to.
-   * @param right The right argument data item to apply to.
-   * @return The literal result of the operation.
-   **/
-  virtual TypedValue applyToDataPtrs(const void *left,
-                                     const void *right) const = 0;
-
-  /**
    * @brief Apply to two equally-sized vectors of values without type-checking.
    *
    * @param left The left argument ColumnVector to apply to.
@@ -182,47 +174,6 @@ class UncheckedBinaryOperator {
       const ColumnVector &right) const = 0;
 #endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
 
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  virtual ColumnVector* applyToValueAccessorAndStaticValueForJoin(
-      ValueAccessor *left_accessor,
-      const bool left_accessor_is_left_relation,
-      const attribute_id left_id,
-      const TypedValue &right,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const = 0;
-
-  virtual ColumnVector* applyToStaticValueAndValueAccessorForJoin(
-      const TypedValue &left,
-      ValueAccessor *right_accessor,
-      const bool right_accessor_is_left_relation,
-      const attribute_id right_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const = 0;
-
-  virtual ColumnVector* applyToColumnVectorAndValueAccessorForJoin(
-      const ColumnVector &left,
-      ValueAccessor *right_accessor,
-      const bool right_accessor_is_left_relation,
-      const attribute_id right_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const = 0;
-
-  virtual ColumnVector* applyToValueAccessorAndColumnVectorForJoin(
-      ValueAccessor *left_accessor,
-      const bool left_accessor_is_left_relation,
-      const attribute_id left_id,
-      const ColumnVector &right,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const = 0;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN_WITH_BINARY_EXPRESSIONS
-  virtual ColumnVector* applyToValueAccessorsForJoin(
-      ValueAccessor *left_accessor,
-      const bool left_accessor_is_left_relation,
-      const attribute_id left_id,
-      ValueAccessor *right_accessor,
-      const bool right_accessor_is_left_relation,
-      const attribute_id right_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const = 0;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN_WITH_BINARY_EXPRESSIONS
-
   /**
    * @brief Apply binary operator on column vector accumulating on the current
    * value. This is useful for summing/multiplying the values of the column
@@ -297,241 +248,44 @@ class UncheckedBinaryOperator {
  **/
 class BinaryOperation : public Operation {
  public:
-  /**
-   * @brief Generate a serialized Protocol Buffer representation of
-   *        this BinaryOperation.
-   *
-   * @return The serialized Protocol Buffer representation of
-   *         this BinaryOperation.
-   **/
-  serialization::BinaryOperation getProto() const;
-
-  /**
-   * @brief Determine the ID of this BinaryOperation
-   *
-   * @return The ID of this BinaryOperation
-   **/
-  inline BinaryOperationID getBinaryOperationID() const {
-    return operation_id_;
-  }
-
-  /**
-   * @brief Get a human-readable name for this BinaryOperation.
-   *
-   * @return A human-readable name for this BinaryOperation.
-   **/
   virtual std::string getName() const {
-    return kBinaryOperationNames[static_cast<std::size_t>(operation_id_)];
+    return "NoName";
   }
 
-  /**
-   * @brief Get a human-readable short name (e.g. "+", "-", "*", "/") for this
-   *        BinaryOperation.
-   *
-   * @return A human-readable short name for this BinaryOperation.
-   **/
   virtual std::string getShortName() const {
-    return kBinaryOperationShortNames[static_cast<std::size_t>(operation_id_)];
+    return getName();
   }
 
-  /**
-   * @brief Whether this binary operation is commutative.
-   *
-   * @note The commutative property provides more optimization opportunities,
-   *       e.g. common subexpression elimination. Meanwhile it is always safe
-   *       to assume that a binary operation is not commutative.
-   *
-   * @return True if this binary operation is commutative; false otherwise.
-   */
+  // TODO
   virtual bool isCommutative() const {
     return false;
   }
 
-  /**
-   * @brief Determine whether this BinaryOperation can apply to the specified
-   *        Types.
-   * @note When the Types that an operator can apply to are changed,
-   *       its definition in the function catalog of the query optimizer
-   *       needs to be modified accordingly.
-   *
-   * @param left The left argument Type to check.
-   * @param right The right argument Type to check.
-   * @return Whether this BinaryOperation can apply to left and right.
-   **/
-  virtual bool canApplyToTypes(const Type &left, const Type &right) const = 0;
-
-  /**
-   * @brief Determine the Type of the result from applying this BinaryOperation
-   *        to arguments of the specified Types.
-   *
-   * @param left The left argument Type to check.
-   * @param right The right argument Type to check.
-   * @return The Type of the result from applying this BinaryOperation to left
-   *         and right (NULL if not applicable).
-   **/
-  virtual const Type* resultTypeForArgumentTypes(const Type &left, const Type &right) const = 0;
-
-  /**
-   * @brief Similar to resultTypeForArgumentTypes(), but allows either or both
-   *        argument types to be NULL to indicate an unknown (but presumed
-   *        nullable) type. If the return type can be unambiguously determined
-   *        based on the incomplete information about the argument types, that
-   *        will be returned. Otherwise, NULL will be returned.
-   * @note This method returns NULL in cases where the return Type is
-   *       ambiguous, and also in cases where this BinaryOperation can not
-   *       possibly be applied to argument(s) of one of the known types left or
-   *       right. See also partialTypeSignatureIsPlausible(), which will return
-   *       true in the former case (ambiguous result type) but false in the
-   *       latter (can not apply to specfied argument types).
-   *
-   * @param left The left argument Type, or NULL if unknown (but presumed
-   *        nullable).
-   * @param right The right argument Type, or NULL if unknown (but presumed
-   *        nullable).
-   * @return The result Type for the given partial argument type information,
-   *         if such a result Type can be unambiguously determined. Otherwise
-   *         NULL.
-   **/
-  virtual const Type* resultTypeForPartialArgumentTypes(const Type *left,
-                                                        const Type *right) const = 0;
-
-  /**
-   * @brief Determine if an incomplete type signature is plausible for this
-   *        BinaryOperation. Specifically, checks if for each unknown Type in
-   *        the partial Type signature, there is some concrete Type that could
-   *        be substituted such that the overall signature becomes valid.
-   *
-   * @param result_type The result Type for this BinaryOperation, or NULL if
-   *        unknown.
-   * @param left_argument_type The Type for the left argument to this
-   *        BinaryOperation, or NULL if unknown (but presumed nullable).
-   * @param right_argument_type The Type for the right argument to this
-   *        BinaryOperation, or NULL if unknown (but presumed nullable).
-   * @return true if the specified partial Type signature is plausible.
-   **/
-  virtual bool partialTypeSignatureIsPlausible(const Type *result_type,
-                                               const Type *left_argument_type,
-                                               const Type *right_argument_type) const = 0;
-
-  // TODO(chasseur): This hinting interface is currently rather rudimentary,
-  // and we would like it to be more flexible to capture the full semantics of
-  // binary operations. Three issues immediately come to mind:
-  //
-  //     1. We should be able to use a category of Types or multiple Types as
-  //        a hint. For example, if we hint that the result of
-  //        DivideBinaryOperation should be DatetimeIntervalType, we know that
-  //        the hint for the left argument should be DatetimeIntervalType, but
-  //        the hint for the right argument can be any numeric type.
-  //     2. We should know something about whether or not a BinaryOperation is
-  //        commutative with respect to its argument types. For example,
-  //        AddBinaryOperation is commutative. If we hint that its result
-  //        should be DatetimeType, then one of its arguments should be
-  //        DatetimeType and the other should be one of the interval types, but
-  //        which is left and which is right does not matter (although it does
-  //        matter that there is one of each).
-  //     3. We may want to use "sideways" hinting, where we tentatively resolve
-  //        the types for arguments and note where we encounter "strong"
-  //        information about what a type should be (i.e. from the catalog or
-  //        an explicitly-typed literal in the parser), then using that to help
-  //        hint "weak" guesses about typing for the other argument.
-  //
-  // These issues can be difficult to solve in general, and it may not be worth
-  // doing in the current optimizer if another more sophisticated optimizer
-  // frontend is to be added in the future.
+  virtual bool canApplyTo(const Type &left,
+                          const Type &right,
+                          const std::vector<TypedValue> &static_arguments,
+                          std::string *message) const = 0;
 
-  /**
-   * @brief Get a pair of "hint" Types for the arguments to this
-   *        BinaryOperation based on a hint for this BinaryOperation's result
-   *        type. If possible, returns pointers to Types that, when given to
-   *        this BinaryOperation as arguments, yield values of the desired type
-   *        (i.e. calling resultTypeForArgumentTypes() on the returned types
-   *        should return the original type_hint).
-   *
-   * This method is designed to help the query optimizer's Resolver determine
-   * the type of literal values that appear in SQL queries. The Resolver
-   * propagates known Type information (e.g. from the Catalog) top-down through
-   * parsed expression trees, eventually using a Type hint at a leaf
-   * ParseLiteralValue node in the tree to concretize that literal value as the
-   * appropriate Type. This is especially important for NULL literals that
-   * appear in SQL queries, because a NULL by itself does not convey any type
-   * information and could be an instance of any nullable type. Hints generated
-   * by this method are to be treated as hints only, not as hard or
-   * authoritative requirements. After resolving literals, the Resolver
-   * propagates known concrete Types bottom-up through the tree and explicitly
-   * checks canApplyToTypes() for correctness.
-   *
-   * @note In some cases, either or both arguments could take on more than one
-   *       possible Type and this BinaryOperation would still yield the
-   *       specified result_type_hint (e.g. for arithmetic operations, if
-   *       result_type_hint is DoubleType, then the arguments could both be
-   *       DoubleType, or DoubleType and a different numeric Type, or even
-   *       LongType and FloatType). In such cases, the most precise suitable
-   *       Type is used as the hint.
-   * @note In some cases, the choice of argument Type hints for a given
-   *       result_type_hint is ambiguous and there is no single precise Type
-   *       that can represent values of any of the possible argument types
-   *       (e.g. an addition returning Datetime could be
-   *       Datetime + DatetimeInterval, DatetimeInterval + Datetime,
-   *       Datetime + YearMonthInterval, or YearMonthInterval + Datetime, and
-   *       none of these Types is coercible to the others or to a common more
-   *       precise type). In such cases, NULL is used to represent an ambiguous
-   *       or unknown hint.
-   *
-   * @param result_type_hint A hint about what Type the result of this
-   *        BinaryOperation should have. May be NULL to indicate no preference.
-   * @return A pair of type hints for the left and right arguments to this
-   *         BinaryOperation based on type_hint, or NULL if no suitable Type
-   *         exists or if the hint is ambiguous.
-   **/
-  virtual std::pair<const Type*, const Type*> pushDownTypeHint(
-      const Type *result_type_hint) const = 0;
+  bool canApplyTo(const Type &left,
+                  const Type &right,
+                  const std::vector<TypedValue> &static_arguments = {}) const {
+    std::string message;
+    return canApplyTo(left, right, static_arguments, &message);
+  }
 
-  /**
-   * @brief Apply this BinaryOperation to two TypedValues.
-   * @warning It is an error to call this method if this BinaryOperation can
-   *          not be applied to arguments of the specified types. If in doubt,
-   *          check canApplyToTypes() first.
-   *
-   * @param left The left argument TypedValue to apply to.
-   * @param left_type The Type that left belongs to.
-   * @param right The right argument TypedValue to apply to.
-   * @param right_type The Type that right belongs to.
-   * @return The literal result of the operation.
-   **/
-  virtual TypedValue applyToChecked(const TypedValue &left,
-                                    const Type &left_type,
-                                    const TypedValue &right,
-                                    const Type &right_type) const = 0;
+  virtual const Type* getResultType(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments = {}) const = 0;
 
-  /**
-   * @brief Create an UncheckedBinaryOperator which can apply to items of the
-   *        specified types.
-   * @warning The resulting UncheckedBinaryOperator performs no type-checking
-   *          whatsoever. Nonetheless, it is useful in situations where many
-   *          data items of the same, known types are to be operated on (for
-   *          example, over many tuples in the same table).
-   *
-   * @param left The left argument Type to compare.
-   * @param right The right argument Type to compare.
-   * @return An UncheckedBinaryOperator which applies this BinaryOperation to
-   *         the specified Types.
-   * @exception OperationInapplicableToType This BinaryOperation is not
-   *            applicable to either left or right.
-   **/
-  virtual UncheckedBinaryOperator* makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                                       const Type &right) const = 0;
+  virtual UncheckedBinaryOperator* makeUncheckedBinaryOperator(
+      const Type &left,
+      const Type &right,
+      const std::vector<TypedValue> &static_arguments = {}) const = 0;
 
  protected:
-  explicit BinaryOperation(const BinaryOperationID operation_id)
-      : Operation(Operation::kBinaryOperation,
-                  kBinaryOperationNames[
-                      static_cast<typename std::underlying_type<BinaryOperationID>::type>(operation_id)],
-                  kBinaryOperationShortNames[
-                      static_cast<typename std::underlying_type<BinaryOperationID>::type>(operation_id)]),
-        operation_id_(operation_id) {
-  }
-
-  const BinaryOperationID operation_id_;
+  BinaryOperation()
+      : Operation(Operation::kBinaryOperation) {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(BinaryOperation);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/BinaryOperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationFactory.cpp b/types/operations/binary_operations/BinaryOperationFactory.cpp
deleted file mode 100644
index 51b5a7e..0000000
--- a/types/operations/binary_operations/BinaryOperationFactory.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-
-#include <string>
-
-#include "types/operations/Operation.pb.h"
-#include "types/operations/binary_operations/AddBinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "types/operations/binary_operations/DivideBinaryOperation.hpp"
-#include "types/operations/binary_operations/ModuloBinaryOperation.hpp"
-#include "types/operations/binary_operations/MultiplyBinaryOperation.hpp"
-#include "types/operations/binary_operations/SubtractBinaryOperation.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-const BinaryOperation& BinaryOperationFactory::GetBinaryOperation(const BinaryOperationID id) {
-  switch (id) {
-    case BinaryOperationID::kAdd:
-      return AddBinaryOperation::Instance();
-    case BinaryOperationID::kSubtract:
-      return SubtractBinaryOperation::Instance();
-    case BinaryOperationID::kMultiply:
-      return MultiplyBinaryOperation::Instance();
-    case BinaryOperationID::kDivide:
-      return DivideBinaryOperation::Instance();
-    case BinaryOperationID::kModulo:
-      return ModuloBinaryOperation::Instance();
-    default:
-      break;  // Prevent compiler from complaining about unhandled case.
-  }
-  // Should never be reached
-  FATAL_ERROR("Unrecognized BinaryOperationID");
-}
-
-bool BinaryOperationFactory::ProtoIsValid(const serialization::BinaryOperation &proto) {
-  // Check that BinaryOperation is fully initialized.
-  if (!proto.IsInitialized()) {
-    return false;
-  }
-
-  // Check that the operation_id is a valid BinaryOperation.
-  if (!proto.BinaryOperationID_IsValid(proto.operation_id())) {
-    return false;
-  }
-
-  return true;
-}
-
-const BinaryOperation& BinaryOperationFactory::ReconstructFromProto(
-    const serialization::BinaryOperation &proto) {
-  DCHECK(ProtoIsValid(proto))
-      << "Attempted to create BinaryOperation from an invalid proto description:\n"
-      << proto.DebugString();
-
-  switch (proto.operation_id()) {
-    case serialization::BinaryOperation::ADD:
-      return GetBinaryOperation(BinaryOperationID::kAdd);
-    case serialization::BinaryOperation::SUBTRACT:
-      return GetBinaryOperation(BinaryOperationID::kSubtract);
-    case serialization::BinaryOperation::MULTIPLY:
-      return GetBinaryOperation(BinaryOperationID::kMultiply);
-    case serialization::BinaryOperation::DIVIDE:
-      return GetBinaryOperation(BinaryOperationID::kDivide);
-    case serialization::BinaryOperation::MODULO:
-      return GetBinaryOperation(BinaryOperationID::kModulo);
-    default:
-      FATAL_ERROR("Unrecognized BinaryOperationID in "
-                  "BinaryOperationFactory::ReconstructFromProto");
-  }
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/BinaryOperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationFactory.hpp b/types/operations/binary_operations/BinaryOperationFactory.hpp
deleted file mode 100644
index 578dfb8..0000000
--- a/types/operations/binary_operations/BinaryOperationFactory.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_FACTORY_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_FACTORY_HPP_
-
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-namespace quickstep {
-
-class BinaryOperation;
-namespace serialization { class BinaryOperation; }
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief All-static factory object that provides access to BinaryOperations.
- **/
-class BinaryOperationFactory {
- public:
-  /**
-   * @brief Convenience factory method to get a pointer to a BinaryOperation
-   *        from that BinaryOperation's ID.
-   *
-   * @param id The ID of the desired BinaryOperation.
-   * @return The BinaryOperation corresponding to id.
-   **/
-  static const BinaryOperation& GetBinaryOperation(const BinaryOperationID id);
-
-  /**
-   * @brief Get a reference to a BinaryOperation from that BinaryOperation's
-   *        serialized Protocol Buffer representation.
-   *
-   * @param proto A serialized Protocol Buffer representation of a
-   *        BinaryOperation, originally generated by getProto().
-   * @return The BinaryOperation described by proto.
-   **/
-  static const BinaryOperation& ReconstructFromProto(const serialization::BinaryOperation &proto);
-
-  /**
-   * @brief Check whether a serialization::BinaryOperation is fully-formed and
-   *        all parts are valid.
-   *
-   * @param proto A serialized Protocol Buffer representation of a
-   *        BinaryOperation, originally generated by getProto().
-   * @return Whether proto is fully-formed and valid.
-   **/
-  static bool ProtoIsValid(const serialization::BinaryOperation &proto);
-
- private:
-  BinaryOperationFactory();
-
-  DISALLOW_COPY_AND_ASSIGN(BinaryOperationFactory);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_FACTORY_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/BinaryOperationID.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationID.cpp b/types/operations/binary_operations/BinaryOperationID.cpp
deleted file mode 100644
index 7ba2e69..0000000
--- a/types/operations/binary_operations/BinaryOperationID.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-
-namespace quickstep {
-
-const char *kBinaryOperationNames[] = {
-  "Add",
-  "Subtract",
-  "Multiply",
-  "Divide",
-  "Modulo"
-};
-
-const char *kBinaryOperationShortNames[] = {
-  "+",
-  "-",
-  "*",
-  "/",
-  "%"
-};
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/BinaryOperationID.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationID.hpp b/types/operations/binary_operations/BinaryOperationID.hpp
deleted file mode 100644
index 2cf20d1..0000000
--- a/types/operations/binary_operations/BinaryOperationID.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_ID_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_ID_HPP_
-
-#include <type_traits>
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief Concrete BinaryOperations.
- **/
-enum class BinaryOperationID {
-  kAdd = 0,
-  kSubtract,
-  kMultiply,
-  kDivide,
-  kModulo,
-  kNumBinaryOperationIDs  // Not a real BinaryOperationID, exists for counting purposes.
-};
-
-/**
- * @brief Names of comparisons in the same order as BinaryOperationID.
- **/
-extern const char *kBinaryOperationNames[
-    static_cast<typename std::underlying_type<BinaryOperationID>::type>(
-        BinaryOperationID::kNumBinaryOperationIDs)];
-
-/**
- * @brief Short names (i.e. mathematical symbols) of comparisons in the same
- *        order as BinaryOperationID.
- **/
-extern const char *kBinaryOperationShortNames[
-    static_cast<typename std::underlying_type<BinaryOperationID>::type>(
-        BinaryOperationID::kNumBinaryOperationIDs)];
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_BINARY_OPERATION_ID_HPP_


[08/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/CMathUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryOperations.hpp b/types/operations/unary_operations/CMathUnaryOperations.hpp
new file mode 100644
index 0000000..7a372e0
--- /dev/null
+++ b/types/operations/unary_operations/CMathUnaryOperations.hpp
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_
+
+#include <cmath>
+#include <string>
+
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/operations/OperationUtil.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename ArgumentT, typename ResultT,
+          typename ResultT::cpptype f(typename ArgumentT::cpptype),
+          typename FunctorNameT>
+struct CMathUnaryFunctorWrapper {
+  struct Implemenation : public UnaryFunctor<ArgumentT, ResultT> {
+    inline typename ResultT::cpptype apply(
+        const typename ArgumentT::cpptype &argument) const {
+      return f(argument);
+    }
+    inline static std::string GetName() {
+      return FunctorNameT::ToString();
+    }
+  };
+
+  typedef Implemenation type;
+};
+
+template <typename ArgumentT, typename ResultT,
+          typename ResultT::cpptype f(typename ArgumentT::cpptype),
+          typename FunctorNameT>
+using CMathUnaryFunctor =
+    typename CMathUnaryFunctorWrapper<ArgumentT, ResultT, f, FunctorNameT>::type;
+
+inline std::int64_t CMathRound(const float arg) {
+  return std::llround(arg);
+}
+inline std::int64_t CMathRound(const double arg) {
+  return std::llround(arg);
+}
+
+using CMathUnaryFunctorPack = FunctorPack<
+// abs
+    CMathUnaryFunctor<IntType, IntType,
+                      std::abs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<LongType, LongType,
+                      std::abs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::fabs, meta::StringLiteral<'a','b','s'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::fabs, meta::StringLiteral<'a','b','s'>>,
+// sqrt
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
+// exp
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::exp, meta::StringLiteral<'e','x','p'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::exp, meta::StringLiteral<'e','x','p'>>,
+// log
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::log, meta::StringLiteral<'l','o','g'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::log, meta::StringLiteral<'l','o','g'>>,
+// ceil
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
+// floor
+    CMathUnaryFunctor<FloatType, FloatType,
+                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
+    CMathUnaryFunctor<DoubleType, DoubleType,
+                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
+// round
+    CMathUnaryFunctor<FloatType, LongType,
+                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>,
+    CMathUnaryFunctor<DoubleType, LongType,
+                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>
+>;
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_CMATH_UNARY_OPERATIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp
new file mode 100644
index 0000000..5091e89
--- /dev/null
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -0,0 +1,298 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/operations/unary_operations/CastOperation.hpp"
+
+#include <algorithm>
+#include <map>
+#include <cstdint>
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include "types/CharType.hpp"
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/TypedValue.hpp"
+#include "types/VarCharType.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "types/port/strnlen.hpp"
+#include "utility/EqualsAnyConstant.hpp"
+#include "utility/StringUtil.hpp"
+
+namespace quickstep {
+
+namespace {
+
+template <typename ArgumentT, typename ResultT>
+struct NumericCastToNumericFunctor
+    : public UnaryFunctor<ArgumentT, ResultT> {
+  inline typename ResultT::cpptype apply(
+      const typename ArgumentT::cpptype &argument) const {
+    return static_cast<typename ResultT::cpptype>(argument);
+  }
+};
+
+template <typename ArgumentT, typename ResultT>
+class CastToAsciiStringFunctor : public UnaryFunctor<ArgumentT, ResultT> {
+ public:
+  explicit CastToAsciiStringFunctor(const ArgumentT &argument_type,
+                                    const std::size_t max_string_length)
+      : argument_type_(argument_type),
+        max_string_length_(max_string_length) {}
+
+  inline void apply(const typename ArgumentT::cpptype &argument, void *result) const {
+    std::string str = argument_type_.printValueToString(TypedValue(argument));
+    const std::size_t str_len = str.length();
+
+    if (str_len < max_string_length_) {
+      std::memcpy(result, str.c_str(), str_len);
+      static_cast<char *>(result)[str_len] = 0;
+    } else {
+      std::memcpy(result, str.c_str(), max_string_length_);
+    }
+  }
+
+  inline TypedValue apply(const typename ArgumentT::cpptype &argument) const {
+    std::string str = argument_type_.printValueToString(TypedValue(argument));
+    const std::size_t len = std::min(str.length(), max_string_length_);
+    const std::size_t buf_len = len + 1;
+
+    char *buf = static_cast<char *>(std::malloc(buf_len));
+    std::memcpy(buf, str.c_str(), len);
+    buf[len] = 0;
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, buf_len);
+  }
+
+ private:
+  const ArgumentT &argument_type_;
+  const std::size_t max_string_length_;
+};
+
+template <typename ResultCppType>
+ResultCppType CastStringToNumericImpl(const char *str);
+
+template <>
+bool CastStringToNumericImpl(const char *str) {
+  const std::string lo_str = ToLower(str);
+  if (lo_str == "true") {
+    return true;
+  } else {
+    return false;
+  }
+}
+template <>
+int CastStringToNumericImpl(const char *str) {
+  return std::atoi(str);
+}
+template <>
+float CastStringToNumericImpl(const char *str) {
+  return static_cast<float>(std::atof(str));
+}
+template <>
+std::int64_t CastStringToNumericImpl(const char *str) {
+  return std::atoll(str);
+}
+template <>
+double CastStringToNumericImpl(const char *str) {
+  return std::atof(str);
+}
+
+template <typename ArgumentT, typename ResultT,
+          typename ResultT::cpptype f(const char*)>
+struct AsciiStringCastToNumericFunctor
+    : public UnaryFunctor<ArgumentT, ResultT> {
+  explicit AsciiStringCastToNumericFunctor(const std::size_t max_string_length)
+      : max_string_length_(max_string_length) {}
+
+  inline typename ResultT::cpptype apply(const TypedValue &argument) const {
+    return f(static_cast<const char*>(argument.getDataPtr()));
+  }
+
+  inline typename ResultT::cpptype apply(const void *argument) const {
+    const char *str = static_cast<const char*>(argument);
+    const std::string value(str, strnlen(str, max_string_length_));
+    return f(value.c_str());
+  }
+
+ private:
+  const std::size_t max_string_length_;
+};
+
+template <typename ArgumentT, typename ResultT>
+struct AsciiStringCastToAsciiStringFunctor
+    : public UnaryFunctor<ArgumentT, ResultT> {
+  explicit AsciiStringCastToAsciiStringFunctor(const std::size_t max_string_length)
+      : max_string_length_(max_string_length) {}
+
+  inline void apply(const void *argument, void *result) const {
+    std::memcpy(result, argument, max_string_length_);
+  }
+
+  inline void apply(const TypedValue &argument, void *result) const {
+    std::memcpy(result,
+                argument.getOutOfLineData(),
+                std::min(argument.getDataSize(), max_string_length_));
+  }
+
+  inline TypedValue apply(const void *argument) const {
+    const std::size_t len =
+        strnlen(static_cast<const char*>(argument), max_string_length_);
+
+    char *buf = static_cast<char *>(std::malloc(len+1));
+    std::memcpy(buf, argument, len);
+    buf[len] = 0;
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, len+1);
+  }
+
+  inline TypedValue apply(const TypedValue &argument) const {
+    const std::size_t len =
+        std::min(argument.getDataSize() - 1, max_string_length_);
+
+    char *buf = static_cast<char *>(std::malloc(len+1));
+    std::memcpy(buf, argument.getDataPtr(), len);
+    buf[len] = 0;
+    return TypedValue::CreateWithOwnedData(kVarChar, buf, len+1);
+  }
+
+ private:
+  const std::size_t max_string_length_;
+};
+
+}  // namespace
+
+const re2::RE2 CastOperation::kTypePattern("([a-z]+)(\\(([0-9]+)\\))?");
+
+const std::map<std::string, TypeID> CastOperation::kNameToTypeIDMap = {
+    { "bool",    kBool },
+    { "int",     kInt },
+    { "long",    kLong },
+    { "float",   kFloat },
+    { "double",  kDouble },
+    { "char",    kChar },
+    { "varchar", kVarChar }
+};
+
+UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
+    const Type &type,
+    const std::vector<TypedValue> &static_arguments) const {
+  const Type *result_type = getResultType(type, static_arguments);
+  DCHECK(result_type != nullptr);
+
+  const TypeID argument_type_id = type.getTypeID();
+  const TypeID result_type_id = result_type->getTypeID();
+
+  if (QUICKSTEP_EQUALS_ANY_CONSTANT(argument_type_id, kBool, kInt, kLong, kFloat, kDouble)) {
+    return InvokeOnTypeID<TypeIDSelectorNumeric>(
+        argument_type_id,
+        [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+      using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
+
+      switch (result_type_id) {
+        case kBool:  // Fall through
+        case kInt:
+        case kLong:
+        case kFloat:
+        case kDouble: {
+          return InvokeOnTypeID<TypeIDSelectorNumeric>(
+              result_type_id,
+              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
+
+            return new UncheckedUnaryOperatorWrapperCodegen<
+                NumericCastToNumericFunctor<ArgumentT, ResultT>>(type, *result_type);
+          });
+        }
+        case kChar:  // Fall through
+        case kVarChar: {
+          return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+              result_type_id,
+              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
+
+            return new UncheckedUnaryOperatorWrapperCodegen<
+                 CastToAsciiStringFunctor<ArgumentT, ResultT>>(
+                     type, *result_type,
+                     static_cast<const ArgumentT&>(type),
+                     static_cast<const ResultT*>(result_type)->getStringLength());
+          });
+        }
+        default:
+          LOG(FATAL) << "Unexpected result type " << result_type->getName()
+                     << " in CastOperation::makeUncheckedUnaryOperator "
+                     << "for argument type " << type.getName();
+      }
+    });
+  } else if (QUICKSTEP_EQUALS_ANY_CONSTANT(argument_type_id, kChar, kVarChar)) {
+    return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+        argument_type_id,
+        [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+      using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
+
+      switch (result_type_id) {
+        case kBool:  // Fall through
+        case kInt:
+        case kLong:
+        case kFloat:
+        case kDouble: {
+          return InvokeOnTypeID<TypeIDSelectorNumeric>(
+              result_type_id,
+              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
+
+            return new UncheckedUnaryOperatorWrapperCodegen<
+                AsciiStringCastToNumericFunctor<
+                    ArgumentT, ResultT,
+                    CastStringToNumericImpl<typename ResultT::cpptype>>>(
+                        type, *result_type,
+                        static_cast<const ArgumentT&>(type).getStringLength());
+          });
+        }
+        case kChar:  // Fall through
+        case kVarChar: {
+          return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
+              result_type_id,
+              [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
+
+            return new UncheckedUnaryOperatorWrapperCodegen<
+                 AsciiStringCastToAsciiStringFunctor<ArgumentT, ResultT>>(
+                     type, *result_type,
+                     std::min(static_cast<const ArgumentT&>(type).getStringLength(),
+                              static_cast<const ResultT*>(result_type)->getStringLength()));
+          });
+        }
+        default:
+          LOG(FATAL) << "Unexpected result type " << result_type->getName()
+                     << " in CastOperation::makeUncheckedUnaryOperator "
+                     << "for argument type " << type.getName();
+      }
+    });
+  }
+
+  LOG(FATAL) << "Unexpected argument type in "
+             << "CastOperation::makeUncheckedUnaryOperator: "
+             << result_type->getName();
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/CastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp
new file mode 100644
index 0000000..140c152
--- /dev/null
+++ b/types/operations/unary_operations/CastOperation.hpp
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
+
+#include <cstddef>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "types/IntType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
+
+#include "glog/logging.h"
+
+#include "re2/stringpiece.h"
+#include "re2/re2.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief UnaryOperation for CAST.
+ */
+class CastOperation : public UnaryOperation {
+ public:
+  CastOperation() {}
+
+  std::string getName() const override {
+    return "Cast";
+  }
+
+  std::string getShortName() const override {
+    return "Cast";
+  }
+
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    const std::vector<TypeID> source_type_ids =
+        { kBool, kInt, kLong, kFloat, kDouble, kChar, kVarChar };
+    const std::vector<TypeID> target_type_carrier = { kVarChar };
+
+    std::vector<OperationSignaturePtr> signatures;
+    for (const TypeID source_type_id : source_type_ids) {
+      signatures.emplace_back(
+          OperationSignature::Create(getName(), {source_type_id}, target_type_carrier));
+    }
+    return signatures;
+  }
+
+  bool canApplyTo(const Type &type,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK_EQ(1u, static_arguments.size());
+    if (getResultTypeInternal(type, static_arguments.front()) == nullptr) {
+      *message = "Invalid target type for CAST";
+      return false;
+    }
+    return true;
+  }
+
+  const Type* getResultType(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK_EQ(1u, static_arguments.size());
+    const Type *target_type =
+        getResultTypeInternal(type, static_arguments.front());
+    DCHECK(target_type != nullptr);
+    return target_type;
+  }
+
+  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override;
+
+ private:
+  static const Type* getResultTypeInternal(const Type &type,
+                                           const TypedValue &type_arg) {
+    DCHECK(type_arg.getTypeID() == kVarChar);
+    const std::string type_str =
+        ToLower(std::string(static_cast<const char*>(type_arg.getOutOfLineData())));
+
+    if (type_str == "text") {
+      return &TypeFactory::GetType(
+          kVarChar, type.getPrintWidth(), type.isNullable());
+    }
+
+    const re2::StringPiece type_piece(type_str);
+    std::string type_name;
+    std::string length_str;
+    if (!re2::RE2::FullMatch(type_piece,
+                             kTypePattern,
+                             &type_name,
+                             static_cast<void *>(nullptr),
+                             &length_str)) {
+      return nullptr;
+    }
+
+    auto it = kNameToTypeIDMap.find(type_name);
+    if (it == kNameToTypeIDMap.end()) {
+      return nullptr;
+    }
+
+    if (length_str.empty()) {
+      return &TypeFactory::GetType(it->second);
+    } else {
+      TypedValue length_value;
+      if (IntType::InstanceNonNullable().parseValueFromString(length_str, &length_value)) {
+        return &TypeFactory::GetType(
+            it->second,
+            static_cast<std::size_t>(length_value.getLiteral<int>()),
+            type.isNullable());
+      }
+    }
+    return nullptr;
+  }
+
+  static const re2::RE2 kTypePattern;
+  static const std::map<std::string, TypeID> kNameToTypeIDMap;
+
+  DISALLOW_COPY_AND_ASSIGN(CastOperation);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/DateExtractOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp
index c99e403..f95e109 100644
--- a/types/operations/unary_operations/DateExtractOperation.cpp
+++ b/types/operations/unary_operations/DateExtractOperation.cpp
@@ -21,521 +21,135 @@
 
 #include <cstddef>
 #include <cstdint>
-#include <memory>
+#include <map>
 #include <string>
 #include <type_traits>
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <utility>
 #include <vector>
 
-#include "storage/StorageBlockInfo.hpp"
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
+#include "types/DateType.hpp"
 #include "types/DatetimeLit.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
+#include "types/DatetimeType.hpp"
 #include "types/Type.hpp"
-#include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/Operation.pb.h"
-#include "utility/Macros.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
 
 #include "glog/logging.h"
 
-using std::int32_t;
-using std::int64_t;
-
 namespace quickstep {
 
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue(
-    const TypedValue &argument) const {
-  if (argument_nullable && argument.isNull()) {
-    return TypedValue(kLong);
-  }
-
-  return TypedValue(dateExtract(argument.getLiteral<DatetimeLit>()));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToTypedValue(
-    const TypedValue &argument) const {
-  if (argument_nullable && argument.isNull()) {
-    return TypedValue(kInt);
-  }
-
-  return TypedValue(dateExtract(argument.getLiteral<DateLit>()));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const {
-  if (argument_nullable && argument == nullptr) {
-    return TypedValue(kLong);
-  }
-
-  return TypedValue(dateExtract(*static_cast<const DatetimeLit*>(argument)));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-TypedValue DateExtractUncheckedOperator<unit, argument_nullable>::applyToDataPtr(const void *argument) const {
-  if (argument_nullable && argument == nullptr) {
-    return TypedValue(kInt);
-  }
-
-  return TypedValue(dateExtract(*static_cast<const DateLit*>(argument)));
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector(
-    const ColumnVector &argument) const {
-  // Datetime are usable with NativeColumnVector, so 'argument' should always
-  // be native.
-  DCHECK(argument.isNative());
-
-  const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
-  std::unique_ptr<NativeColumnVector> result(
-      new NativeColumnVector(LongType::Instance(argument_nullable), native_argument.size()));
-
-  for (std::size_t pos = 0;
-       pos < native_argument.size();
-       ++pos) {
-    const DatetimeLit *datetime_arg =
-        static_cast<const DatetimeLit*>(native_argument.getUntypedValue<argument_nullable>(pos));
-    if (argument_nullable && (datetime_arg == nullptr)) {
-      result->appendNullValue();
-    } else {
-      *static_cast<int64_t*>(result->getPtrForDirectWrite())
-          = dateExtract(*datetime_arg);
-    }
-  }
-
-  return result.release();
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToColumnVector(
-    const ColumnVector &argument) const {
-  // Date is usable with NativeColumnVector, so 'argument' should always
-  // be native.
-  DCHECK(argument.isNative());
-
-  const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
-  std::unique_ptr<NativeColumnVector> result(
-      new NativeColumnVector(IntType::Instance(argument_nullable), native_argument.size()));
-
-  for (std::size_t pos = 0;
-       pos < native_argument.size();
-       ++pos) {
-    const DateLit *date_arg =
-        static_cast<const DateLit*>(native_argument.getUntypedValue<argument_nullable>(pos));
-    if (argument_nullable && (date_arg == nullptr)) {
-      result->appendNullValue();
-    } else {
-      *static_cast<int32_t*>(result->getPtrForDirectWrite())
-          = dateExtract(*date_arg);
-    }
-  }
-
-  return result.release();
-}
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor(
-    ValueAccessor *accessor,
-    const attribute_id argument_attr_id) const {
-  return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    std::unique_ptr<NativeColumnVector> result(
-        new NativeColumnVector(LongType::Instance(argument_nullable), accessor->getNumTuples()));
-    accessor->beginIteration();
-    while (accessor->next()) {
-      const DatetimeLit *datetime_arg =
-          static_cast<const DatetimeLit*>(
-              accessor->template getUntypedValue<argument_nullable>(argument_attr_id));
-      if (argument_nullable && (datetime_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<int64_t*>(result->getPtrForDirectWrite())
-            = this->dateExtract(*datetime_arg);
-      }
-    }
-    return result.release();
-  });
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessor(
-    ValueAccessor *accessor,
-    const attribute_id argument_attr_id) const {
-  return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    std::unique_ptr<NativeColumnVector> result(
-        new NativeColumnVector(IntType::Instance(argument_nullable), accessor->getNumTuples()));
-    accessor->beginIteration();
-    while (accessor->next()) {
-      const DateLit *date_arg =
-          static_cast<const DateLit*>(
-              accessor->template getUntypedValue<argument_nullable>(argument_attr_id));
-      if (argument_nullable && (date_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<int32_t*>(result->getPtrForDirectWrite())
-            = this->dateExtract(*date_arg);
-      }
-    }
-    return result.release();
-  });
-}
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DatetimeExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin(
-    ValueAccessor *accessor,
-    const bool use_left_relation,
-    const attribute_id argument_attr_id,
-    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
-  std::unique_ptr<NativeColumnVector> result(
-      new NativeColumnVector(LongType::Instance(argument_nullable), joined_tuple_ids.size()));
-  return InvokeOnValueAccessorNotAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-      const DatetimeLit *datetime_arg =
-          static_cast<const DatetimeLit*>(
-              accessor->template getUntypedValueAtAbsolutePosition<argument_nullable>(
-                  argument_attr_id,
-                  use_left_relation ? joined_pair.first : joined_pair.second));
-      if (argument_nullable && (datetime_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<int64_t*>(result->getPtrForDirectWrite())
-            = this->dateExtract(*datetime_arg);
-      }
-    }
-    return result.release();
-  });
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-ColumnVector* DateExtractUncheckedOperator<unit, argument_nullable>::applyToValueAccessorForJoin(
-    ValueAccessor *accessor,
-    const bool use_left_relation,
-    const attribute_id argument_attr_id,
-    const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
-  std::unique_ptr<NativeColumnVector> result(
-      new NativeColumnVector(IntType::Instance(argument_nullable), joined_tuple_ids.size()));
-  return InvokeOnValueAccessorNotAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-      const DateLit *date_arg =
-          static_cast<const DateLit*>(
-              accessor->template getUntypedValueAtAbsolutePosition<argument_nullable>(
-                  argument_attr_id,
-                  use_left_relation ? joined_pair.first : joined_pair.second));
-      if (argument_nullable && (date_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<int32_t*>(result->getPtrForDirectWrite())
-            = this->dateExtract(*date_arg);
-      }
-    }
-    return result.release();
-  });
-}
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-template <DateExtractUnit unit, bool argument_nullable>
-inline int64_t
-DatetimeExtractUncheckedOperator<unit, argument_nullable>::dateExtract(
-    const DatetimeLit &argument) const {
-  switch (unit) {
-    case DateExtractUnit::kYear:
-      return argument.yearField();
-    case DateExtractUnit::kMonth:
-      return argument.monthField();
-    case DateExtractUnit::kDay:
-      return argument.dayField();
-    case DateExtractUnit::kHour:
-      return argument.hourField();
-    case DateExtractUnit::kMinute:
-      return argument.minuteField();
-    case DateExtractUnit::kSecond:
-      return argument.secondField();
-    default:
-      FATAL_ERROR("Unsupported DateExtractUnit in DatetimeExtractUncheckedOperator::dateExtract.");
-  }
-}
-
-template <DateExtractUnit unit, bool argument_nullable>
-inline int32_t DateExtractUncheckedOperator<unit, argument_nullable>::dateExtract(const DateLit &argument) const {
-  switch (unit) {
-    case DateExtractUnit::kYear:
-      return argument.yearField();
-    case DateExtractUnit::kMonth:
-      return argument.monthField();
-    default:
-      FATAL_ERROR("Unsupported DateExtractUnit in DateExtractUncheckedOperator::dateExtract.");
-  }
-}
-
-const DateExtractOperation& DateExtractOperation::Instance(const DateExtractUnit unit) {
-  switch (unit) {
-    case DateExtractUnit::kYear: {
-      static DateExtractOperation instance(DateExtractUnit::kYear);
-      return instance;
-    }
-    case DateExtractUnit::kMonth: {
-      static DateExtractOperation instance(DateExtractUnit::kMonth);
-      return instance;
-    }
-    case DateExtractUnit::kDay: {
-      static DateExtractOperation instance(DateExtractUnit::kDay);
-      return instance;
-    }
-    case DateExtractUnit::kHour: {
-      static DateExtractOperation instance(DateExtractUnit::kHour);
-      return instance;
-    }
-    case DateExtractUnit::kMinute: {
-      static DateExtractOperation instance(DateExtractUnit::kMinute);
-      return instance;
-    }
-    case DateExtractUnit::kSecond: {
-      static DateExtractOperation instance(DateExtractUnit::kSecond);
-      return instance;
-    }
-    default: {
-      FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::Instance.");
+struct DateExtractFunctor : public UnaryFunctor<DateType, IntType> {
+  template <typename DateExtractUnitT>
+  inline int apply(const DateLit &argument) const {
+    switch (DateExtractUnitT::value) {
+      case DateExtractUnit::kYear:
+        return argument.yearField();
+      case DateExtractUnit::kMonth:
+        return argument.monthField();
+      case DateExtractUnit::kDay:
+        return argument.dayField();
+      default:
+        DLOG(FATAL) << "Unsupported DateExtractUnit in DateExtractFunctor::apply";
     }
   }
-}
-
-serialization::UnaryOperation DateExtractOperation::getProto() const {
-  serialization::UnaryOperation proto;
-  proto.set_operation_id(serialization::UnaryOperation::DATE_EXTRACT);
-
-  switch (unit_) {
-    case DateExtractUnit::kYear:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::YEAR);
-      break;
-    case DateExtractUnit::kMonth:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::MONTH);
-      break;
-    case DateExtractUnit::kDay:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::DAY);
-      break;
-    case DateExtractUnit::kHour:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::HOUR);
-      break;
-    case DateExtractUnit::kMinute:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::MINUTE);
-      break;
-    case DateExtractUnit::kSecond:
-      proto.SetExtension(serialization::DateExtractOperation::unit, serialization::DateExtractOperation::SECOND);
-      break;
-    default:
-      FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::getProto.");
-  }
-
-  return proto;
-}
-
-std::string DateExtractOperation::getName() const {
-  std::string name(kUnaryOperationNames[static_cast<std::size_t>(operation_id_)]);
-  name.push_back('(');
-  switch (unit_) {
-    case DateExtractUnit::kYear:
-      name.append("YEAR)");
-      break;
-    case DateExtractUnit::kMonth:
-      name.append("MONTH)");
-      break;
-    case DateExtractUnit::kDay:
-      name.append("DAY)");
-      break;
-    case DateExtractUnit::kHour:
-      name.append("HOUR)");
-      break;
-    case DateExtractUnit::kMinute:
-      name.append("MINUTE)");
-      break;
-    case DateExtractUnit::kSecond:
-      name.append("SECOND)");
-      break;
-    default:
-      name.append("UNKNOWN)");
-      break;
-  }
-  return name;
-}
-
-const Type* DateExtractOperation::pushDownTypeHint(const Type *type_hint) const {
-  if (type_hint == nullptr) {
-    return nullptr;
-  }
+};
 
-  if (type_hint->getTypeID() == kLong) {
-    switch (unit_) {
-      case DateExtractUnit::kYear:  // Fall through.
+struct DatetimeExtractFunctor : public UnaryFunctor<DatetimeType, IntType> {
+  template <typename DateExtractUnitT>
+  inline std::int64_t apply(const DatetimeLit &argument) const {
+    switch (DateExtractUnitT::value) {
+      case DateExtractUnit::kYear:
+        return argument.yearField();
       case DateExtractUnit::kMonth:
-        // There are two possibilities for the return type, based on whether we
-        // have Datetime or Date as the underlying date implementation.
-        return nullptr;
-      case DateExtractUnit::kDay:  // Fall through.
+        return argument.monthField();
+      case DateExtractUnit::kDay:
+        return argument.dayField();
       case DateExtractUnit::kHour:
+        return argument.hourField();
       case DateExtractUnit::kMinute:
+        return argument.minuteField();
       case DateExtractUnit::kSecond:
-        return &TypeFactory::GetType(kDatetime, type_hint->isNullable());
+        return argument.secondField();
       default:
-        return nullptr;
+        DLOG(FATAL) << "Unsupported DateExtractUnit in DatetimeExtractFunctor::apply";
+    }
+  }
+};
+
+const std::map<std::string, DateExtractUnit> DateExtractOperation::kNameToUnitMap = {
+    { "year",   DateExtractUnit::kYear },
+    { "month",  DateExtractUnit::kMonth },
+    { "day",    DateExtractUnit::kDay },
+    { "hour",   DateExtractUnit::kHour },
+    { "minute", DateExtractUnit::kMinute },
+    { "second", DateExtractUnit::kSecond }
+};
+
+UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperator(
+    const Type &type,
+    const std::vector<TypedValue> &static_arguments) const {
+  DCHECK_EQ(1u, static_arguments.size());
+
+  const DateExtractUnit unit = parseUnit(static_arguments.front());
+  const Type *result_type = getResultType(type, static_arguments);
+
+  if (type.getTypeID() == kDate) {
+    switch (unit) {
+      case DateExtractUnit::kYear:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DateExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
+                 type, *result_type);
+      case DateExtractUnit::kMonth:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DateExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
+                 type, *result_type);
+      case DateExtractUnit::kDay:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DateExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
+                 type, *result_type);
+      default:
+        LOG(FATAL) << "Unsupported DateExtractUnit for DateType in "
+                   << "DateExtractOperation::makeUncheckedUnaryOperator";
     }
   } else {
-    return nullptr;
-  }
-}
-
-TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument,
-                                                const Type &argument_type) const {
-  if (((argument.getTypeID() != TypeID::kDatetime) ||
-       (argument_type.getTypeID() != TypeID::kDatetime)) &&
-      ((argument.getTypeID() != TypeID::kDate) ||
-       (argument_type.getTypeID() != TypeID::kDate))) {
-    LOG(FATAL) << "UnaryOperation " << getName() << " is only applicable to Type "
-               << kTypeNames[TypeID::kDatetime] << ", but applyToChecked() was "
-               << "called with 'argument' of Type " << kTypeNames[argument.getTypeID()]
-               << " and explicit 'argument_type' parameter of "
-               << argument_type.getName();
-  }
-
-  if (argument.isNull()) {
-    if (argument.getTypeID() == TypeID::kDatetime) {
-      return TypedValue(kLong);
-    } else {
-      // argument type is kDate.
-      DCHECK_EQ(TypeID::kDate, argument.getTypeID());
-      return TypedValue(kInt);
-    }
-  }
-
-  switch (unit_) {
-    case DateExtractUnit::kYear: {
-      if (argument.getTypeID() == TypeID::kDatetime) {
-        return TypedValue(argument.getLiteral<DatetimeLit>().yearField());
-      } else {
-        // argument type is kDate.
-        DCHECK_EQ(TypeID::kDate, argument.getTypeID());
-        return TypedValue(argument.getLiteral<DateLit>().yearField());
-      }
-    }
-    case DateExtractUnit::kMonth: {
-      if (argument.getTypeID() == TypeID::kDatetime) {
-        return TypedValue(argument.getLiteral<DatetimeLit>().monthField());
-      } else {
-        // argument type is kDate.
-        DCHECK_EQ(TypeID::kDate, argument.getTypeID());
-        return TypedValue(argument.getLiteral<DateLit>().monthField());
-      }
-    }
-    case DateExtractUnit::kDay:
-      return TypedValue(argument.getLiteral<DatetimeLit>().dayField());
-    case DateExtractUnit::kHour:
-      return TypedValue(argument.getLiteral<DatetimeLit>().hourField());
-    case DateExtractUnit::kMinute:
-      return TypedValue(argument.getLiteral<DatetimeLit>().minuteField());
-    case DateExtractUnit::kSecond:
-      return TypedValue(argument.getLiteral<DatetimeLit>().secondField());
-    default: {
-      LOG(FATAL) << "Unsupported DateExtractUnit in DateExtractOperation::applyToChecked().";
-    }
-  }
-}
-
-UncheckedUnaryOperator* DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper(const Type &type) const {
-  switch (unit_) {
-    case DateExtractUnit::kYear: {
-      if (type.getTypeID() == TypeID::kDatetime) {
-        if (type.isNullable()) {
-          return new DatetimeExtractUncheckedOperator<DateExtractUnit::kYear, true>();
-        } else {
-          return new DatetimeExtractUncheckedOperator<DateExtractUnit::kYear, false>();
-        }
-      } else {
-        DCHECK_EQ(TypeID::kDate, type.getTypeID());
-        // type is kDate.
-        if (type.isNullable()) {
-          return new DateExtractUncheckedOperator<DateExtractUnit::kYear, true>();
-        } else {
-          return new DateExtractUncheckedOperator<DateExtractUnit::kYear, false>();
-        }
-      }
-    }
-    case DateExtractUnit::kMonth: {
-      if (type.getTypeID() == TypeID::kDatetime) {
-        if (type.isNullable()) {
-          return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMonth, true>();
-        } else {
-          return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMonth, false>();
-        }
-      } else {
-        // type is kDate.
-        DCHECK_EQ(TypeID::kDate, type.getTypeID());
-        if (type.isNullable()) {
-          return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, true>();
-        } else {
-          return new DateExtractUncheckedOperator<DateExtractUnit::kMonth, false>();
-        }
-      }
-    }
-    case DateExtractUnit::kDay:
-      if (type.isNullable()) {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, true>();
-      } else {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kDay, false>();
-      }
-    case DateExtractUnit::kHour:
-      if (type.isNullable()) {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, true>();
-      } else {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kHour, false>();
-      }
-    case DateExtractUnit::kMinute:
-      if (type.isNullable()) {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, true>();
-      } else {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kMinute, false>();
-      }
-    case DateExtractUnit::kSecond:
-      if (type.isNullable()) {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, true>();
-      } else {
-        return new DatetimeExtractUncheckedOperator<DateExtractUnit::kSecond, false>();
-      }
-    default:
-      FATAL_ERROR("Unsupported DateExtractUnit in DateExtractOperation::makeUncheckedUnaryOperatorForTypeHelper.");
-  }
-}
-
-const Type* DateExtractOperation::resultTypeForArgumentType(const Type &type) const {
-  if (canApplyToType(type)) {
-    if (type.getTypeID() == kDatetime) {
-      return &LongType::Instance(type.isNullable());
-    } else {
-      DCHECK_EQ(kDate, type.getTypeID());
-      return &IntType::Instance(type.isNullable());
+    switch (unit) {
+      case DateExtractUnit::kYear:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kYear>>(
+                 type, *result_type);
+      case DateExtractUnit::kMonth:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kMonth>>(
+                 type, *result_type);
+      case DateExtractUnit::kDay:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kDay>>(
+                 type, *result_type);
+      case DateExtractUnit::kHour:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kHour>>(
+                 type, *result_type);
+      case DateExtractUnit::kMinute:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kMinute>>(
+                 type, *result_type);
+      case DateExtractUnit::kSecond:
+        return new UncheckedUnaryOperatorWrapperCodegen<
+             DatetimeExtractFunctor,
+             std::integral_constant<DateExtractUnit, DateExtractUnit::kSecond>>(
+                 type, *result_type);
+      default:
+        LOG(FATAL) << "Unsupported DateExtractUnit for DatetimeType in "
+                   << "DateExtractOperation::makeUncheckedUnaryOperator";
     }
-  } else {
-    return nullptr;
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/DateExtractOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.hpp b/types/operations/unary_operations/DateExtractOperation.hpp
index f8c091b..577e924 100644
--- a/types/operations/unary_operations/DateExtractOperation.hpp
+++ b/types/operations/unary_operations/DateExtractOperation.hpp
@@ -23,109 +23,25 @@
 #include <cstdint>
 #include <string>
 
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <utility>
-#include <vector>
-
-#include "storage/StorageBlockInfo.hpp"
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#include "catalog/CatalogTypedefs.hpp"
+#include "types/IntType.hpp"
 #include "types/LongType.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
-#include "types/operations/Operation.pb.h"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
 #include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
 
 namespace quickstep {
 
-class ColumnVector;
-class ValueAccessor;
-
-struct DatetimeLit;
-
-/** \addtogroup Types
- *  @{
- */
-
 enum class DateExtractUnit {
   kYear = 0,
   kMonth,
   kDay,
   kHour,
   kMinute,
-  kSecond
-};
-
-/**
- * @brief UncheckedUnaryOperator for Datetime Extract.
- */
-template <DateExtractUnit unit, bool argument_nullable>
-class DatetimeExtractUncheckedOperator : public UncheckedUnaryOperator {
- public:
-  DatetimeExtractUncheckedOperator()
-      : UncheckedUnaryOperator() {}
-
-  TypedValue applyToTypedValue(const TypedValue &argument) const override;
-
-  TypedValue applyToDataPtr(const void *argument) const override;
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override;
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id argument_attr_id) const override;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  ColumnVector* applyToValueAccessorForJoin(
-      ValueAccessor *accessor,
-      const bool use_left_relation,
-      const attribute_id argument_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
-  inline std::int64_t dateExtract(const DatetimeLit &argument) const;
-
-  DISALLOW_COPY_AND_ASSIGN(DatetimeExtractUncheckedOperator);
-};
-
-/**
- * @brief UncheckedUnaryOperator for Date Extract.
- */
-template <DateExtractUnit unit, bool argument_nullable>
-class DateExtractUncheckedOperator : public UncheckedUnaryOperator {
- public:
-  DateExtractUncheckedOperator()
-      : UncheckedUnaryOperator() {}
-
-  TypedValue applyToTypedValue(const TypedValue &argument) const override;
-
-  TypedValue applyToDataPtr(const void *argument) const override;
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override;
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id argument_attr_id) const override;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  ColumnVector* applyToValueAccessorForJoin(
-      ValueAccessor *accessor,
-      const bool use_left_relation,
-      const attribute_id argument_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override;
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
-  inline std::int32_t dateExtract(const DateLit &argument) const;
-
-  DISALLOW_COPY_AND_ASSIGN(DateExtractUncheckedOperator);
+  kSecond,
+  kInvalid
 };
 
 /**
@@ -133,55 +49,82 @@ class DateExtractUncheckedOperator : public UncheckedUnaryOperator {
  */
 class DateExtractOperation : public UnaryOperation {
  public:
-  /**
-   * @brief Get a reference to the singleton instance of this Operation for a
-   *        particular DateExtractUnit.
-   *
-   * @param unit The date unit to extract.
-   * @return A reference to the singleton instance of this Operation for the
-   *         specified DateExtractUnit.
-   **/
-  static const DateExtractOperation& Instance(const DateExtractUnit unit);
-
-  serialization::UnaryOperation getProto() const override;
-
-  std::string getName() const override;
-
-  bool canApplyToType(const Type &type) const override {
-    return type.getTypeID() == TypeID::kDatetime || type.getTypeID() == kDate;
-  }
-
-  const Type* resultTypeForArgumentType(const Type &type) const override;
+  DateExtractOperation() {}
 
-  const Type* fixedNullableResultType() const override {
-    return nullptr;
+  std::string getName() const override {
+    return "DateExtract";
   }
 
-  bool resultTypeIsPlausible(const Type &result_type) const override {
-    return result_type.getTypeID() == kLong || result_type.getTypeID() == kInt;
+  std::string getShortName() const override {
+    return "DateExtract";
   }
 
-  const Type* pushDownTypeHint(const Type *type_hint) const override;
-
-  TypedValue applyToChecked(const TypedValue &argument,
-                            const Type &argument_type) const override;
+  std::vector<OperationSignaturePtr> getSignatures() const override {
+    const std::vector<TypeID> unit_carrier = { kVarChar };
+    return {
+        OperationSignature::Create(getName(), {kDate}, unit_carrier),
+        OperationSignature::Create(getName(), {kDatetime}, unit_carrier)
+    };
+  }
 
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override {
-    DCHECK(canApplyToType(type));
+  bool canApplyTo(const Type &type,
+                  const std::vector<TypedValue> &static_arguments,
+                  std::string *message) const override {
+    DCHECK(type.getTypeID() == kDate || type.getTypeID() == kDatetime);
+    DCHECK_EQ(1u, static_arguments.size());
+
+    const DateExtractUnit unit = parseUnit(static_arguments.front());
+    switch (unit) {
+      case DateExtractUnit::kYear:  // Fall through
+      case DateExtractUnit::kMonth:
+      case DateExtractUnit::kDay:
+        return true;
+      case DateExtractUnit::kHour:  // Fall through
+      case DateExtractUnit::kMinute:
+      case DateExtractUnit::kSecond:
+        if (type.getTypeID() == kDate) {
+          *message = "Invalid extraction unit for argument of DATE type";
+        } else {
+          return true;
+        }
+      default:
+        *message = "Invalid extraction unit for DateExtract";
+        return false;
+    }
+  }
 
-    return makeUncheckedUnaryOperatorForTypeHelper(type);
+  const Type* getResultType(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override {
+    DCHECK(UnaryOperation::canApplyTo(type, static_arguments));
+    if (type.getTypeID() == kDatetime) {
+      return &LongType::Instance(type.isNullable());
+    } else {
+      DCHECK_EQ(kDate, type.getTypeID());
+      return &IntType::Instance(type.isNullable());
+    }
   }
 
- private:
-  explicit DateExtractOperation(const DateExtractUnit unit)
-      : UnaryOperation(UnaryOperationID::kDateExtract),
-        unit_(unit) {}
+  UncheckedUnaryOperator* makeUncheckedUnaryOperator(
+      const Type &type,
+      const std::vector<TypedValue> &static_arguments) const override;
 
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorForTypeHelper(const Type &type) const;
+ private:
+  static DateExtractUnit parseUnit(const TypedValue &unit_arg) {
+    DCHECK(unit_arg.getTypeID() == kVarChar);
+    const std::string unit_str =
+        ToLower(std::string(static_cast<const char*>(unit_arg.getOutOfLineData())));
+
+    auto it = kNameToUnitMap.find(unit_str);
+    if (it != kNameToUnitMap.end()) {
+      return it->second;
+    } else {
+      return DateExtractUnit::kInvalid;
+    }
+  }
 
-  const DateExtractUnit unit_;
+  static const std::map<std::string, DateExtractUnit> kNameToUnitMap;
 
- private:
   DISALLOW_COPY_AND_ASSIGN(DateExtractOperation);
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/NumericCastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/NumericCastOperation.hpp b/types/operations/unary_operations/NumericCastOperation.hpp
deleted file mode 100644
index 1c5e3d4..0000000
--- a/types/operations/unary_operations/NumericCastOperation.hpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_
-
-#include <cstddef>
-#include <string>
-#include <utility>
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-#include <vector>
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
-#include "types/Type.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/operations/Operation.pb.h"
-#include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
-#include "utility/Macros.hpp"
-#include "utility/PtrMap.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-// TODO(quickstep-team): Support CAST on Datetime, YearMonthInterval, DatetimeInterval, VarChar, Char.
-//                       Currently we only need cast operations on numeric values.
-
-/**
- * @brief UncheckedUnaryOperator for CAST.
- */
-template <class SourceType, bool source_nullability, class TargetType, bool target_nullability>
-class UncheckedNumericCastOperator : public UncheckedUnaryOperator {
- public:
-  UncheckedNumericCastOperator()
-      : UncheckedUnaryOperator(),
-        target_type_(TargetType::Instance(target_nullability)) {
-  }
-
-  TypedValue applyToTypedValue(const TypedValue &argument) const override {
-    if (source_nullability && argument.isNull()) {
-      return TypedValue(TargetType::kStaticTypeID);
-    }
-
-    return TypedValue(static_cast<typename TargetType::cpptype>(
-        argument.getLiteral<typename SourceType::cpptype>()));
-  }
-
-  TypedValue applyToDataPtr(const void *argument) const override {
-    if (source_nullability && argument == nullptr) {
-      return TypedValue(TargetType::kStaticTypeID);
-    }
-
-    return TypedValue(
-        static_cast<const typename TargetType::cpptype>(
-            *static_cast<const typename SourceType::cpptype*>(argument)));
-  }
-
-  ColumnVector* applyToColumnVector(const ColumnVector &argument) const override {
-    DCHECK(NativeColumnVector::UsableForType(target_type_));
-    DCHECK(argument.isNative());
-    const NativeColumnVector &native_argument = static_cast<const NativeColumnVector&>(argument);
-    NativeColumnVector *result = new NativeColumnVector(
-        target_type_,
-        native_argument.size());
-    for (std::size_t pos = 0;
-         pos < native_argument.size();
-         ++pos) {
-      const typename SourceType::cpptype *scalar_arg
-          = static_cast<const typename SourceType::cpptype*>(
-              native_argument.getUntypedValue<source_nullability>(pos));
-      if (source_nullability && (scalar_arg == nullptr)) {
-        result->appendNullValue();
-      } else {
-        *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
-            = static_cast<typename TargetType::cpptype>(*scalar_arg);
-      }
-    }
-    return result;
-  }
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-  ColumnVector* applyToValueAccessor(ValueAccessor *accessor,
-                                     const attribute_id argument_attr_id) const override {
-    DCHECK(NativeColumnVector::UsableForType(target_type_));
-    return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-        accessor,
-        [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-      NativeColumnVector *result = new NativeColumnVector(
-          target_type_,
-          accessor->getNumTuples());
-      accessor->beginIteration();
-      while (accessor->next()) {
-        const typename SourceType::cpptype *scalar_arg
-            = static_cast<const typename SourceType::cpptype*>(
-                accessor->template getUntypedValue<source_nullability>(argument_attr_id));
-        if (source_nullability && (scalar_arg == nullptr)) {
-          result->appendNullValue();
-        } else {
-          *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
-              = static_cast<typename TargetType::cpptype>(*scalar_arg);
-        }
-      }
-      return result;
-    });
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-  ColumnVector* applyToValueAccessorForJoin(
-      ValueAccessor *accessor,
-      const bool use_left_relation,
-      const attribute_id argument_attr_id,
-      const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const override {
-    DCHECK(NativeColumnVector::UsableForType(target_type_));
-    NativeColumnVector *result = new NativeColumnVector(target_type_,
-                                                        joined_tuple_ids.size());
-    InvokeOnValueAccessorNotAdapter(
-        accessor,
-        [&](auto *accessor) -> void {  // NOLINT(build/c++11)
-      for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-        const typename SourceType::cpptype *scalar_arg
-            = static_cast<const typename SourceType::cpptype*>(
-                accessor->template getUntypedValueAtAbsolutePosition<source_nullability>(
-                    argument_attr_id,
-                    use_left_relation ? joined_pair.first : joined_pair.second));
-        if (source_nullability && (scalar_arg == nullptr)) {
-          result->appendNullValue();
-        } else {
-          *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
-              = static_cast<typename TargetType::cpptype>(*scalar_arg);
-        }
-      }
-    });
-    return result;
-  }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
- private:
-  const Type &target_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(UncheckedNumericCastOperator);
-};
-
-/**
- * @brief UnaryOperation for CAST.
- */
-class NumericCastOperation : public UnaryOperation {
- public:
-  serialization::UnaryOperation getProto() const override {
-    serialization::UnaryOperation proto;
-    proto.set_operation_id(serialization::UnaryOperation::CAST);
-    proto.MutableExtension(serialization::CastOperation::target_type)
-        ->CopyFrom(getTargetType().getProto());
-
-    return proto;
-  }
-
-  /**
-   * @brief Get a reference to the singleton instance of this Operation.
-   *
-   * @param target_type The target type to coerce input values to.
-   * @return A reference to the singleton instance of this Operation.
-   **/
-  static const NumericCastOperation& Instance(const Type &target_type) {
-    static PtrMap<const Type*, NumericCastOperation> instance_map;
-    PtrMap<const Type*, NumericCastOperation>::iterator instance_map_it =
-        instance_map.find(&target_type);
-    if (instance_map_it == instance_map.end()) {
-      instance_map_it = instance_map.insert(&target_type,
-                                            new NumericCastOperation(target_type)).first;
-    }
-    return *(instance_map_it->second);
-  }
-
-  /**
-   * @return The target type for coercion.
-   */
-  const Type& getTargetType() const {
-    return target_type_;
-  }
-
-  std::string getName() const override {
-    return std::string(kUnaryOperationNames[static_cast<std::size_t>(operation_id_)])
-        .append("(")
-        .append(target_type_.getName())
-        .append(")");
-  }
-
-  bool canApplyToType(const Type &type) const override {
-    return target_type_.isCoercibleFrom(type);
-  }
-
-  const Type* resultTypeForArgumentType(const Type &type) const override {
-    if (canApplyToType(type)) {
-      return &target_type_;
-    } else {
-      return nullptr;
-    }
-  }
-
-  const Type* fixedNullableResultType() const override {
-    return &target_type_.getNullableVersion();
-  }
-
-  bool resultTypeIsPlausible(const Type &result_type) const override {
-    return result_type.equals(target_type_)
-           || result_type.equals(target_type_.getNullableVersion());
-  }
-
-  const Type* pushDownTypeHint(const Type *type_hint) const override {
-    return &target_type_;
-  }
-
-  TypedValue applyToChecked(const TypedValue &argument,
-                            const Type &argument_type) const override {
-    return target_type_.coerceValue(argument, argument_type);
-  }
-
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorForType(const Type &type) const override {
-    switch (type.getTypeID()) {
-      case kInt:
-        return makeUncheckedUnaryOperatorHelperForSourceNullability<IntType>(type);
-      case kLong:
-        return makeUncheckedUnaryOperatorHelperForSourceNullability<LongType>(type);
-      case kFloat:
-        return makeUncheckedUnaryOperatorHelperForSourceNullability<FloatType>(type);
-      case kDouble:
-        return makeUncheckedUnaryOperatorHelperForSourceNullability<DoubleType>(type);
-      default:
-        FATAL_ERROR("Unhandled type " << kTypeNames[type.getTypeID()]);
-    }
-  }
-
- private:
-  explicit NumericCastOperation(const Type &target_type)
-      : UnaryOperation(UnaryOperationID::kCast),
-        target_type_(target_type) {}
-
-  template <class SourceType>
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForSourceNullability(const Type &type) const {
-    if (type.isNullable()) {
-      return makeUncheckedUnaryOperatorHelperForTargetType<SourceType, true>();
-    } else {
-      return makeUncheckedUnaryOperatorHelperForTargetType<SourceType, false>();
-    }
-  }
-
-  template <class SourceType, bool source_nullability>
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForTargetType() const {
-    switch (target_type_.getTypeID()) {
-      case kInt:
-        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, IntType>();
-      case kLong:
-        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, LongType>();
-      case kFloat:
-        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, FloatType>();
-      case kDouble:
-        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, DoubleType>();
-      default:
-        FATAL_ERROR("Unhandled type " << kTypeNames[target_type_.getTypeID()]);
-    }
-  }
-
-  template <class SourceType, bool source_nullability, class TargetType>
-  UncheckedUnaryOperator* makeUncheckedUnaryOperatorHelperForTargetNullability() const {
-    if (target_type_.isNullable()) {
-      return new UncheckedNumericCastOperator<SourceType, source_nullability, TargetType, true>();
-    } else {
-      return new UncheckedNumericCastOperator<SourceType, source_nullability, TargetType, false>();
-    }
-  }
-
-  const Type& target_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(NumericCastOperation);
-};
-
-/** @} */
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_UNARY_OPERATIONS_NUMERIC_CAST_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/unary_operations/SubstringOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/SubstringOperation.cpp b/types/operations/unary_operations/SubstringOperation.cpp
index 84f1c8d..1cc8912 100644
--- a/types/operations/unary_operations/SubstringOperation.cpp
+++ b/types/operations/unary_operations/SubstringOperation.cpp
@@ -19,198 +19,48 @@
 
 #include "types/operations/unary_operations/SubstringOperation.hpp"
 
-#include <algorithm>
-#include <tuple>
-#include <utility>
+#include <cstddef>
 #include <vector>
 
-#include "catalog/CatalogTypedefs.hpp"
-#include "storage/ValueAccessor.hpp"
-#include "storage/ValueAccessorUtil.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
-#include "types/containers/ColumnVector.hpp"
-#include "types/containers/ColumnVectorUtil.hpp"
-#include "types/operations/Operation.pb.h"
-#include "types/port/strnlen.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Dispatchers.hpp"
 
 #include "glog/logging.h"
 
 namespace quickstep {
 
-serialization::UnaryOperation SubstringOperation::getProto() const {
-  serialization::UnaryOperation proto;
-  proto.set_operation_id(serialization::UnaryOperation::SUBSTRING);
-  proto.SetExtension(serialization::SubstringOperation::start_position,
-                     start_position_);
-  proto.SetExtension(serialization::SubstringOperation::substring_length,
-                     substring_length_);
-  return proto;
-}
+UncheckedUnaryOperator* SubstringOperation::makeUncheckedUnaryOperator(
+    const Type &type,
+    const std::vector<TypedValue> &static_arguments) const {
+  DCHECK(UnaryOperation::canApplyTo(type, static_arguments));
 
-UncheckedUnaryOperator* SubstringOperation::makeUncheckedUnaryOperatorForType(
-    const Type &type) const {
-  DCHECK(type.getSuperTypeID() == Type::kAsciiString);
+  std::size_t start_position;
+  std::size_t substring_length;
+  ExtractStaticArguments(static_arguments, &start_position, &substring_length);
 
   const std::size_t input_maximum_length =
-      static_cast<const AsciiStringSuperType&>(type).getStringLength();
+      type.getTypeID() == kChar
+          ? static_cast<const CharType&>(type).getStringLength()
+          : static_cast<const VarCharType&>(type).getStringLength();
   const bool input_null_terminated = (type.getTypeID() == TypeID::kVarChar);
 
-  const Type *result_type = resultTypeForArgumentType(type);
+  const Type *result_type = getResultType(type, static_arguments);
   DCHECK(result_type != nullptr);
 
-  return CreateBoolInstantiatedInstance<SubstringUncheckedOperator, UncheckedUnaryOperator>(
-      std::forward_as_tuple(start_position_,
-                            computeMaximumSubstringLength(type),
-                            input_maximum_length,
-                            *result_type),
-      input_null_terminated, type.isNullable());
-}
-
-template <bool null_terminated, bool input_nullable>
-inline void SubstringUncheckedOperator<null_terminated, input_nullable>
-    ::computeSubstring(const char *input,
-                       char *output) const {
-  std::size_t string_length =
-      (null_terminated ? strlen(input) : strnlen(input, maximum_input_length_));
-
-  if (start_position_ >= string_length) {
-    *output = '\0';
-    return;
-  }
-
-  const std::size_t actual_substring_length =
-      std::min(string_length - start_position_, substring_length_);
-  std::memcpy(output, input + start_position_, actual_substring_length);
-
-  if (actual_substring_length < substring_length_) {
-    output[actual_substring_length] = '\0';
-  }
-}
-
-template <bool null_terminated, bool input_nullable>
-TypedValue SubstringUncheckedOperator<null_terminated,
-                                      input_nullable>
-    ::applyToTypedValue(const TypedValue& argument) const {
-  if (input_nullable && argument.isNull()) {
-    return TypedValue(result_type_.getTypeID());
-  }
-
-  char *output_ptr = static_cast<char*>(std::malloc(substring_length_));
-  computeSubstring(static_cast<const char*>(argument.getOutOfLineData()),
-                   output_ptr);
-
-  return TypedValue::CreateWithOwnedData(result_type_.getTypeID(),
-                                         output_ptr,
-                                         substring_length_);
-}
-
-template <bool null_terminated, bool input_nullable>
-TypedValue SubstringUncheckedOperator<null_terminated,
-                                      input_nullable>
-    ::applyToDataPtr(const void *argument) const {
-  if (input_nullable && argument == nullptr) {
-    return TypedValue(result_type_.getTypeID());
-  }
-
-  char *output_ptr = static_cast<char*>(std::malloc(substring_length_));
-  computeSubstring(static_cast<const char*>(argument),
-                   output_ptr);
-
-  return TypedValue::CreateWithOwnedData(result_type_.getTypeID(),
-                                         output_ptr,
-                                         substring_length_);
-}
-
-template <bool null_terminated, bool input_nullable>
-ColumnVector* SubstringUncheckedOperator<null_terminated,
-                                         input_nullable>
-    ::applyToColumnVector(const ColumnVector &argument) const {
-  return InvokeOnColumnVector(
-      argument,
-      [&](const auto &column_vector) -> ColumnVector* {  // NOLINT(build/c++11)
-    NativeColumnVector *result =
-        new NativeColumnVector(result_type_, column_vector.size());
-
-    for (std::size_t cv_pos = 0;
-         cv_pos < column_vector.size();
-         ++cv_pos) {
-      const char *input_ptr = static_cast<const char *>(
-          column_vector.template getUntypedValue<input_nullable>(cv_pos));
-
-      if (input_nullable && input_ptr == nullptr) {
-        result->appendNullValue();
-      } else {
-        this->computeSubstring(input_ptr,
-                               static_cast<char *>(result->getPtrForDirectWrite()));
-      }
-    }
-    return result;
-  });
-}
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
-template <bool null_terminated, bool input_nullable>
-ColumnVector* SubstringUncheckedOperator<null_terminated,
-                                         input_nullable>
-    ::applyToValueAccessor(ValueAccessor *accessor,
-                           const attribute_id argument_attr_id) const {
-  return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    NativeColumnVector *result =
-        new NativeColumnVector(result_type_, accessor->getNumTuples());
-
-    accessor->beginIteration();
-    while (accessor->next()) {
-      const char *input_ptr = static_cast<const char *>(
-          accessor->template getUntypedValue<input_nullable>(argument_attr_id));
-
-      if (input_nullable && (input_ptr == nullptr)) {
-        result->appendNullValue();
-      } else {
-        this->computeSubstring(input_ptr,
-                               static_cast<char *>(result->getPtrForDirectWrite()));
-      }
-    }
-    return result;
-  });
-}
-#endif
-
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-template <bool null_terminated, bool input_nullable>
-ColumnVector* SubstringUncheckedOperator<null_terminated,
-                                         input_nullable>
-    ::applyToValueAccessorForJoin(
-        ValueAccessor *accessor,
-        const bool use_left_relation,
-        const attribute_id argument_attr_id,
-        const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids) const {
-  return InvokeOnValueAccessorNotAdapter(
-      accessor,
-      [&](auto *accessor) -> ColumnVector* {  // NOLINT(build/c++11)
-    NativeColumnVector *result =
-        new NativeColumnVector(result_type_, accessor->getNumTuples());
-
-    for (const std::pair<tuple_id, tuple_id> &joined_pair : joined_tuple_ids) {
-      const char *input_ptr = static_cast<const char *>(
-          accessor->template getUntypedValueAtAbsolutePosition<input_nullable>(
-              argument_attr_id,
-              use_left_relation ? joined_pair.first : joined_pair.second));
-
-      if (input_nullable && input_ptr == nullptr) {
-        result->appendNullValue();
-      } else {
-        this->computeSubstring(input_ptr,
-                               static_cast<char *>(result->getPtrForDirectWrite()));
-      }
-    }
-    return result;
+  return meta::InvokeOnBools(
+      input_null_terminated, type.isNullable(),
+      [&](auto is_null_terminated,  // NOLINT(build/c++11)
+          auto is_nullable) -> UncheckedUnaryOperator* {
+    return new SubstringUncheckedOperator<
+        decltype(is_null_terminated)::value,
+        decltype(is_nullable)::value>(
+            start_position,
+            ComputeMaximumSubstringLength(type, start_position, substring_length),
+            input_maximum_length,
+            *result_type);
   });
 }
-#endif
 
 }  // namespace quickstep


[32/38] incubator-quickstep git commit: More updates, refactor names

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/types/operations/utility/OperationSynthesizeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/utility/OperationSynthesizeUtil.hpp b/types/operations/utility/OperationSynthesizeUtil.hpp
new file mode 100644
index 0000000..2b910b3
--- /dev/null
+++ b/types/operations/utility/OperationSynthesizeUtil.hpp
@@ -0,0 +1,335 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
+
+#include <cstddef>
+#include <list>
+#include <string>
+#include <type_traits>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "types/Type.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename FunctorT, typename ...SpecArgs>
+struct FunctorSpecializer {
+  template <bool specialize = (sizeof...(SpecArgs) != 0),
+            typename EnableT = void>
+  struct Implementation;
+
+  typedef Implementation<> type;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool specialize>
+struct FunctorSpecializer<FunctorT, SpecArgs...>
+    ::Implementation<specialize, std::enable_if_t<specialize>> {
+  template <typename ...FuncArgs>
+  inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) {
+    return functor.template apply<SpecArgs...>(std::forward<FuncArgs>(args)...);
+  }
+  typedef FunctorT FunctorType;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool specialize>
+struct FunctorSpecializer<FunctorT, SpecArgs...>
+    ::Implementation<specialize, std::enable_if_t<!specialize>> {
+  template <typename ...FuncArgs>
+  inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) {
+    return functor.apply(std::forward<FuncArgs>(args)...);
+  }
+  typedef FunctorT FunctorType;
+};
+
+template <typename ColumnVectorT>
+struct ColumnVectorValueAccessor {
+  explicit ColumnVectorValueAccessor(const ColumnVectorT &column_vector_in)
+      : column_vector(column_vector_in),
+        length(column_vector.size()) {}
+
+  inline void beginIteration() {
+    pos = static_cast<std::size_t>(-1);
+  }
+
+  inline bool next() {
+    return (++pos) < length;
+  }
+
+  inline std::size_t getNumTuples() const {
+    return length;
+  }
+
+  template <bool nullable>
+  inline const void* getUntypedValue(const attribute_id) const {
+    return column_vector.template getUntypedValue<nullable>(pos);
+  }
+
+  inline TypedValue getTypedValue(const attribute_id) const {
+    return column_vector.getTypedValue(pos);
+  }
+
+  const ColumnVectorT &column_vector;
+  const std::size_t length;
+  std::size_t pos;
+};
+
+template <typename FuncSpec, typename T, typename EnableT = void>
+struct OperationCodegen;
+
+template <typename FuncSpec, typename T>
+struct OperationCodegen<FuncSpec, T,
+                        std::enable_if_t<T::kMemoryLayout == kCxxInlinePod>> {
+  using ColumnVectorType = NativeColumnVector;
+  using FunctorSpecializer = FuncSpec;
+
+  using NativeType = typename T::cpptype;
+  using NativeTypeConst = const typename T::cpptype;
+  using NativeTypeConstRef = const NativeType&;
+  using NativeTypeConstPtr = const NativeType*;
+
+  template <typename ArgumentGen>
+  inline static TypedValue ApplyUnaryTypedValue(
+      typename ArgumentGen::NativeTypeConstRef argument,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    return TypedValue(FuncSpec::Invoke(functor, argument));
+  }
+
+  template <typename ArgumentGen>
+  inline static void ApplyUnaryColumnVector(
+      const typename ArgumentGen::NativeTypeConstRef argument,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    *static_cast<NativeType *>(cv->getPtrForDirectWrite()) =
+        FuncSpec::Invoke(functor, argument);
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static TypedValue ApplyBinaryTypedValue(
+      typename LeftGen::NativeTypeConstRef left,
+      typename RightGen::NativeTypeConstRef right,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    return TypedValue(FuncSpec::Invoke(functor, left, right));
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static void ApplyBinaryColumnVector(
+      const typename LeftGen::NativeTypeConstRef left,
+      const typename RightGen::NativeTypeConstRef right,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    *static_cast<NativeType *>(cv->getPtrForDirectWrite()) =
+        FuncSpec::Invoke(functor, left, right);
+  }
+
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor,
+                                               const attribute_id attr_id) {
+    return static_cast<NativeTypeConstPtr>(
+        accessor->template getUntypedValue<nullable>(attr_id));
+  }
+
+  inline static bool IsNull(const NativeType *value) {
+    return value == nullptr;
+  }
+
+  // Dereference: NativeTypeConstPtr& -> const NativeType&
+  inline static const NativeType& Dereference(const NativeType *value) {
+    return *value;
+  }
+
+  inline static const NativeType ToNativeValueConst(const TypedValue &value) {
+    return value.getLiteral<NativeType>();
+  }
+};
+
+template <typename FuncSpec, typename T>
+struct OperationCodegen<FuncSpec, T,
+                        std::enable_if_t<T::kMemoryLayout == kParInlinePod>> {
+  using ColumnVectorType = NativeColumnVector;
+  using FunctorSpecializer = FuncSpec;
+
+  using NativeType = const void*;
+  using NativeTypeConst = const void*;
+  using NativeTypeConstRef = const void*;
+  using NativeTypeConstPtr = const void*;
+
+  template <typename ArgumentGen>
+  inline static TypedValue ApplyUnaryTypedValue(
+      typename ArgumentGen::NativeTypeConstRef argument,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    void *result = std::malloc(result_type.maximumByteLength());
+    FuncSpec::Invoke(functor, argument, result);
+    return TypedValue::CreateWithOwnedData(T::kStaticTypeID,
+                                           result,
+                                           result_type.maximumByteLength());
+  }
+
+  template <typename ArgumentGen>
+  inline static void ApplyUnaryColumnVector(
+      const typename ArgumentGen::NativeTypeConstRef argument,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    FuncSpec::Invoke(functor, argument, cv->getPtrForDirectWrite());
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static TypedValue ApplyBinaryTypedValue(
+      typename LeftGen::NativeTypeConstRef left,
+      typename RightGen::NativeTypeConstRef right,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    void *result = std::malloc(result_type.maximumByteLength());
+    FuncSpec::Invoke(functor, left, right, result);
+    return TypedValue::CreateWithOwnedData(T::kStaticTypeID,
+                                           result,
+                                           result_type.maximumByteLength());
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static void ApplyBinaryColumnVector(
+      const typename LeftGen::NativeTypeConstRef left,
+      const typename RightGen::NativeTypeConstRef right,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    FuncSpec::Invoke(functor, left, right, cv->getPtrForDirectWrite());
+  }
+
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor,
+                                               const attribute_id attr_id) {
+    return accessor->template getUntypedValue<nullable>(attr_id);
+  }
+
+  inline static bool IsNull(const void *value) {
+    return value == nullptr;
+  }
+
+  // Dereference: NativeTypeConstPtr& -> const NativeType&
+  inline static const void* Dereference(const void *value) {
+    return value;
+  }
+
+  inline static const void* ToNativeValueConst(const TypedValue &value) {
+    return value.getDataPtr();
+  }
+};
+
+template <typename FuncSpec, typename T>
+struct OperationCodegen<FuncSpec, T,
+                        std::enable_if_t<T::kMemoryLayout == kParOutOfLinePod>> {
+  using ColumnVectorType = IndirectColumnVector;
+  using FunctorSpecializer = FuncSpec;
+
+  using NativeType = TypedValue;
+  using NativeTypeConst = const TypedValue;
+  using NativeTypeConstRef = const TypedValue&;
+  using NativeTypeConstPtr = const TypedValue;
+
+  template <typename ArgumentGen>
+  inline static TypedValue ApplyUnaryTypedValue(
+      typename ArgumentGen::NativeTypeConstRef argument,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    return FuncSpec::Invoke(functor, argument);
+  }
+
+  template <typename ArgumentGen>
+  inline static void ApplyUnaryColumnVector(
+      const typename ArgumentGen::NativeTypeConstRef argument,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    cv->appendTypedValue(FuncSpec::Invoke(functor, argument));
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static TypedValue ApplyBinaryTypedValue(
+      typename LeftGen::NativeTypeConstRef left,
+      typename RightGen::NativeTypeConstRef right,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    return FuncSpec::Invoke(functor, left, right);
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static void ApplyBinaryColumnVector(
+      const typename LeftGen::NativeTypeConstRef left,
+      const typename RightGen::NativeTypeConstRef right,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    cv->appendTypedValue(FuncSpec::Invoke(functor, left, right));
+  }
+
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(
+      const AccessorT *accessor,
+      const attribute_id attr_id) {
+    return accessor->getTypedValue(attr_id);
+  }
+
+  inline static bool IsNull(NativeTypeConstPtr &value) {
+    return value.isNull();
+  }
+
+  // Dereference: NativeTypeConstPtr& -> const NativeType&
+  inline static const NativeType& Dereference(NativeTypeConstPtr &value) {
+    return value;
+  }
+
+  inline static const NativeType& ToNativeValueConst(const TypedValue &value) {
+    return value;
+  }
+};
+
+template <typename ...FunctorTypes>
+struct FunctorPack {
+  template <typename Dispatcher>
+  inline static std::list<OperationPtr> GenerateOperations() {
+    std::vector<std::list<OperationPtr>> op_list_groups =
+        { Dispatcher::template Generate<FunctorTypes>()... };
+
+    std::list<OperationPtr> operations;
+    for (std::list<OperationPtr> &op_list : op_list_groups) {
+      operations.splice(operations.end(), std::move(op_list));
+    }
+    return operations;
+  }
+};
+
+struct OperationPack {
+  virtual std::vector<OperationPtr> generateOperations() = 0;
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/utility/meta/Common.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp
index 901b65c..cbad665 100644
--- a/utility/meta/Common.hpp
+++ b/utility/meta/Common.hpp
@@ -23,7 +23,7 @@
 namespace quickstep {
 namespace meta {
 
-/** \addtogroup Utility
+/** \addtogroup Meta
  *  @{
  */
 
@@ -99,6 +99,19 @@ struct IsWellFormed<T, Op, std::enable_if_t<std::is_same<Op<T>, Op<T>>::value>>
 };
 
 
+namespace internal {
+
+template <typename T, std::size_t = sizeof(T)>
+std::true_type IsCompleteTypeImpl(T *);
+
+std::false_type IsCompleteTypeImpl(...);
+
+}  // namespace internal
+
+template <typename T>
+using IsCompleteType = decltype(internal::IsCompleteTypeImpl(std::declval<T*>()));
+
+
 template <typename LeftT, typename RightT>
 struct PairSelectorLeft {
   typedef LeftT type;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/utility/meta/Dispatchers.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Dispatchers.hpp b/utility/meta/Dispatchers.hpp
index 5b0ee48..1624bea 100644
--- a/utility/meta/Dispatchers.hpp
+++ b/utility/meta/Dispatchers.hpp
@@ -25,7 +25,7 @@
 namespace quickstep {
 namespace meta {
 
-/** \addtogroup Utility
+/** \addtogroup Meta
  *  @{
  */
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/utility/meta/MetaprogrammingModule.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/MetaprogrammingModule.hpp b/utility/meta/MetaprogrammingModule.hpp
new file mode 100644
index 0000000..912fdef
--- /dev/null
+++ b/utility/meta/MetaprogrammingModule.hpp
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ **/
+
+/** @defgroup Meta
+ *  @ingroup Utility
+ *
+ * Template metaprogramming utilities.
+ **/

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/utility/meta/TransitiveClosure.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TransitiveClosure.hpp b/utility/meta/TransitiveClosure.hpp
index a5362bb..d5bb0ca 100644
--- a/utility/meta/TransitiveClosure.hpp
+++ b/utility/meta/TransitiveClosure.hpp
@@ -25,7 +25,7 @@
 namespace quickstep {
 namespace meta {
 
-/** \addtogroup Utility
+/** \addtogroup Meta
  *  @{
  */
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/utility/meta/TypeList.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeList.hpp b/utility/meta/TypeList.hpp
index fac3ce5..5f4c4d9 100644
--- a/utility/meta/TypeList.hpp
+++ b/utility/meta/TypeList.hpp
@@ -26,15 +26,19 @@
 namespace quickstep {
 namespace meta {
 
-/** \addtogroup Utility
+/** \addtogroup Meta
  *  @{
  */
 
 template <typename ...Ts>
 class TypeList;
 
+namespace internal {
+
+using EmptyList = TypeList<>;
+
 template <typename ...Ts>
-class TypeListCommon {
+class TypeListBase {
  private:
   template <typename ...Tail> struct AppendHelper {
     using type = TypeList<Ts..., Tail...>;
@@ -44,13 +48,20 @@ class TypeListCommon {
   static constexpr std::size_t length = sizeof...(Ts);
 
   using type = TypeList<Ts...>;
+  using self = type;
 
   template <template <typename ...> class Host>
   using bind_to = Host<Ts...>;
 
   template <std::size_t ...pos>
-  using at = typename internal::ElementAtImpl<
-      TypeList<Ts...>, TypeList<std::integral_constant<std::size_t, pos>...>>::type;
+  using at = typename ElementAtImpl<
+      self, TypeList<std::integral_constant<std::size_t, pos>...>>::type;
+
+  template <std::size_t n>
+  using take = typename TakeImpl<self, EmptyList, n>::type;
+
+  template <std::size_t n>
+  using skip = typename SkipImpl<self, n>::type;
 
   template <typename T>
   using push_front = TypeList<T, Ts...>;
@@ -62,59 +73,59 @@ class TypeListCommon {
   using contains = EqualsAny<T, Ts...>;
 
   template <typename ...DumbT>
-  using unique = typename internal::UniqueImpl<TypeList<>, TypeList<Ts...>, DumbT...>::type;
+  using unique = typename UniqueImpl<EmptyList, self, DumbT...>::type;
 
   template <typename TL>
   using append = typename TL::template bind_to<AppendHelper>::type;
 
   template <typename TL>
-  using cartesian_product = typename internal::CartesianProductImpl<TypeList<Ts...>, TL>::type;
+  using cartesian_product = typename CartesianProductImpl<self, TL>::type;
 
   template <typename Subtrahend>
-  using subtract = typename internal::SubtractImpl<TypeList<>, TypeList<Ts...>, Subtrahend>::type;
+  using subtract = typename SubtractImpl<EmptyList, self, Subtrahend>::type;
 
   template <template <typename ...> class Op>
   using map = TypeList<typename Op<Ts>::type...>;
 
   template <template <typename ...> class Op>
-  using flatmap = typename internal::FlatmapImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+  using flatmap = typename FlatmapImpl<EmptyList, self, Op>::type;
 
   template <template <typename ...> class Op>
-  using filter = typename internal::FilterImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+  using filter = typename FilterImpl<EmptyList, self, Op>::type;
 
   template <template <typename ...> class Op>
-  using filtermap = typename internal::FiltermapImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+  using filtermap = typename FiltermapImpl<EmptyList, self, Op>::type;
+
+  template <typename ...DumbT>
+  using flatten = typename FlattenImpl<EmptyList, self, DumbT...>::type;
 
   template <typename ...DumbT>
-  using flatten_once = typename internal::FlattenOnceImpl<TypeList<>, TypeList<Ts...>, DumbT...>::type;
+  using flatten_once = typename FlattenOnceImpl<EmptyList, self, DumbT...>::type;
+
+  template <template <typename ...> class Op, typename InitT>
+  using foldl = typename FoldlImpl<InitT, self, Op>::type;
 
   template <typename TL>
-  using zip = typename internal::ZipImpl<TypeList<>, TypeList<Ts...>, TL>::type;
+  using zip = typename ZipImpl<EmptyList, self, TL>::type;
 
   template <typename TL, template <typename ...> class Op>
-  using zip_with = typename internal::ZipWithImpl<TypeList<>, TypeList<Ts...>, TL, Op>::type;
+  using zip_with = typename ZipWithImpl<EmptyList, self, TL, Op>::type;
 
   template <typename T>
-  using as_sequence = typename internal::AsSequenceImpl<T, Ts...>::type;
+  using as_sequence = typename AsSequenceImpl<T, Ts...>::type;
 };
 
-template <typename ...Ts>
-class TypeList : public TypeListCommon<Ts...> {
- private:
-  template <typename Head, typename ...Tail>
-  struct HeadTailHelper {
-    using head = Head;
-    using tail = TypeList<Tail...>;
-  };
+}  // namespace internal
 
+template <typename T, typename ...Ts>
+class TypeList<T, Ts...> : public internal::TypeListBase<T, Ts...> {
  public:
-  using head = typename HeadTailHelper<Ts...>::head;
-  using tail = typename HeadTailHelper<Ts...>::tail;
+  using head = T;
+  using tail = TypeList<Ts...>;
 };
 
 template <>
-class TypeList<> : public TypeListCommon<> {
-};
+class TypeList<> : public internal::TypeListBase<> {};
 
 /** @} */
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/f9e32e6a/utility/meta/TypeListMetaFunctions.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeListMetaFunctions.hpp b/utility/meta/TypeListMetaFunctions.hpp
index d908493..baebe91 100644
--- a/utility/meta/TypeListMetaFunctions.hpp
+++ b/utility/meta/TypeListMetaFunctions.hpp
@@ -25,13 +25,24 @@
 namespace quickstep {
 namespace meta {
 
-/** \addtogroup Utility
+/** \addtogroup Meta
  *  @{
  */
 
 template <typename ...Ts>
 class TypeList;
 
+
+template <typename T>
+struct IsTypeList {
+  constexpr static bool value = false;
+};
+template <typename ...Ts>
+struct IsTypeList<TypeList<Ts...>> {
+  constexpr static bool value = true;
+};
+
+
 namespace internal {
 
 template <typename TL, typename PosTL, typename Enable = void>
@@ -52,6 +63,34 @@ struct ElementAtImpl<TL, PosTL,
                     typename PosTL::tail> {};
 
 
+template <typename TL, typename Out, std::size_t rest, typename Enable = void>
+struct TakeImpl;
+
+template <typename TL, typename Out, std::size_t rest>
+struct TakeImpl<TL, Out, rest, std::enable_if_t<rest == 0>> {
+  using type = Out;
+};
+
+template <typename TL, typename Out, std::size_t rest>
+struct TakeImpl<TL, Out, rest, std::enable_if_t<rest != 0>>
+    : TakeImpl<typename TL::tail,
+               typename Out::template push_back<typename TL::head>,
+               rest - 1> {};
+
+
+template <typename TL, std::size_t rest, typename Enable = void>
+struct SkipImpl;
+
+template <typename TL, std::size_t rest>
+struct SkipImpl<TL, rest, std::enable_if_t<rest == 0>> {
+  using type = TL;
+};
+
+template <typename TL, std::size_t rest>
+struct SkipImpl<TL, rest, std::enable_if_t<rest != 0>>
+    : SkipImpl<typename TL::tail, rest - 1> {};
+
+
 template <typename Out, typename Rest, typename Enable = void>
 struct UniqueImpl;
 
@@ -174,6 +213,30 @@ struct FiltermapImpl<Out, Rest, Op,
 
 
 template <typename Out, typename Rest, typename Enable = void>
+struct FlattenImpl;
+
+template <typename Out, typename Rest>
+struct FlattenImpl<Out, Rest,
+                   std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest>
+struct FlattenImpl<Out, Rest,
+                   std::enable_if_t<Rest::length != 0 &&
+                                    IsTypeList<typename Rest::head>::value>>
+    : FlattenImpl<typename Out::template append<typename Rest::head::template flatten<>>,
+                  typename Rest::tail> {};
+
+template <typename Out, typename Rest>
+struct FlattenImpl<Out, Rest,
+                   std::enable_if_t<Rest::length != 0 &&
+                                    !IsTypeList<typename Rest::head>::value>>
+    : FlattenImpl<typename Out::template push_back<typename Rest::head>,
+                  typename Rest::tail> {};
+
+
+template <typename Out, typename Rest, typename Enable = void>
 struct FlattenOnceImpl;
 
 template <typename Out, typename Rest>
@@ -188,6 +251,21 @@ struct FlattenOnceImpl<Out, Rest,
     : FlattenOnceImpl<typename Out::template append<typename Rest::head>,
                       typename Rest::tail> {};
 
+template <typename Out, typename Rest, template <typename ...> class Op,
+          typename Enable = void>
+struct FoldlImpl;
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FoldlImpl<Out, Rest, Op,
+                 std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FoldlImpl<Out, Rest, Op,
+                 std::enable_if_t<Rest::length != 0>>
+    : FoldlImpl<typename Op<Out, typename Rest::head>::type,
+                typename Rest::tail, Op> {};
 
 template <typename Out, typename RestL, typename RestR, typename Enable = void>
 struct ZipImpl;


[19/38] incubator-quickstep git commit: Some updates

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index ff73cc7..035e325 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -98,88 +98,89 @@ extern int quickstep_yydebug;
     TOKEN_DESC = 308,
     TOKEN_DISTINCT = 309,
     TOKEN_DOUBLE = 310,
-    TOKEN_DROP = 311,
-    TOKEN_ELSE = 312,
-    TOKEN_END = 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_STDERR = 369,
-    TOKEN_STDOUT = 370,
-    TOKEN_SUBSTRING = 371,
-    TOKEN_TABLE = 372,
-    TOKEN_THEN = 373,
-    TOKEN_TIME = 374,
-    TOKEN_TIMESTAMP = 375,
-    TOKEN_TO = 376,
-    TOKEN_TRUE = 377,
-    TOKEN_TUPLESAMPLE = 378,
-    TOKEN_UNBOUNDED = 379,
-    TOKEN_UNIQUE = 380,
-    TOKEN_UPDATE = 381,
-    TOKEN_USING = 382,
-    TOKEN_VALUES = 383,
-    TOKEN_VARCHAR = 384,
-    TOKEN_WHEN = 385,
-    TOKEN_WHERE = 386,
-    TOKEN_WINDOW = 387,
-    TOKEN_WITH = 388,
-    TOKEN_YEAR = 389,
-    TOKEN_YEARMONTH = 390,
-    TOKEN_EOF = 391,
-    TOKEN_LEX_ERROR = 392
+    TOKEN_DOUBLECOLON = 311,
+    TOKEN_DROP = 312,
+    TOKEN_ELSE = 313,
+    TOKEN_END = 314,
+    TOKEN_EXISTS = 315,
+    TOKEN_EXTRACT = 316,
+    TOKEN_FALSE = 317,
+    TOKEN_FIRST = 318,
+    TOKEN_FLOAT = 319,
+    TOKEN_FOLLOWING = 320,
+    TOKEN_FOR = 321,
+    TOKEN_FOREIGN = 322,
+    TOKEN_FROM = 323,
+    TOKEN_FULL = 324,
+    TOKEN_GROUP = 325,
+    TOKEN_HASH = 326,
+    TOKEN_HAVING = 327,
+    TOKEN_HOUR = 328,
+    TOKEN_IN = 329,
+    TOKEN_INDEX = 330,
+    TOKEN_INNER = 331,
+    TOKEN_INSERT = 332,
+    TOKEN_INTEGER = 333,
+    TOKEN_INTERVAL = 334,
+    TOKEN_INTO = 335,
+    TOKEN_JOIN = 336,
+    TOKEN_KEY = 337,
+    TOKEN_LAST = 338,
+    TOKEN_LEFT = 339,
+    TOKEN_LIMIT = 340,
+    TOKEN_LONG = 341,
+    TOKEN_MINUTE = 342,
+    TOKEN_MONTH = 343,
+    TOKEN_NULL = 344,
+    TOKEN_NULLS = 345,
+    TOKEN_OFF = 346,
+    TOKEN_ON = 347,
+    TOKEN_ORDER = 348,
+    TOKEN_OUTER = 349,
+    TOKEN_OVER = 350,
+    TOKEN_PARTITION = 351,
+    TOKEN_PARTITIONS = 352,
+    TOKEN_PERCENT = 353,
+    TOKEN_PRECEDING = 354,
+    TOKEN_PRIMARY = 355,
+    TOKEN_PRIORITY = 356,
+    TOKEN_QUIT = 357,
+    TOKEN_RANGE = 358,
+    TOKEN_REAL = 359,
+    TOKEN_REFERENCES = 360,
+    TOKEN_RIGHT = 361,
+    TOKEN_ROW = 362,
+    TOKEN_ROW_DELIMITER = 363,
+    TOKEN_ROWS = 364,
+    TOKEN_SECOND = 365,
+    TOKEN_SELECT = 366,
+    TOKEN_SET = 367,
+    TOKEN_SMA = 368,
+    TOKEN_SMALLINT = 369,
+    TOKEN_STDERR = 370,
+    TOKEN_STDOUT = 371,
+    TOKEN_SUBSTRING = 372,
+    TOKEN_TABLE = 373,
+    TOKEN_THEN = 374,
+    TOKEN_TIME = 375,
+    TOKEN_TIMESTAMP = 376,
+    TOKEN_TO = 377,
+    TOKEN_TRUE = 378,
+    TOKEN_TUPLESAMPLE = 379,
+    TOKEN_UNBOUNDED = 380,
+    TOKEN_UNIQUE = 381,
+    TOKEN_UPDATE = 382,
+    TOKEN_USING = 383,
+    TOKEN_VALUES = 384,
+    TOKEN_VARCHAR = 385,
+    TOKEN_WHEN = 386,
+    TOKEN_WHERE = 387,
+    TOKEN_WINDOW = 388,
+    TOKEN_WITH = 389,
+    TOKEN_YEAR = 390,
+    TOKEN_YEARMONTH = 391,
+    TOKEN_EOF = 392,
+    TOKEN_LEX_ERROR = 393
   };
 #endif
 
@@ -289,7 +290,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 293 "SqlParser_gen.hpp" /* yacc.c:1915  */
+#line 294 "SqlParser_gen.hpp" /* yacc.c:1915  */
 };
 
 typedef union YYSTYPE YYSTYPE;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/query_optimizer/rules/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/CMakeLists.txt b/query_optimizer/rules/CMakeLists.txt
index f578bb8..b7f384c 100644
--- a/query_optimizer/rules/CMakeLists.txt
+++ b/query_optimizer/rules/CMakeLists.txt
@@ -186,9 +186,9 @@ target_link_libraries(quickstep_queryoptimizer_rules_Partition
                       quickstep_queryoptimizer_physical_TableReference
                       quickstep_queryoptimizer_physical_TopLevelPlan
                       quickstep_queryoptimizer_rules_BottomUpRule
+                      quickstep_types_operations_OperationFactory
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Cast
                       quickstep_utility_EqualsAnyConstant
                       quickstep_utility_Macros

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/query_optimizer/rules/Partition.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/Partition.cpp b/query_optimizer/rules/Partition.cpp
index 5f68cd3..d55d296 100644
--- a/query_optimizer/rules/Partition.cpp
+++ b/query_optimizer/rules/Partition.cpp
@@ -49,9 +49,8 @@
 #include "query_optimizer/physical/Sort.hpp"
 #include "query_optimizer/physical/TableReference.hpp"
 #include "query_optimizer/physical/TopLevelPlan.hpp"
+#include "types/operations/OperationFactory.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "utility/Cast.hpp"
 #include "utility/EqualsAnyConstant.hpp"
 
@@ -410,10 +409,17 @@ P::PhysicalPtr Partition::applyToNode(const P::PhysicalPtr &node) {
       for (const auto &avg_recompute_expression : avg_recompute_expressions) {
         const auto &avg_expr = get<0>(avg_recompute_expression);
         // Obtain AVG by evaluating SUM/COUNT in Selection.
-        const BinaryOperation &divide_op =
-            BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide);
+        const OperationSignaturePtr op_sig =
+            OperationSignature::Create(
+                "+",
+                { get<1>(avg_recompute_expression)->getValueType().getTypeID(),
+                  get<2>(avg_recompute_expression)->getValueType().getTypeID() },
+                0);
+        const BinaryOperationPtr divide_op =
+            OperationFactory::Instance().getBinaryOperation(op_sig);
         const E::BinaryExpressionPtr new_avg_expr =
-            E::BinaryExpression::Create(divide_op,
+            E::BinaryExpression::Create(op_sig,
+                                        divide_op,
                                         get<1>(avg_recompute_expression),
                                         get<2>(avg_recompute_expression));
         project_expressions.emplace_back(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index df4462f..325c6ea 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -47,6 +47,7 @@ add_library(quickstep_types_IntervalLit ../empty_src.cpp IntervalLit.hpp)
 add_library(quickstep_types_IntervalParser IntervalParser.cpp IntervalParser.hpp)
 add_library(quickstep_types_LongType LongType.cpp LongType.hpp)
 add_library(quickstep_types_NullCoercibilityCheckMacro ../empty_src.cpp NullCoercibilityCheckMacro.hpp)
+add_library(quickstep_types_NullLit ../empty_src.cpp NullLit.hpp)
 add_library(quickstep_types_NullType ../empty_src.cpp NullType.hpp)
 add_library(quickstep_types_NumericSuperType ../empty_src.cpp NumericSuperType.hpp)
 add_library(quickstep_types_NumericTypeSafeCoercibility ../empty_src.cpp NumericTypeSafeCoercibility.hpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/NullLit.hpp
----------------------------------------------------------------------
diff --git a/types/NullLit.hpp b/types/NullLit.hpp
new file mode 100644
index 0000000..8713c72
--- /dev/null
+++ b/types/NullLit.hpp
@@ -0,0 +1,38 @@
+/**
+ * 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_NULL_LIT_HPP_
+#define QUICKSTEP_TYPES_NULL_LIT_HPP_
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief An empty struct representing the null value.
+ **/
+struct NullLit {};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_NULL_LIT_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index c416a05..7491ca7 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -88,7 +88,7 @@ class NullType : public TypeSynthesizer<kNullType> {
   // NOTE(chasseur): NullType requires 0 bytes of inherent storage. It does,
   // however, require a bit in NULL bitmaps.
   NullType(const bool nullable)
-      : TypeSynthesizer<kNullType>(nullable, 0, 0) {
+      : TypeSynthesizer<kNullType>(nullable) {
     DCHECK(nullable);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index 66efc92..223d487 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -33,7 +33,7 @@
 namespace quickstep {
 
 bool TypeFactory::TypeRequiresLengthParameter(const TypeID id) {
-  return TypeUtil::IsParameterized(id);
+  return TypeUtil::IsParameterizedPod(id);
 }
 
 const Type& TypeFactory::GetType(const TypeID id,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/TypeID.hpp
----------------------------------------------------------------------
diff --git a/types/TypeID.hpp b/types/TypeID.hpp
index d27368c..ecbdc9b 100644
--- a/types/TypeID.hpp
+++ b/types/TypeID.hpp
@@ -49,11 +49,11 @@ enum TypeID : int {
   kNumTypeIDs  // Not a real TypeID, exists for counting purposes.
 };
 
-enum TypeStorageLayout {
-  kNativeEmbedded,
-  kNativeInline,
-  kNonNativeInline,
-  kOutOfLine
+enum MemoryLayout {
+  kCxxNativePod,
+  kParNativePod,
+  kParIndirectPod,
+  kGeneric
 };
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
index f4c9fb9..ffe2b7e 100644
--- a/types/TypeRegistrar.hpp
+++ b/types/TypeRegistrar.hpp
@@ -25,6 +25,7 @@
 
 #include "types/DatetimeLit.hpp"
 #include "types/IntervalLit.hpp"
+#include "types/NullLit.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypeIDSelectors.hpp"
@@ -41,41 +42,42 @@ namespace quickstep {
 template <TypeID type_id>
 struct TypeIDTrait;
 
-#define REGISTER_TYPE(T, type_id, super_type_id, parameterized, layout, CppType) \
-  class T; \
+#define REGISTER_TYPE(type_class, type_id, super_type_id, memory_layout, cpp_type) \
+  class type_class; \
   template <> struct TypeIDTrait<type_id> { \
-    typedef T TypeClass; \
-    typedef CppType cpptype; \
+    typedef type_class TypeClass; \
+    typedef cpp_type 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; \
+    static constexpr MemoryLayout kMemoryLayout = memory_layout; \
+    static constexpr bool kIsParameterizedPod = \
+        (memory_layout == kParNativePod || memory_layout == kParIndirectPod); \
   };
 
 REGISTER_TYPE(BoolType, kBool, \
-              Type::kNumeric, false, kNativeEmbedded, bool);
+              Type::kNumeric, kCxxNativePod, bool);
 REGISTER_TYPE(IntType, kInt, \
-              Type::kNumeric, false, kNativeEmbedded, int);
+              Type::kNumeric, kCxxNativePod, int);
 REGISTER_TYPE(LongType, kLong, \
-              Type::kNumeric, false, kNativeEmbedded, std::int64_t);
+              Type::kNumeric, kCxxNativePod, std::int64_t);
 REGISTER_TYPE(FloatType, kFloat, \
-              Type::kNumeric, false, kNativeEmbedded, float);
+              Type::kNumeric, kCxxNativePod, float);
 REGISTER_TYPE(DoubleType, kDouble, \
-              Type::kNumeric, false, kNativeEmbedded, double);
+              Type::kNumeric, kCxxNativePod, double);
 REGISTER_TYPE(DateType, kDate, \
-              Type::kOther, false, kNativeEmbedded, DateLit);
+              Type::kOther, kCxxNativePod, DateLit);
 REGISTER_TYPE(DatetimeType, kDatetime, \
-              Type::kOther, false, kNativeEmbedded, DatetimeLit);
+              Type::kOther, kCxxNativePod, DatetimeLit);
 REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval, \
-              Type::kOther, false, kNativeEmbedded, DatetimeIntervalLit);
+              Type::kOther, kCxxNativePod, DatetimeIntervalLit);
 REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval, \
-              Type::kOther, false, kNativeEmbedded, YearMonthIntervalLit);
+              Type::kOther, kCxxNativePod, YearMonthIntervalLit);
 REGISTER_TYPE(CharType, kChar, \
-              Type::kAsciiString, true, kNonNativeInline, void);
+              Type::kAsciiString, kParNativePod, void);
 REGISTER_TYPE(VarCharType, kVarChar, \
-              Type::kAsciiString, true, kOutOfLine, void);
+              Type::kAsciiString, kParIndirectPod, void);
 REGISTER_TYPE(NullType, kNullType, \
-              Type::kOther, false, kNonNativeInline, void);
+              Type::kOther, kCxxNativePod, NullLit);
 
 #undef REGISTER_TYPE
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
index 27ba02a..16d59c9 100644
--- a/types/TypeSynthesizer.hpp
+++ b/types/TypeSynthesizer.hpp
@@ -46,15 +46,15 @@ template <TypeID type_id>
 class TypeSynthesizer
     : public Type,
       public TypeInstance<typename TypeIDTrait<type_id>::TypeClass,
-                          TypeIDTrait<type_id>::kParameterized> {
+                          TypeIDTrait<type_id>::kIsParameterizedPod> {
  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;
+  static constexpr bool kIsParameterizedPod = Trait::kIsParameterizedPod;
+  static constexpr MemoryLayout kMemoryLayout = Trait::kMemoryLayout;
 
   typedef typename Trait::cpptype cpptype;
 
@@ -64,7 +64,7 @@ class TypeSynthesizer
     proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
     proto.set_nullable(nullable_);
 
-    if (kParameterized) {
+    if (kIsParameterizedPod) {
       proto.set_length(parameter_);
     }
 
@@ -72,62 +72,45 @@ class TypeSynthesizer
   }
 
   const Type& getNullableVersion() const override {
-    return getInstance<kParameterized>(true);
+    return getInstance<kIsParameterizedPod>(true);
   }
 
   const Type& getNonNullableVersion() const override {
-    return getInstance<kParameterized>(false);
+    return getInstance<kIsParameterizedPod>(false);
   }
 
  protected:
-  template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+  template <MemoryLayout layout = kMemoryLayout, bool par = kIsParameterizedPod>
   explicit TypeSynthesizer(const bool nullable,
-                           std::enable_if_t<layout == kNativeEmbedded ||
-                                            layout == kNativeInline>* = 0)
+                           std::enable_if_t<layout == kCxxNativePod>* = 0)
       : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
              sizeof(cpptype), sizeof(cpptype)) {
-    DCHECK(!kParameterized);
   }
 
-  template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+  template <MemoryLayout layout = kMemoryLayout, bool par = kIsParameterizedPod>
   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)
+                  std::enable_if_t<par>* = 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);
+    return TypeInstance<TypeClass, kIsParameterizedPod>::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);
+    return TypeInstance<TypeClass, kIsParameterizedPod>::Instance(nullable);
   }
 
-  friend class TypeInstance<TypeClass, kParameterized>;
+  friend class TypeInstance<TypeClass, kIsParameterizedPod>;
 
   DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
 };
@@ -139,10 +122,10 @@ template <TypeID type_id>
 constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
 
 template <TypeID type_id>
-constexpr bool TypeSynthesizer<type_id>::kParameterized;
+constexpr bool TypeSynthesizer<type_id>::kIsParameterizedPod;
 
 template <TypeID type_id>
-constexpr TypeStorageLayout TypeSynthesizer<type_id>::kLayout;
+constexpr MemoryLayout TypeSynthesizer<type_id>::kMemoryLayout;
 
 
 template <typename TypeClass>

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
index b146f02..5a55280 100644
--- a/types/TypeUtil.hpp
+++ b/types/TypeUtil.hpp
@@ -49,11 +49,11 @@ namespace quickstep {
 
 class TypeUtil {
  public:
-  static bool IsParameterized(const TypeID type_id) {
+  static bool IsParameterizedPod(const TypeID type_id) {
     return InvokeOnTypeID(
         type_id,
         [&](auto tid) -> bool {  // NOLINT(build/c++11)
-      return TypeIDTrait<decltype(tid)::value>::kParameterized;
+      return TypeIDTrait<decltype(tid)::value>::kIsParameterizedPod;
     });
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/containers/ColumnVector.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp
index 0d6447d..a312ee2 100644
--- a/types/containers/ColumnVector.hpp
+++ b/types/containers/ColumnVector.hpp
@@ -70,13 +70,25 @@ typedef std::shared_ptr<const ColumnVector> ColumnVectorPtr;
  **/
 class ColumnVector {
  public:
+   /**
+    * @brief Enum with cases for different subclasses of ColumnVector.
+    */
+   enum Implementation {
+     kNative = 0,
+     kIndirect,
+     kGeneric
+   };
+
   /**
    * @brief Constructor.
    *
    * @param type The Type of values to hold.
    **/
-  explicit ColumnVector(const Type &type)
-      : type_(type) {
+  explicit ColumnVector(const Implementation implementation,
+                        const Type &type)
+      : implementation_(implementation),
+        type_(type) {
+    // TODO: check that impl matches type.
   }
 
   /**
@@ -101,14 +113,27 @@ class ColumnVector {
       const TypedValue &value,
       const std::size_t num_copies);
 
+
   /**
-   * @brief Check whether this ColumnVector is a NativeColumnVector or an
-   *        IndirectColumnVector.
+   * @brief Determine the concrete type of this ColumnVector.
    *
-   * @return true if this is a NativeColumnVector, false if this is an
-   *         IndirectColumnVector.
+   * @return The implementation type of this ColumnVector.
    **/
-  virtual bool isNative() const = 0;
+  inline Implementation getImplementation() const {
+    return implementation_;
+  }
+
+  inline bool isNative() const {
+    return implementation_ == kNative;
+  }
+
+  inline bool isIndrect() const {
+    return implementation_ == kIndirect;
+  }
+
+  inline bool isGeneric() const {
+    return implementation_ == kGeneric;
+  }
 
   /**
    * @brief Get the number of values in this ColumnVector.
@@ -118,6 +143,7 @@ class ColumnVector {
   virtual std::size_t size() const = 0;
 
  protected:
+  const Implementation implementation_;
   const Type &type_;
 
  private:
@@ -140,7 +166,7 @@ class NativeColumnVector : public ColumnVector {
    *        NativeColumnVector will hold.
    **/
   NativeColumnVector(const Type &type, const std::size_t reserved_length)
-      : ColumnVector(type),
+      : ColumnVector(ColumnVector::kNative, type),
         type_length_(type.maximumByteLength()),
         reserved_length_(reserved_length),
         values_(std::malloc(type.maximumByteLength() * reserved_length)),
@@ -170,10 +196,6 @@ class NativeColumnVector : public ColumnVector {
     return !type.isVariableLength();
   }
 
-  bool isNative() const override {
-    return true;
-  }
-
   /**
    * @brief Determine if this NativeColumnVector's Type is nullable.
    *
@@ -421,7 +443,7 @@ class IndirectColumnVector : public ColumnVector {
    * @param reserved_length The number of values to reserve space for.
    **/
   IndirectColumnVector(const Type &type, const std::size_t reserved_length)
-      : ColumnVector(type),
+      : ColumnVector(ColumnVector::kIndirect, type),
         type_is_nullable_(type.isNullable()),
         reserved_length_(reserved_length) {
     values_.reserve(reserved_length);
@@ -433,10 +455,6 @@ class IndirectColumnVector : public ColumnVector {
   ~IndirectColumnVector() override {
   }
 
-  bool isNative() const override {
-    return false;
-  }
-
   /**
    * @brief Determine if this IndirectColumnVector's Type is nullable.
    *
@@ -590,6 +608,11 @@ class IndirectColumnVector : public ColumnVector {
   DISALLOW_COPY_AND_ASSIGN(IndirectColumnVector);
 };
 
+class GenericColumnVector {
+
+
+};
+
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/containers/ColumnVectorsValueAccessor.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVectorsValueAccessor.hpp b/types/containers/ColumnVectorsValueAccessor.hpp
index ebd46d4..0ea6d50 100644
--- a/types/containers/ColumnVectorsValueAccessor.hpp
+++ b/types/containers/ColumnVectorsValueAccessor.hpp
@@ -73,10 +73,11 @@ class ColumnVectorsValueAccessor : public ValueAccessor {
    *             this value-accessor is responsible for freeing this column
    *             vector.
    **/
-  void addColumn(ColumnVectorPtr column) {
+  void addColumn(const ColumnVectorPtr &column) {
     // If this is not the first column to be added, make sure it is the same
     // length as the others.
     DCHECK(columns_.empty() || column->size() == column_length_);
+    DCHECK(column->isNative() || column->isIndrect());
     columns_.push_back(column);
     column_native_.push_back(column->isNative());
     column_length_ = column->size();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/operations/OperationUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationUtil.hpp b/types/operations/OperationUtil.hpp
index 076dc0c..8290061 100644
--- a/types/operations/OperationUtil.hpp
+++ b/types/operations/OperationUtil.hpp
@@ -103,7 +103,7 @@ template <typename FuncSpec, typename T, typename EnableT = void>
 struct Codegen;
 
 template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kNativeEmbedded>> {
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kCxxNativePod>> {
   using ColumnVectorType = NativeColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -171,7 +171,7 @@ struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kNativeEmbedded>> {
 };
 
 template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kNonNativeInline>> {
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParNativePod>> {
   using ColumnVectorType = NativeColumnVector;
   using FunctorSpecializer = FuncSpec;
 
@@ -244,7 +244,7 @@ struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kNonNativeInline>> {
 };
 
 template <typename FuncSpec, typename T>
-struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kOutOfLine>> {
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kMemoryLayout == kParIndirectPod>> {
   using ColumnVectorType = IndirectColumnVector;
   using FunctorSpecializer = FuncSpec;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/operations/binary_operations/BinaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationWrapper.hpp b/types/operations/binary_operations/BinaryOperationWrapper.hpp
index 98c2e8d..d819000 100644
--- a/types/operations/binary_operations/BinaryOperationWrapper.hpp
+++ b/types/operations/binary_operations/BinaryOperationWrapper.hpp
@@ -195,7 +195,7 @@ class UncheckedBinaryOperatorWrapperCodegen : public UncheckedBinaryOperator {
       std::size_t *num_tuples_applied) const override {
     constexpr bool is_supported =
         LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
-        (LeftType::kLayout == kNativeEmbedded || LeftType::kLayout == kNativeInline) &&
+        LeftType::kMemoryLayout == kCxxNativePod &&
         std::is_copy_assignable<typename LeftType::cpptype>::value;
 
     using RightCVT = typename RightGen::ColumnVectorType;
@@ -217,7 +217,7 @@ class UncheckedBinaryOperatorWrapperCodegen : public UncheckedBinaryOperator {
       std::size_t *num_tuples_applied) const override {
     constexpr bool is_supported =
         LeftType::kStaticTypeID == ResultType::kStaticTypeID &&
-        (LeftType::kLayout == kNativeEmbedded || LeftType::kLayout == kNativeInline) &&
+        LeftType::kMemoryLayout == kCxxNativePod &&
         std::is_copy_assignable<typename LeftType::cpptype>::value;
 
     return InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
@@ -511,7 +511,7 @@ class BinaryOperationWrapper : public BinaryOperation {
     DCHECK(left.getTypeID() == LeftType::kStaticTypeID);
     DCHECK(right.getTypeID() == RightType::kStaticTypeID);
     DCHECK(static_arguments.empty());
-    return getResultTypeImpl<ResultType::kParameterized>(
+    return getResultTypeImpl<ResultType::kIsParameterizedPod>(
         left, right, static_arguments);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/types/operations/unary_operations/UnaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/UnaryOperationWrapper.hpp b/types/operations/unary_operations/UnaryOperationWrapper.hpp
index 59b2cf0..09e7b05 100644
--- a/types/operations/unary_operations/UnaryOperationWrapper.hpp
+++ b/types/operations/unary_operations/UnaryOperationWrapper.hpp
@@ -184,7 +184,7 @@ class UnaryOperationWrapper : public UnaryOperation {
       const std::vector<TypedValue> &static_arguments) const override {
     DCHECK(argument_type.getTypeID() == ArgumentType::kStaticTypeID);
     DCHECK(static_arguments.empty());
-    return getResultTypeImpl<ResultType::kParameterized>(
+    return getResultTypeImpl<ResultType::kIsParameterizedPodz>(
         argument_type, static_arguments);
   }
 


[29/38] incubator-quickstep git commit: Continue the work

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/operations/OperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.hpp b/types/operations/OperationFactory.hpp
index 3e90b6d..b3fd9b4 100644
--- a/types/operations/OperationFactory.hpp
+++ b/types/operations/OperationFactory.hpp
@@ -26,8 +26,8 @@
 #include <utility>
 #include <vector>
 
+#include "types/GenericValue.hpp"
 #include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
 #include "types/operations/Operation.hpp"
 #include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
@@ -104,9 +104,9 @@ class OperationFactory {
   OperationSignaturePtr resolveOperation(
       const std::string &operation_name,
       const std::shared_ptr<const std::vector<const Type*>> &argument_types,
-      const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+      const std::shared_ptr<const std::vector<GenericValue>> &static_arguments,
       std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
-      std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+      std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
       std::string *message) const;
 
  private:
@@ -155,8 +155,8 @@ class OperationFactory {
       const PartialSignatureIndex &secondary_index,
       const std::vector<TypeID> &argument_type_ids,
       const std::vector<const Type*> &argument_types,
-      const std::vector<TypedValue> &static_arguments,
-      std::shared_ptr<const std::vector<TypedValue>> *trimmed_static_arguments,
+      const std::vector<GenericValue> &static_arguments,
+      std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
       OperationSignaturePtr *resolved_op_signature,
       std::string *message) const;
 
@@ -164,9 +164,9 @@ class OperationFactory {
       const PartialSignatureIndex &secondary_index,
       const std::vector<TypeID> &argument_type_ids,
       const std::vector<const Type*> &argument_types,
-      const std::vector<TypedValue> &static_arguments,
+      const std::vector<GenericValue> &static_arguments,
       std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
-      std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+      std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
       OperationSignaturePtr *resolved_op_signature,
       std::string *message) const;
 
@@ -174,15 +174,15 @@ class OperationFactory {
 //      const std::set<OperationSignaturePtr> signatures,
 //      const std::vector<TypeID> &argument_type_ids,
 //      const std::vector<const Type*> &argument_types,
-//      const std::vector<TypedValue> &static_arguments,
+//      const std::vector<GenericValue> &static_arguments,
 //      std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
-//      std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+//      std::shared_ptr<const std::vector<GenericValue>> *coerced_static_arguments,
 //      OperationSignaturePtr *op_signature,
 //      std::string *message) const;
 
   bool canApplyOperationTo(const OperationPtr operation,
                            const std::vector<const Type*> &argument_types,
-                           const std::vector<TypedValue> &static_arguments,
+                           const std::vector<GenericValue> &static_arguments,
                            std::string *message) const;
 
   std::unordered_map<OperationSignaturePtr,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/operations/comparisons/BasicComparison.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/BasicComparison.hpp b/types/operations/comparisons/BasicComparison.hpp
index bf80e50..1d4bbdc 100644
--- a/types/operations/comparisons/BasicComparison.hpp
+++ b/types/operations/comparisons/BasicComparison.hpp
@@ -245,8 +245,8 @@ bool BasicComparison::compareTypedValuesCheckedHelper(const TypedValue &left,
   const Type *unifier = TypeFactory::GetUnifyingType(left_type, right_type);
   DCHECK(unifier != nullptr);
 
-  const TypedValue left_coerced = unifier->coerceValue(left, left_type);
-  const TypedValue right_coerced = unifier->coerceValue(right, right_type);
+  const TypedValue left_coerced = unifier->coerceTypedValue(left, left_type);
+  const TypedValue right_coerced = unifier->coerceTypedValue(right, right_type);
 
   switch (unifier->getTypeID()) {
     case kInt: {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/a7ccb467/types/operations/unary_operations/CastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.hpp b/types/operations/unary_operations/CastOperation.hpp
index 140c152..7270dec 100644
--- a/types/operations/unary_operations/CastOperation.hpp
+++ b/types/operations/unary_operations/CastOperation.hpp
@@ -131,7 +131,7 @@ class CastOperation : public UnaryOperation {
       return &TypeFactory::GetType(it->second);
     } else {
       TypedValue length_value;
-      if (IntType::InstanceNonNullable().parseValueFromString(length_str, &length_value)) {
+      if (IntType::InstanceNonNullable().parseTypedValueFromString(length_str, &length_value)) {
         return &TypeFactory::GetType(
             it->second,
             static_cast<std::size_t>(length_value.getLiteral<int>()),


[36/38] incubator-quickstep git commit: Type as first class citizen

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/843a1723/parser/preprocessed/SqlParser_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.cpp b/parser/preprocessed/SqlParser_gen.cpp
index 7bdc0ab..fcd070f 100644
--- a/parser/preprocessed/SqlParser_gen.cpp
+++ b/parser/preprocessed/SqlParser_gen.cpp
@@ -108,6 +108,7 @@ typedef struct YYLTYPE {
 #include "parser/ParseBasicExpressions.hpp"
 #include "parser/ParseBlockProperties.hpp"
 #include "parser/ParseCaseExpressions.hpp"
+#include "parser/ParseDataType.hpp"
 #include "parser/ParseExpression.hpp"
 #include "parser/ParseGeneratorTableReference.hpp"
 #include "parser/ParseGroupBy.hpp"
@@ -147,7 +148,7 @@ typedef struct YYLTYPE {
 // Needed for Bison 2.6 and higher, which do not automatically provide this typedef.
 typedef void* yyscan_t;
 
-#line 151 "SqlParser_gen.cpp" /* yacc.c:339  */
+#line 152 "SqlParser_gen.cpp" /* yacc.c:339  */
 
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -209,117 +210,103 @@ extern int quickstep_yydebug;
     TOKEN_ALTER = 282,
     TOKEN_AS = 283,
     TOKEN_ASC = 284,
-    TOKEN_BIGINT = 285,
-    TOKEN_BIT = 286,
-    TOKEN_BITWEAVING = 287,
-    TOKEN_BLOCKPROPERTIES = 288,
-    TOKEN_BLOCKSAMPLE = 289,
-    TOKEN_BLOOM_FILTER = 290,
-    TOKEN_CSB_TREE = 291,
-    TOKEN_BY = 292,
-    TOKEN_CASE = 293,
-    TOKEN_CAST = 294,
-    TOKEN_CHARACTER = 295,
-    TOKEN_CHECK = 296,
-    TOKEN_COLUMN = 297,
-    TOKEN_CONSTRAINT = 298,
-    TOKEN_COPY = 299,
-    TOKEN_CREATE = 300,
-    TOKEN_CURRENT = 301,
-    TOKEN_DATE = 302,
-    TOKEN_DATETIME = 303,
-    TOKEN_DAY = 304,
-    TOKEN_DECIMAL = 305,
-    TOKEN_DEFAULT = 306,
-    TOKEN_DELETE = 307,
-    TOKEN_DESC = 308,
-    TOKEN_DISTINCT = 309,
-    TOKEN_DOUBLE = 310,
-    TOKEN_DOUBLECOLON = 311,
-    TOKEN_DROP = 312,
-    TOKEN_ELSE = 313,
-    TOKEN_END = 314,
-    TOKEN_EXISTS = 315,
-    TOKEN_EXTRACT = 316,
-    TOKEN_FALSE = 317,
-    TOKEN_FIRST = 318,
-    TOKEN_FLOAT = 319,
-    TOKEN_FOLLOWING = 320,
-    TOKEN_FOR = 321,
-    TOKEN_FOREIGN = 322,
-    TOKEN_FROM = 323,
-    TOKEN_FULL = 324,
-    TOKEN_GROUP = 325,
-    TOKEN_HASH = 326,
-    TOKEN_HAVING = 327,
-    TOKEN_HOUR = 328,
-    TOKEN_IN = 329,
-    TOKEN_INDEX = 330,
-    TOKEN_INNER = 331,
-    TOKEN_INSERT = 332,
-    TOKEN_INTEGER = 333,
-    TOKEN_INTERVAL = 334,
-    TOKEN_INTO = 335,
-    TOKEN_JOIN = 336,
-    TOKEN_KEY = 337,
-    TOKEN_LAST = 338,
-    TOKEN_LBRACE = 339,
-    TOKEN_LEFT = 340,
-    TOKEN_LIMIT = 341,
-    TOKEN_LONG = 342,
-    TOKEN_MINUTE = 343,
-    TOKEN_MONTH = 344,
-    TOKEN_NULL = 345,
-    TOKEN_NULLS = 346,
-    TOKEN_OFF = 347,
-    TOKEN_ON = 348,
-    TOKEN_ORDER = 349,
-    TOKEN_OUTER = 350,
-    TOKEN_OVER = 351,
-    TOKEN_PARTITION = 352,
-    TOKEN_PARTITIONS = 353,
-    TOKEN_PERCENT = 354,
-    TOKEN_PRECEDING = 355,
-    TOKEN_PRIMARY = 356,
-    TOKEN_PRIORITY = 357,
-    TOKEN_QUIT = 358,
-    TOKEN_RANGE = 359,
-    TOKEN_RBRACE = 360,
-    TOKEN_REAL = 361,
-    TOKEN_REFERENCES = 362,
-    TOKEN_RIGHT = 363,
-    TOKEN_ROW = 364,
-    TOKEN_ROW_DELIMITER = 365,
-    TOKEN_ROWS = 366,
-    TOKEN_SECOND = 367,
-    TOKEN_SELECT = 368,
-    TOKEN_SET = 369,
-    TOKEN_SMA = 370,
-    TOKEN_SMALLINT = 371,
-    TOKEN_STDERR = 372,
-    TOKEN_STDOUT = 373,
-    TOKEN_SUBSTRING = 374,
-    TOKEN_TABLE = 375,
-    TOKEN_THEN = 376,
-    TOKEN_TIME = 377,
-    TOKEN_TIMESTAMP = 378,
-    TOKEN_TO = 379,
-    TOKEN_TRUE = 380,
-    TOKEN_TUPLESAMPLE = 381,
-    TOKEN_UNBOUNDED = 382,
-    TOKEN_UNIQUE = 383,
-    TOKEN_UPDATE = 384,
-    TOKEN_USING = 385,
-    TOKEN_VALUES = 386,
-    TOKEN_VARCHAR = 387,
-    TOKEN_WHEN = 388,
-    TOKEN_WHERE = 389,
-    TOKEN_WINDOW = 390,
-    TOKEN_WITH = 391,
-    TOKEN_YEAR = 392,
-    TOKEN_YEARMONTH = 393,
-    TOKEN_EOF = 394,
-    TOKEN_LEX_ERROR = 395
+    TOKEN_BIT = 285,
+    TOKEN_BITWEAVING = 286,
+    TOKEN_BLOCKPROPERTIES = 287,
+    TOKEN_BLOCKSAMPLE = 288,
+    TOKEN_BLOOM_FILTER = 289,
+    TOKEN_CSB_TREE = 290,
+    TOKEN_BY = 291,
+    TOKEN_CASE = 292,
+    TOKEN_CAST = 293,
+    TOKEN_CHECK = 294,
+    TOKEN_COLUMN = 295,
+    TOKEN_CONSTRAINT = 296,
+    TOKEN_COPY = 297,
+    TOKEN_CREATE = 298,
+    TOKEN_CURRENT = 299,
+    TOKEN_DAY = 300,
+    TOKEN_DEFAULT = 301,
+    TOKEN_DELETE = 302,
+    TOKEN_DESC = 303,
+    TOKEN_DISTINCT = 304,
+    TOKEN_DOUBLECOLON = 305,
+    TOKEN_DROP = 306,
+    TOKEN_ELSE = 307,
+    TOKEN_END = 308,
+    TOKEN_EXISTS = 309,
+    TOKEN_EXTRACT = 310,
+    TOKEN_FALSE = 311,
+    TOKEN_FIRST = 312,
+    TOKEN_FOLLOWING = 313,
+    TOKEN_FOR = 314,
+    TOKEN_FOREIGN = 315,
+    TOKEN_FROM = 316,
+    TOKEN_FULL = 317,
+    TOKEN_GROUP = 318,
+    TOKEN_HASH = 319,
+    TOKEN_HAVING = 320,
+    TOKEN_HOUR = 321,
+    TOKEN_IN = 322,
+    TOKEN_INDEX = 323,
+    TOKEN_INNER = 324,
+    TOKEN_INSERT = 325,
+    TOKEN_INTERVAL = 326,
+    TOKEN_INTO = 327,
+    TOKEN_JOIN = 328,
+    TOKEN_KEY = 329,
+    TOKEN_LAST = 330,
+    TOKEN_LBRACE = 331,
+    TOKEN_LEFT = 332,
+    TOKEN_LIMIT = 333,
+    TOKEN_MINUTE = 334,
+    TOKEN_MONTH = 335,
+    TOKEN_NULL = 336,
+    TOKEN_NULLS = 337,
+    TOKEN_OFF = 338,
+    TOKEN_ON = 339,
+    TOKEN_ORDER = 340,
+    TOKEN_OUTER = 341,
+    TOKEN_OVER = 342,
+    TOKEN_PARTITION = 343,
+    TOKEN_PARTITIONS = 344,
+    TOKEN_PERCENT = 345,
+    TOKEN_PRECEDING = 346,
+    TOKEN_PRIMARY = 347,
+    TOKEN_PRIORITY = 348,
+    TOKEN_QUIT = 349,
+    TOKEN_RANGE = 350,
+    TOKEN_RBRACE = 351,
+    TOKEN_REAL = 352,
+    TOKEN_REFERENCES = 353,
+    TOKEN_RIGHT = 354,
+    TOKEN_ROW = 355,
+    TOKEN_ROW_DELIMITER = 356,
+    TOKEN_ROWS = 357,
+    TOKEN_SECOND = 358,
+    TOKEN_SELECT = 359,
+    TOKEN_SET = 360,
+    TOKEN_SMA = 361,
+    TOKEN_STDERR = 362,
+    TOKEN_STDOUT = 363,
+    TOKEN_SUBSTRING = 364,
+    TOKEN_TABLE = 365,
+    TOKEN_THEN = 366,
+    TOKEN_TO = 367,
+    TOKEN_TRUE = 368,
+    TOKEN_TUPLESAMPLE = 369,
+    TOKEN_UNBOUNDED = 370,
+    TOKEN_UNIQUE = 371,
+    TOKEN_UPDATE = 372,
+    TOKEN_USING = 373,
+    TOKEN_VALUES = 374,
+    TOKEN_WHEN = 375,
+    TOKEN_WHERE = 376,
+    TOKEN_WINDOW = 377,
+    TOKEN_WITH = 378,
+    TOKEN_YEAR = 379,
+    TOKEN_EOF = 380,
+    TOKEN_LEX_ERROR = 381
   };
 #endif
 
@@ -328,7 +315,7 @@ extern int quickstep_yydebug;
 
 union YYSTYPE
 {
-#line 115 "../SqlParser.ypp" /* yacc.c:355  */
+#line 116 "../SqlParser.ypp" /* yacc.c:355  */
 
   quickstep::ParseString *string_value_;
 
@@ -430,7 +417,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 434 "SqlParser_gen.cpp" /* yacc.c:355  */
+#line 421 "SqlParser_gen.cpp" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -459,13 +446,13 @@ int quickstep_yyparse (yyscan_t yyscanner, quickstep::ParseStatement **parsedSta
 #endif /* !YY_QUICKSTEP_YY_SQLPARSER_GEN_HPP_INCLUDED  */
 
 /* Copy the second part of user declarations.  */
-#line 217 "../SqlParser.ypp" /* yacc.c:358  */
+#line 218 "../SqlParser.ypp" /* yacc.c:358  */
 
 /* This header needs YYSTYPE, which is defined by the %union directive above */
 #include "SqlLexer_gen.hpp"
 void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature);
 
-#line 469 "SqlParser_gen.cpp" /* yacc.c:358  */
+#line 456 "SqlParser_gen.cpp" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -709,21 +696,21 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  50
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1626
+#define YYLAST   792
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  152
+#define YYNTOKENS  138
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  113
+#define YYNNTS  115
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  308
+#define YYNRULES  296
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  570
+#define YYNSTATES  554
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   395
+#define YYMAXUTOK   381
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -733,11 +720,11 @@ union yyalloc
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     147,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     133,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,   151,     2,     2,
-     148,   149,    23,    21,   150,    22,    27,    24,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,   146,
+       2,     2,     2,     2,     2,     2,     2,   137,     2,     2,
+     134,   135,    23,    21,   136,    22,    27,    24,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,   132,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -770,45 +757,43 @@ static const yytype_uint8 yytranslate[] =
      100,   101,   102,   103,   104,   105,   106,   107,   108,   109,
      110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
      120,   121,   122,   123,   124,   125,   126,   127,   128,   129,
-     130,   131,   132,   133,   134,   135,   136,   137,   138,   139,
-     140,   141,   142,   143,   144,   145
+     130,   131
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   643,   643,   647,   651,   655,   659,   662,   669,   672,
-     675,   678,   681,   684,   687,   690,   693,   696,   702,   708,
-     715,   721,   728,   737,   742,   751,   756,   761,   765,   771,
-     776,   779,   782,   787,   790,   793,   796,   799,   802,   805,
-     808,   811,   814,   826,   829,   832,   850,   870,   873,   876,
-     881,   886,   892,   898,   907,   911,   917,   920,   925,   930,
-     935,   942,   949,   953,   959,   962,   967,   970,   975,   978,
-     983,   986,  1005,  1008,  1013,  1017,  1023,  1026,  1029,  1032,
-    1037,  1040,  1043,  1050,  1055,  1066,  1071,  1076,  1080,  1084,
-    1090,  1093,  1099,  1107,  1110,  1113,  1119,  1124,  1129,  1133,
-    1139,  1143,  1146,  1151,  1154,  1159,  1164,  1169,  1173,  1179,
-    1188,  1191,  1196,  1199,  1218,  1223,  1227,  1233,  1239,  1248,
-    1253,  1261,  1267,  1273,  1276,  1279,  1284,  1287,  1292,  1296,
-    1302,  1305,  1308,  1313,  1318,  1323,  1326,  1329,  1334,  1337,
-    1340,  1343,  1346,  1349,  1352,  1355,  1360,  1363,  1368,  1372,
-    1376,  1379,  1383,  1386,  1391,  1394,  1399,  1402,  1407,  1411,
-    1417,  1420,  1425,  1428,  1433,  1436,  1441,  1444,  1463,  1466,
-    1471,  1475,  1481,  1487,  1492,  1495,  1500,  1503,  1508,  1511,
-    1516,  1519,  1524,  1525,  1528,  1533,  1534,  1537,  1542,  1546,
-    1552,  1559,  1562,  1565,  1570,  1573,  1576,  1582,  1585,  1590,
-    1595,  1604,  1609,  1618,  1623,  1626,  1631,  1634,  1639,  1645,
-    1651,  1654,  1657,  1660,  1663,  1666,  1672,  1681,  1687,  1692,
-    1698,  1703,  1708,  1713,  1716,  1719,  1722,  1725,  1729,  1733,
-    1736,  1739,  1742,  1745,  1748,  1753,  1756,  1762,  1766,  1773,
-    1777,  1781,  1784,  1789,  1803,  1812,  1826,  1837,  1848,  1856,
-    1867,  1870,  1875,  1879,  1885,  1890,  1894,  1900,  1905,  1908,
-    1913,  1917,  1923,  1926,  1929,  1932,  1944,  1948,  1967,  1980,
-    1995,  1998,  2001,  2004,  2007,  2010,  2015,  2019,  2025,  2028,
-    2033,  2037,  2044,  2047,  2050,  2053,  2056,  2059,  2062,  2065,
-    2068,  2071,  2076,  2087,  2090,  2095,  2098,  2101,  2107,  2111,
-    2117,  2120,  2128,  2131,  2134,  2137,  2143,  2148,  2153
+       0,   632,   632,   636,   640,   644,   648,   651,   658,   661,
+     664,   667,   670,   673,   676,   679,   682,   685,   691,   697,
+     704,   710,   717,   726,   731,   740,   745,   750,   754,   760,
+     763,   768,   774,   780,   785,   792,   795,   798,   803,   806,
+     809,   814,   819,   825,   831,   840,   844,   850,   853,   858,
+     863,   868,   875,   882,   886,   892,   895,   900,   903,   908,
+     911,   916,   919,   938,   941,   946,   950,   956,   959,   962,
+     965,   970,   973,   976,   983,   988,   999,  1004,  1009,  1013,
+    1017,  1023,  1026,  1032,  1040,  1043,  1046,  1052,  1057,  1062,
+    1066,  1072,  1076,  1079,  1084,  1087,  1092,  1097,  1102,  1106,
+    1112,  1121,  1124,  1129,  1132,  1151,  1156,  1160,  1166,  1172,
+    1181,  1186,  1194,  1200,  1206,  1209,  1212,  1217,  1220,  1225,
+    1229,  1235,  1238,  1241,  1246,  1251,  1256,  1259,  1262,  1267,
+    1270,  1273,  1276,  1279,  1282,  1285,  1288,  1293,  1296,  1301,
+    1305,  1309,  1312,  1316,  1319,  1324,  1327,  1332,  1335,  1340,
+    1344,  1350,  1353,  1358,  1361,  1366,  1369,  1374,  1377,  1396,
+    1399,  1404,  1408,  1414,  1420,  1425,  1428,  1433,  1436,  1441,
+    1444,  1449,  1452,  1457,  1458,  1461,  1466,  1467,  1470,  1475,
+    1479,  1485,  1492,  1495,  1498,  1503,  1506,  1509,  1515,  1518,
+    1523,  1528,  1537,  1542,  1551,  1556,  1559,  1564,  1567,  1572,
+    1578,  1584,  1587,  1590,  1593,  1596,  1599,  1605,  1614,  1620,
+    1625,  1631,  1636,  1641,  1646,  1649,  1652,  1655,  1658,  1662,
+    1666,  1669,  1672,  1675,  1678,  1681,  1686,  1689,  1695,  1699,
+    1706,  1710,  1714,  1717,  1722,  1725,  1730,  1741,  1749,  1760,
+    1763,  1768,  1772,  1778,  1783,  1787,  1793,  1798,  1801,  1806,
+    1810,  1816,  1819,  1822,  1825,  1837,  1841,  1860,  1875,  1878,
+    1881,  1884,  1887,  1890,  1895,  1899,  1905,  1908,  1913,  1917,
+    1924,  1927,  1930,  1933,  1936,  1939,  1942,  1945,  1948,  1951,
+    1956,  1967,  1970,  1975,  1978,  1981,  1987,  1991,  1997,  2000,
+    2008,  2011,  2014,  2017,  2023,  2028,  2033
 };
 #endif
 
@@ -824,43 +809,40 @@ static const char *const yytname[] =
   "TOKEN_NEQ", "TOKEN_LIKE", "TOKEN_REGEXP", "TOKEN_BETWEEN", "TOKEN_IS",
   "'+'", "'-'", "'*'", "'/'", "UNARY_PLUS", "UNARY_MINUS", "'.'",
   "TOKEN_ALL", "TOKEN_UNION", "TOKEN_INTERSECT", "TOKEN_ADD",
-  "TOKEN_ALTER", "TOKEN_AS", "TOKEN_ASC", "TOKEN_BIGINT", "TOKEN_BIT",
-  "TOKEN_BITWEAVING", "TOKEN_BLOCKPROPERTIES", "TOKEN_BLOCKSAMPLE",
-  "TOKEN_BLOOM_FILTER", "TOKEN_CSB_TREE", "TOKEN_BY", "TOKEN_CASE",
-  "TOKEN_CAST", "TOKEN_CHARACTER", "TOKEN_CHECK", "TOKEN_COLUMN",
-  "TOKEN_CONSTRAINT", "TOKEN_COPY", "TOKEN_CREATE", "TOKEN_CURRENT",
-  "TOKEN_DATE", "TOKEN_DATETIME", "TOKEN_DAY", "TOKEN_DECIMAL",
-  "TOKEN_DEFAULT", "TOKEN_DELETE", "TOKEN_DESC", "TOKEN_DISTINCT",
-  "TOKEN_DOUBLE", "TOKEN_DOUBLECOLON", "TOKEN_DROP", "TOKEN_ELSE",
-  "TOKEN_END", "TOKEN_EXISTS", "TOKEN_EXTRACT", "TOKEN_FALSE",
-  "TOKEN_FIRST", "TOKEN_FLOAT", "TOKEN_FOLLOWING", "TOKEN_FOR",
+  "TOKEN_ALTER", "TOKEN_AS", "TOKEN_ASC", "TOKEN_BIT", "TOKEN_BITWEAVING",
+  "TOKEN_BLOCKPROPERTIES", "TOKEN_BLOCKSAMPLE", "TOKEN_BLOOM_FILTER",
+  "TOKEN_CSB_TREE", "TOKEN_BY", "TOKEN_CASE", "TOKEN_CAST", "TOKEN_CHECK",
+  "TOKEN_COLUMN", "TOKEN_CONSTRAINT", "TOKEN_COPY", "TOKEN_CREATE",
+  "TOKEN_CURRENT", "TOKEN_DAY", "TOKEN_DEFAULT", "TOKEN_DELETE",
+  "TOKEN_DESC", "TOKEN_DISTINCT", "TOKEN_DOUBLECOLON", "TOKEN_DROP",
+  "TOKEN_ELSE", "TOKEN_END", "TOKEN_EXISTS", "TOKEN_EXTRACT",
+  "TOKEN_FALSE", "TOKEN_FIRST", "TOKEN_FOLLOWING", "TOKEN_FOR",
   "TOKEN_FOREIGN", "TOKEN_FROM", "TOKEN_FULL", "TOKEN_GROUP", "TOKEN_HASH",
   "TOKEN_HAVING", "TOKEN_HOUR", "TOKEN_IN", "TOKEN_INDEX", "TOKEN_INNER",
-  "TOKEN_INSERT", "TOKEN_INTEGER", "TOKEN_INTERVAL", "TOKEN_INTO",
-  "TOKEN_JOIN", "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LBRACE", "TOKEN_LEFT",
-  "TOKEN_LIMIT", "TOKEN_LONG", "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL",
-  "TOKEN_NULLS", "TOKEN_OFF", "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER",
-  "TOKEN_OVER", "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
+  "TOKEN_INSERT", "TOKEN_INTERVAL", "TOKEN_INTO", "TOKEN_JOIN",
+  "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LBRACE", "TOKEN_LEFT", "TOKEN_LIMIT",
+  "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL", "TOKEN_NULLS", "TOKEN_OFF",
+  "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER", "TOKEN_OVER",
+  "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
   "TOKEN_PRECEDING", "TOKEN_PRIMARY", "TOKEN_PRIORITY", "TOKEN_QUIT",
   "TOKEN_RANGE", "TOKEN_RBRACE", "TOKEN_REAL", "TOKEN_REFERENCES",
   "TOKEN_RIGHT", "TOKEN_ROW", "TOKEN_ROW_DELIMITER", "TOKEN_ROWS",
-  "TOKEN_SECOND", "TOKEN_SELECT", "TOKEN_SET", "TOKEN_SMA",
-  "TOKEN_SMALLINT", "TOKEN_STDERR", "TOKEN_STDOUT", "TOKEN_SUBSTRING",
-  "TOKEN_TABLE", "TOKEN_THEN", "TOKEN_TIME", "TOKEN_TIMESTAMP", "TOKEN_TO",
-  "TOKEN_TRUE", "TOKEN_TUPLESAMPLE", "TOKEN_UNBOUNDED", "TOKEN_UNIQUE",
-  "TOKEN_UPDATE", "TOKEN_USING", "TOKEN_VALUES", "TOKEN_VARCHAR",
+  "TOKEN_SECOND", "TOKEN_SELECT", "TOKEN_SET", "TOKEN_SMA", "TOKEN_STDERR",
+  "TOKEN_STDOUT", "TOKEN_SUBSTRING", "TOKEN_TABLE", "TOKEN_THEN",
+  "TOKEN_TO", "TOKEN_TRUE", "TOKEN_TUPLESAMPLE", "TOKEN_UNBOUNDED",
+  "TOKEN_UNIQUE", "TOKEN_UPDATE", "TOKEN_USING", "TOKEN_VALUES",
   "TOKEN_WHEN", "TOKEN_WHERE", "TOKEN_WINDOW", "TOKEN_WITH", "TOKEN_YEAR",
-  "TOKEN_YEARMONTH", "TOKEN_EOF", "TOKEN_LEX_ERROR", "';'", "'\\n'", "'('",
-  "')'", "','", "'%'", "$accept", "start", "sql_statement",
-  "quit_statement", "alter_table_statement", "create_table_statement",
+  "TOKEN_EOF", "TOKEN_LEX_ERROR", "';'", "'\\n'", "'('", "')'", "','",
+  "'%'", "$accept", "start", "sql_statement", "quit_statement",
+  "alter_table_statement", "create_table_statement",
   "create_index_statement", "drop_table_statement", "column_def",
-  "column_def_commalist", "data_type", "column_constraint_def",
-  "column_constraint_def_list", "opt_column_constraint_def_list",
-  "table_constraint_def", "table_constraint_def_commalist",
-  "opt_table_constraint_def_commalist", "opt_column_list",
-  "opt_block_properties", "opt_partition_clause", "partition_type",
-  "key_value_list", "key_value", "key_string_value", "key_string_list",
-  "key_integer_value", "key_bool_value", "index_type",
+  "column_def_commalist", "data_type", "data_type_parameter_commalist",
+  "opt_nullable", "column_constraint_def", "column_constraint_def_list",
+  "opt_column_constraint_def_list", "table_constraint_def",
+  "table_constraint_def_commalist", "opt_table_constraint_def_commalist",
+  "opt_column_list", "opt_block_properties", "opt_partition_clause",
+  "partition_type", "key_value_list", "key_value", "key_string_value",
+  "key_string_list", "key_integer_value", "key_bool_value", "index_type",
   "opt_index_properties", "insert_statement", "copy_statement",
   "copy_to_target", "opt_copy_params", "update_statement",
   "delete_statement", "assignment_list", "assignment_item",
@@ -910,18 +892,16 @@ static const yytype_uint16 yytoknum[] =
      350,   351,   352,   353,   354,   355,   356,   357,   358,   359,
      360,   361,   362,   363,   364,   365,   366,   367,   368,   369,
      370,   371,   372,   373,   374,   375,   376,   377,   378,   379,
-     380,   381,   382,   383,   384,   385,   386,   387,   388,   389,
-     390,   391,   392,   393,   394,   395,    59,    10,    40,    41,
-      44,    37
+     380,   381,    59,    10,    40,    41,    44,    37
 };
 # endif
 
-#define YYPACT_NINF -280
+#define YYPACT_NINF -257
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-280)))
+  (!!((Yystate) == (-257)))
 
-#define YYTABLE_NINF -139
+#define YYTABLE_NINF -130
 
 #define yytable_value_is_error(Yytable_value) \
   0
@@ -930,63 +910,62 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     185,  -280,  -280,   -26,    38,     6,    29,    16,    26,  -280,
-      47,   210,   210,  -280,   215,    84,  -280,  -280,  -280,  -280,
-    -280,  -280,  -280,  -280,  -280,  -280,   173,    66,   201,  -280,
-     -54,   222,   210,  -280,  -280,     1,   135,   210,   210,   210,
-     210,   210,  -280,  -280,   768,   138,   113,  -280,   236,   117,
-    -280,  -280,  -280,   154,   189,    66,    47,   187,  -280,   154,
-    -280,  -280,  -280,    50,    22,   151,   294,   151,   214,   160,
-     177,  -280,   -14,  -280,  -280,   314,   317,  -280,  -280,  -280,
-     865,   170,   174,  -280,   246,  -280,  -280,   190,  -280,  -280,
-     337,   962,  -280,  -280,  -280,  -280,   204,  -280,  -280,   209,
-     279,  1059,   355,   292,   217,  -280,  -280,   358,    40,  -280,
-     313,  -280,   -18,   277,  -280,  -280,  -280,  -280,  -280,  -280,
-    1265,     5,   210,   210,   235,   210,     1,   210,  -280,   154,
-     379,  -280,    81,   162,  -280,  -280,  -280,   242,  -280,   151,
-    -280,   210,   210,   671,  -280,  -280,   260,   210,  -280,  -280,
-    -280,   671,    63,    51,  -280,  1362,   387,  -280,   183,   183,
-    -280,   276,  1362,   410,  -280,    -9,    46,  -280,     9,   177,
-    1362,  -280,  -280,   210,  1362,  -280,  -280,  -280,  -280,  1362,
-     340,  -280,  1362,    19,   317,   313,   210,   437,    73,  -280,
-     424,  -280,   154,  -280,   191,  -280,   151,   154,   201,  -280,
-     210,   172,   210,   210,   210,  -280,   288,  -280,   200,  1483,
-    1168,   235,   562,   430,   431,  -280,  -280,   525,   419,  1442,
-     205,    52,  1362,    54,  -280,  1362,  -280,   381,   315,   297,
-    -280,  -280,  -280,  -280,  -280,  -280,   374,  -280,   198,   299,
-    -280,  -280,    18,   220,   253,  -280,   300,   220,     2,   377,
-    -280,  -280,    40,  -280,  -280,  -280,  -280,   276,   347,  -280,
-    -280,   304,  1362,  -280,   276,   221,   210,  -280,  1362,  -280,
-     210,  -280,  -280,  -280,   306,   368,   370,   316,  -280,  -280,
-    -280,   223,  -280,  -280,  -280,  -280,  -280,    12,   210,   327,
-     172,   210,   195,  -280,  -280,    21,    36,   671,   671,   231,
-    -280,  -280,  -280,  -280,  -280,  -280,  -280,  -280,  1362,   318,
-    1362,    86,  -280,   232,   329,  1362,    67,  -280,   405,   276,
-    -280,   340,  -280,  1362,   463,  -280,   155,   210,  -280,  -280,
-     371,  -280,   375,   376,   388,     9,  -280,   471,   477,   220,
-     443,   414,   445,   344,   395,  -280,   239,  -280,  1362,  -280,
-     276,  -280,   671,   350,   351,   210,  -280,   210,  -280,  -280,
-    -280,  -280,  -280,  -280,  -280,   210,  -280,  -280,  -280,   247,
-     468,    60,  -280,   352,   359,  -280,   406,   357,  1442,  -280,
-     420,   210,  -280,  -280,   195,  -280,  -280,   431,  -280,  -280,
-    -280,  1362,   360,   237,  1059,  -280,   276,   415,  -280,  -280,
-    1442,   361,   276,  1362,  -280,   362,   363,    55,    -1,  -280,
-    -280,  -280,  -280,  -280,     9,   253,   409,   412,  -280,  1362,
-     671,   418,  1362,  -280,   472,   -22,  -280,   276,    23,   210,
-     210,   249,  -280,   252,  -280,   210,  -280,  -280,  -280,  -280,
-     380,   172,   480,   417,  -280,   671,  -280,  -280,   382,  -280,
-     293,  1059,  -280,  1362,   254,  -280,  -280,  1442,   276,  -280,
-    -280,  -280,   515,  -280,   425,  -280,  -280,   383,   430,   482,
-     434,   383,  1362,  -280,  -280,  -280,   512,  -280,   257,   262,
-    -280,  -280,  -280,   210,  -280,  -280,   386,   507,  -280,    35,
-     210,  1362,   265,   276,  -280,   270,   401,   671,  1362,   544,
-     416,   402,  -280,   311,    31,   442,  -280,   272,   210,    15,
-    -280,   408,   276,  -280,  -280,  -280,   430,   402,  -280,   210,
-    -280,   416,  -280,  1362,  -280,  -280,   459,   454,   446,   457,
-     554,   210,  -280,   278,  -280,  -280,   422,  -280,   538,  -280,
-    -280,    37,  -280,  -280,  -280,  -280,    62,   427,  -280,   210,
-     428,  -280,  -280,   503,   464,   509,  -280,   210,   280,   347,
-    -280,  -280,  -280,   284,   474,   432,  -280,   575,  -280,  -280
+     653,  -257,  -257,    37,    86,     4,    58,    84,   157,  -257,
+      55,   286,   286,  -257,   245,   185,  -257,  -257,  -257,  -257,
+    -257,  -257,  -257,  -257,  -257,  -257,   169,   -17,   226,  -257,
+     144,   276,   286,  -257,  -257,    10,   -22,   286,   286,   286,
+     286,   286,  -257,  -257,   479,   189,   125,  -257,   271,   178,
+    -257,  -257,  -257,   217,   252,   -17,    55,   254,  -257,   217,
+    -257,  -257,  -257,   174,    79,   207,   354,   207,   281,   251,
+     277,  -257,   -35,  -257,  -257,   393,   403,  -257,   491,   280,
+     294,   416,   503,  -257,   316,   569,   379,   319,  -257,  -257,
+     386,     7,  -257,   396,  -257,   -39,   360,  -257,  -257,  -257,
+    -257,  -257,  -257,   626,    48,   286,   286,   320,   286,    10,
+     286,  -257,   217,   449,  -257,    26,   278,  -257,  -257,  -257,
+     323,  -257,   207,  -257,   286,   286,   472,  -257,  -257,   324,
+     286,  -257,  -257,  -257,   472,    72,   101,  -257,   637,   156,
+     156,  -257,   310,   637,    35,    21,    14,   277,   637,  -257,
+    -257,   286,   637,  -257,  -257,  -257,  -257,   637,   286,  -257,
+     637,    17,   403,   396,   286,   339,   162,  -257,   450,  -257,
+     217,  -257,   198,  -257,   207,   217,   226,  -257,   286,   152,
+     286,   286,   286,  -257,   326,  -257,   206,   286,   576,   320,
+     315,   455,   456,  -257,  -257,   720,   444,   232,   212,    16,
+     637,   147,  -257,   637,  -257,   409,   274,  -257,  -257,  -257,
+    -257,  -257,  -257,   402,  -257,    39,  -257,  -257,     9,    74,
+     335,  -257,   334,    74,    53,   404,  -257,  -257,     7,  -257,
+    -257,   215,   337,   310,   382,  -257,  -257,   345,   637,  -257,
+     310,   228,   286,  -257,   637,  -257,   286,  -257,  -257,  -257,
+     347,   408,   410,   356,  -257,  -257,  -257,   237,  -257,  -257,
+    -257,  -257,  -257,   133,   286,   368,   152,   286,   149,  -257,
+    -257,     6,    36,   472,   472,   283,  -257,  -257,  -257,  -257,
+    -257,  -257,  -257,  -257,   637,   369,   637,    30,  -257,   241,
+     380,   637,    91,  -257,   447,   310,  -257,   286,   637,   499,
+     151,   286,  -257,  -257,   425,  -257,   426,   427,   441,    14,
+    -257,   513,   516,    74,   485,   457,  -257,   362,   362,   487,
+     395,   445,  -257,   243,  -257,   637,  -257,   310,  -257,   472,
+     406,   407,   286,  -257,   286,  -257,  -257,  -257,  -257,  -257,
+    -257,  -257,   286,  -257,  -257,  -257,   253,   509,   192,  -257,
+     411,   414,  -257,   452,   415,   232,  -257,   464,   286,  -257,
+    -257,   149,  -257,  -257,   456,  -257,  -257,  -257,   637,   418,
+     180,   569,  -257,   310,   458,  -257,  -257,   232,   420,   310,
+     637,  -257,   421,    44,   122,  -257,  -257,  -257,  -257,  -257,
+      14,   335,   462,   466,  -257,   637,   472,   460,    77,  -257,
+      77,  -257,   637,  -257,   518,   175,  -257,   310,    11,   286,
+     286,   259,  -257,   262,  -257,   286,  -257,  -257,  -257,  -257,
+     428,   152,   527,   473,  -257,   472,  -257,  -257,   434,  -257,
+     318,   569,  -257,   637,   287,  -257,  -257,   232,   310,  -257,
+    -257,   562,  -257,   481,  -257,  -257,   435,   455,   537,   502,
+     501,  -257,  -257,  -257,   435,   637,  -257,  -257,  -257,   573,
+    -257,   291,   295,  -257,  -257,  -257,   286,  -257,  -257,   454,
+     553,  -257,    18,   286,   637,   297,   310,  -257,   299,   461,
+     472,   637,   588,   474,  -257,   463,  -257,   190,    49,   497,
+    -257,   301,   286,     0,  -257,   467,   310,  -257,  -257,  -257,
+     455,   463,  -257,   286,  -257,   474,  -257,   637,  -257,  -257,
+     520,   507,   504,   512,   601,   286,  -257,   306,  -257,  -257,
+     480,  -257,   582,  -257,  -257,    23,  -257,  -257,  -257,  -257,
+      61,   486,  -257,   286,   488,  -257,  -257,   558,   519,   560,
+    -257,   286,   308,   382,  -257,  -257,  -257,   311,   532,   492,
+    -257,   621,  -257,  -257
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -994,97 +973,96 @@ static const yytype_int16 yypact[] =
      means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
-       0,     6,   308,     0,     0,     0,     0,     0,     0,    18,
-     123,     0,     0,     7,     0,     0,    15,     8,    10,    11,
-      13,    14,     9,    17,    12,    16,     0,   112,   119,   121,
-       0,   306,     0,   300,   301,     0,     0,     0,     0,     0,
-       0,     0,   124,   125,     0,     0,   114,   115,     0,   156,
-       1,     3,     2,     0,     0,   112,   123,     0,   110,     0,
-       5,     4,   307,     0,     0,   103,     0,   103,     0,     0,
-     197,    25,     0,   266,   263,     0,   292,   126,    40,    29,
-       0,     0,     0,    30,    31,    34,    36,     0,    37,    39,
-       0,     0,    41,   262,    35,    38,     0,    32,    33,     0,
-       0,     0,     0,     0,   127,   128,   234,   132,   218,   220,
-     222,   225,     0,   226,   229,   230,   231,   232,   224,   223,
-       0,   278,     0,     0,     0,     0,     0,     0,   111,     0,
-       0,   120,     0,     0,   100,   102,   101,     0,    98,   103,
-      97,     0,     0,     0,   106,   198,     0,     0,    94,   264,
-     265,     0,     0,   258,   255,     0,     0,    43,     0,   267,
-     236,   238,     0,     0,    44,     0,     0,   269,     0,   197,
-       0,   293,   294,     0,     0,   131,   296,   297,   295,     0,
-       0,   235,     0,     0,     0,   221,     0,     0,   197,   108,
-       0,   116,     0,   117,     0,   298,   103,     0,   118,   113,
-       0,     0,     0,     0,     0,    96,    66,    27,     0,     0,
-       0,     0,     0,   199,   201,   203,   205,     0,   223,     0,
-       0,     0,     0,   258,   252,     0,   256,     0,     0,     0,
-     272,   273,   274,   271,   275,   270,     0,   268,     0,     0,
-     134,   233,     0,     0,   158,   147,   133,   152,   135,   160,
-     129,   130,   217,   219,    42,   245,   246,   237,   174,   227,
-     279,     0,     0,   239,   260,     0,     0,   105,     0,   157,
-       0,    99,    95,    19,     0,     0,     0,     0,    20,    21,
-      22,     0,    74,    76,    77,    78,    79,     0,     0,     0,
-      64,     0,    56,   204,   212,     0,     0,     0,     0,     0,
-     282,   284,   285,   286,   287,   283,   288,   290,     0,     0,
-       0,     0,   276,     0,     0,     0,     0,   253,     0,   259,
-     251,     0,    45,     0,     0,    46,   138,     0,   148,   154,
-     144,   139,   140,   142,     0,     0,   151,     0,     0,   150,
-       0,   162,     0,     0,   176,   240,     0,   241,     0,   107,
-     109,   299,     0,     0,     0,     0,   104,     0,    81,    84,
-      82,   304,   305,   303,   302,     0,    80,    85,   280,     0,
-     278,     0,    63,    65,    68,    28,     0,     0,     0,    47,
-       0,     0,    49,    55,    57,    26,   211,   200,   202,   289,
-     291,     0,     0,     0,     0,   213,   210,     0,   209,    93,
-       0,     0,   257,     0,   250,     0,     0,     0,     0,   153,
-     155,   145,   141,   143,     0,   159,     0,     0,   149,     0,
-       0,   164,     0,   228,     0,   178,   242,   261,     0,     0,
-       0,     0,    75,     0,    67,     0,    86,    87,    88,    89,
-      90,     0,     0,    70,    48,     0,    51,    50,     0,    54,
-       0,     0,   215,     0,     0,   208,   277,     0,   254,   243,
-     244,   247,     0,   248,     0,   136,   137,   161,   163,     0,
-     166,   175,     0,   181,   180,   173,     0,    61,     0,     0,
-      58,    83,   281,     0,    24,    62,     0,     0,    23,     0,
-       0,     0,     0,   206,   214,     0,     0,     0,     0,     0,
-     168,   177,   188,   191,     0,     0,    59,     0,     0,     0,
-      52,     0,   207,   216,    92,   249,   146,   165,   167,     0,
-     122,   169,   170,     0,   192,   193,   194,     0,     0,     0,
-       0,     0,    91,     0,    72,    73,     0,    53,     0,   171,
-     189,     0,   190,   182,   184,   183,     0,     0,    69,     0,
-       0,   195,   196,     0,     0,     0,   179,     0,     0,   174,
-     185,   187,   186,     0,     0,     0,    60,     0,   172,    71
+       0,     6,   296,     0,     0,     0,     0,     0,     0,    18,
+     114,     0,     0,     7,     0,     0,    15,     8,    10,    11,
+      13,    14,     9,    17,    12,    16,     0,   103,   110,   112,
+       0,   294,     0,   288,   289,     0,     0,     0,     0,     0,
+       0,     0,   115,   116,     0,     0,   105,   106,     0,   147,
+       1,     3,     2,     0,     0,   103,   114,     0,   101,     0,
+       5,     4,   295,     0,     0,    94,     0,    94,     0,     0,
+     188,    25,     0,   255,   252,     0,   280,   117,     0,     0,
+       0,     0,     0,   251,     0,     0,     0,   118,   119,   225,
+     123,   209,   211,   213,   216,     0,   217,   220,   221,   222,
+     223,   215,   214,     0,   266,     0,     0,     0,     0,     0,
+       0,   102,     0,     0,   111,     0,     0,    91,    93,    92,
+       0,    89,    94,    88,     0,     0,     0,    97,   189,     0,
+       0,    85,   253,   254,     0,     0,   247,   244,     0,     0,
+     256,   227,   229,     0,     0,     0,     0,   188,     0,   281,
+     282,     0,     0,   122,   284,   285,   283,     0,     0,   226,
+       0,     0,     0,   212,     0,     0,   188,    99,     0,   107,
+       0,   108,     0,   286,    94,     0,   109,   104,     0,     0,
+       0,     0,     0,    87,    57,    27,     0,     0,     0,     0,
+       0,   190,   192,   194,   196,     0,   214,     0,     0,     0,
+       0,   247,   241,     0,   245,     0,     0,   260,   261,   262,
+     259,   263,   258,     0,   257,     0,   125,   224,     0,     0,
+     149,   138,   124,   143,   126,   151,   120,   121,   208,   210,
+     235,     0,    29,   228,   165,   218,   267,     0,     0,   230,
+     249,     0,     0,    96,     0,   148,     0,    90,    86,    19,
+       0,     0,     0,     0,    20,    21,    22,     0,    65,    67,
+      68,    69,    70,     0,     0,     0,    55,     0,    47,   195,
+     203,     0,     0,     0,     0,     0,   270,   272,   273,   274,
+     275,   271,   276,   278,     0,     0,     0,     0,   264,     0,
+       0,     0,     0,   242,     0,   248,   240,     0,     0,     0,
+     129,     0,   139,   145,   135,   130,   131,   133,     0,     0,
+     142,     0,     0,   141,     0,   153,    30,     0,     0,     0,
+       0,   167,   231,     0,   232,     0,    98,   100,   287,     0,
+       0,     0,     0,    95,     0,    72,    75,    73,   292,   293,
+     291,   290,     0,    71,    76,   268,     0,   266,     0,    54,
+      56,    59,    28,     0,     0,     0,    38,     0,     0,    40,
+      46,    48,    26,   202,   191,   193,   277,   279,     0,     0,
+       0,     0,   204,   201,     0,   200,    84,     0,     0,   246,
+       0,   239,     0,     0,     0,   144,   146,   136,   132,   134,
+       0,   150,     0,     0,   140,     0,     0,   155,    35,    34,
+      35,    33,     0,   219,     0,   169,   233,   250,     0,     0,
+       0,     0,    66,     0,    58,     0,    77,    78,    79,    80,
+      81,     0,     0,    61,    39,     0,    42,    41,     0,    45,
+       0,     0,   206,     0,     0,   199,   265,     0,   243,   234,
+     236,     0,   237,     0,   127,   128,   152,   154,     0,   157,
+       0,    36,    32,    31,   166,     0,   172,   171,   164,     0,
+      52,     0,     0,    49,    74,   269,     0,    24,    53,     0,
+       0,    23,     0,     0,     0,     0,   197,   205,     0,     0,
+       0,     0,     0,   159,    37,   168,   179,   182,     0,     0,
+      50,     0,     0,     0,    43,     0,   198,   207,    83,   238,
+     137,   156,   158,     0,   113,   160,   161,     0,   183,   184,
+     185,     0,     0,     0,     0,     0,    82,     0,    63,    64,
+       0,    44,     0,   162,   180,     0,   181,   173,   175,   174,
+       0,     0,    60,     0,     0,   186,   187,     0,     0,     0,
+     170,     0,     0,   165,   176,   178,   177,     0,     0,     0,
+      51,     0,   163,    62
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -280,  -280,  -280,  -280,  -280,  -280,  -280,  -280,  -126,  -280,
-    -170,   203,  -280,  -280,  -279,  -280,  -280,  -280,  -280,  -280,
-    -280,  -229,   233,  -280,  -280,  -280,  -280,  -280,  -280,  -280,
-    -280,    42,   -41,  -280,  -280,  -280,   322,  -280,   534,  -280,
-    -280,   469,   256,   462,     0,   537,  -280,  -280,   426,  -280,
-    -103,  -280,  -280,  -181,   180,  -164,    -7,  -280,  -280,  -280,
-    -280,  -280,  -280,  -280,    74,    41,  -280,  -280,  -280,  -280,
-    -280,  -280,   101,    78,  -280,  -280,   -62,  -280,  -150,   305,
-     310,   393,   -35,   435,   433,   490,  -280,  -280,  -162,  -280,
-    -280,  -280,  -280,  -280,   390,  -280,   458,   396,  -248,  -217,
-     461,   159,  -139,  -280,  -280,  -280,  -280,  -280,  -144,    -4,
-    -280,  -280,  -280
+    -257,  -257,  -257,  -257,  -257,  -257,  -257,  -257,  -105,  -257,
+    -182,  -257,   234,   279,  -257,  -257,  -255,  -257,  -257,  -257,
+    -257,  -257,  -257,  -256,   304,  -257,  -257,  -257,  -257,  -257,
+    -257,  -257,  -257,     5,   -40,  -257,  -257,  -257,   397,  -257,
+     591,  -257,  -257,   543,   258,   539,   -50,   597,  -257,  -257,
+     515,  -257,  -101,  -257,  -257,  -180,   270,  -191,   -10,  -257,
+    -257,  -257,  -257,  -257,  -257,  -257,   159,   118,  -257,  -257,
+    -257,  -257,  -257,  -257,   184,   160,  -257,  -257,   100,  -257,
+    -131,   398,   392,   482,   -15,   521,   517,   572,  -257,  -257,
+    -142,  -257,  -257,  -257,  -257,  -257,   471,  -257,   540,   476,
+    -222,  -187,   541,   247,  -109,  -257,  -257,  -257,  -257,  -257,
+    -129,    -4,  -257,  -257,  -257
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    14,    15,    16,    17,    18,    19,    20,   207,   208,
-     102,   383,   384,   385,   278,   373,   374,   289,   443,   488,
-     536,   281,   282,   283,   284,   285,   286,   440,   484,    21,
-      22,    65,   138,    23,    24,   188,   189,    25,    58,    26,
-      46,    47,   165,    28,    29,    44,   103,   104,   105,   169,
-     106,   339,   334,   244,   245,   328,   329,   246,   341,   421,
-     470,   500,   520,   521,   522,   343,   344,   425,   475,   476,
-     530,   556,   501,   502,   526,   542,   144,   145,   213,   214,
-     215,   216,   217,   108,   109,   110,   111,   112,   113,   114,
-     115,   116,   117,   223,   224,   153,   154,   227,   265,   118,
-     236,   313,   119,   369,   310,   120,   174,   179,   194,   121,
-     367,    30,    31
+      -1,    14,    15,    16,    17,    18,    19,    20,   185,   186,
+     230,   231,   452,   360,   361,   362,   254,   350,   351,   265,
+     423,   471,   520,   257,   258,   259,   260,   261,   262,   420,
+     467,    21,    22,    65,   121,    23,    24,   166,   167,    25,
+      58,    26,    46,    47,   144,    28,    29,    44,    86,    87,
+      88,   147,    89,   313,   308,   220,   221,   302,   303,   222,
+     315,   397,   449,   483,   504,   505,   506,   320,   321,   405,
+     458,   459,   514,   540,   485,   486,   510,   526,   127,   128,
+     191,   192,   193,   194,   195,    91,    92,    93,    94,    95,
+      96,    97,    98,    99,   100,   201,   202,   136,   137,   205,
+     241,   101,   213,   289,   102,   346,   286,   103,   152,   157,
+     172,   104,   344,    30,    31
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -1092,435 +1070,267 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      36,   221,   312,   220,   218,    48,   247,    45,    49,   107,
-     255,   372,   218,    33,   346,    34,    33,   358,    34,   359,
-      56,   193,    33,    33,    34,    34,   140,   134,    63,   297,
-      56,   297,   186,    68,    69,    70,    71,    72,   527,   292,
-     360,   337,    33,   297,    34,   152,   299,   300,   301,   302,
-     303,   304,   305,   306,   307,   308,   161,   171,   172,   131,
-     297,   326,   295,   176,   177,   243,   166,   171,   172,   553,
-     462,   218,   148,   218,   273,    42,   171,   172,    67,   361,
-     247,   132,   528,   336,   171,   172,    37,   473,   171,   172,
-      60,   534,   181,    61,   474,    56,   397,   436,   205,    32,
-     437,   438,    39,   175,    10,   551,    43,   249,   294,   362,
-     363,    41,   133,   554,   225,   309,    48,   225,   190,    49,
-     228,   195,   146,   197,   535,   552,   267,   238,   200,   201,
-      64,    38,   182,   338,   147,   107,    10,   206,   209,   243,
-     240,    40,   364,   195,   135,   136,   454,   257,   463,   368,
-     187,   405,   264,   187,   415,   271,    10,   242,   218,   218,
-     365,   446,   485,   529,   248,   375,   242,   258,   196,   251,
-     386,   467,   477,   247,   471,   418,   256,   296,   315,   259,
-     439,   398,   260,   456,   510,   241,     1,   316,     2,   151,
-     319,   178,   222,   403,   555,   241,   209,   272,   279,   280,
-     287,   222,   428,   492,   461,   376,   395,    57,    66,   202,
-     203,   431,   143,   218,    33,    50,    34,     3,   274,   171,
-     172,   433,    53,   266,    33,    62,    34,   264,    51,   330,
-      52,    59,   243,   350,     4,     5,   331,   230,   248,    49,
-     312,   377,     6,    49,   275,   332,   453,     7,   389,   390,
-     391,   378,   247,   327,   507,    54,    27,   122,   171,   172,
-      35,   231,   190,   123,    64,   125,   351,     8,   333,   124,
-     468,   324,    10,   393,   127,   396,   232,   233,   276,   533,
-     402,   218,    55,   366,   370,   478,   479,   209,   407,   452,
-     379,    10,   137,     9,   130,   489,   482,   171,   172,   139,
-     234,   380,   491,    10,   409,   277,   218,   381,   142,   126,
-     392,   243,   141,   427,   171,   172,   143,   406,   155,    11,
-     410,   149,   156,    49,   150,   235,    12,   330,   382,    13,
-     157,   248,   171,   172,   331,    49,   171,   172,   158,  -138,
-     269,   270,   159,   332,    33,   524,    34,   516,   321,   290,
-     291,   195,   162,   287,   314,   270,   450,   163,   218,   264,
-     167,   195,    33,   164,    34,   168,   333,   170,   458,   525,
-     347,   348,   356,   357,   180,    78,    79,   448,   183,   171,
-     172,   399,   400,   192,   264,    82,   199,   264,   426,   348,
-     204,   173,    83,    84,   229,    85,   434,   435,   480,   270,
-      86,   481,   270,   494,   348,   558,   505,   270,   219,    88,
-     248,   506,   270,   563,   513,   348,   264,   239,   493,   514,
-     400,   532,   357,    89,   254,   195,   195,   548,   357,   564,
-     270,   370,    92,   566,   270,   268,   288,   503,   297,   311,
-     298,    33,    73,    34,    74,   320,   322,   323,   325,   342,
-     335,    94,   340,   345,   352,   353,   512,   354,    75,    76,
-     261,    95,   371,   503,   355,   401,   394,    97,    98,   404,
-     408,   411,    78,    79,   414,   412,   413,    99,   416,   287,
-      80,    81,    82,   100,   417,   419,   511,   422,   503,    83,
-      84,   420,    85,   423,   424,   186,   262,    86,   429,   430,
-     442,   444,   441,    87,   287,   445,    88,   447,   451,   457,
-     455,   459,   460,   465,   472,   538,   466,   469,   486,   487,
-      89,    90,   496,   497,   498,   499,    91,   547,   483,    92,
-     490,   504,    93,   348,   508,   299,   300,   301,   302,   303,
-     304,   305,   306,   307,   308,   195,   171,   172,    94,   509,
-     515,   518,   523,   195,   531,   541,   519,   537,    95,   543,
-     544,    96,   545,   546,    97,    98,    33,    73,    34,    74,
-     549,   550,   210,   560,    99,   557,   559,   567,   561,   562,
-     100,   568,   569,    75,    76,   101,   263,   449,   349,   128,
-     432,   198,   191,   129,   464,   539,   250,    78,    79,   517,
-     565,   540,   387,   293,   309,    80,    81,    82,   388,   252,
-     185,   226,   253,   317,    83,    84,   495,    85,     0,   318,
-     237,     0,    86,     0,     0,     0,     0,   211,    87,     0,
-       0,    88,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    89,    90,     0,     0,     0,
-       0,    91,     0,     0,    92,     0,     0,    93,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    94,     0,    33,    73,    34,    74,     0,
-      10,   210,     0,    95,     0,     0,    96,     0,     0,    97,
-      98,     0,    75,    76,     0,     0,     0,     0,     0,    99,
-       0,     0,     0,     0,     0,   100,    78,    79,     0,     0,
-     212,     0,     0,     0,    80,    81,    82,     0,     0,     0,
-       0,     0,     0,    83,    84,     0,    85,     0,     0,     0,
-       0,    86,     0,     0,     0,     0,   211,    87,     0,     0,
-      88,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    89,    90,     0,     0,     0,     0,
-      91,     0,     0,    92,     0,     0,    93,     0,     0,     0,
-       0,     0,    33,    73,    34,    74,     0,     0,     0,     0,
-       0,     0,    94,     0,     0,     0,     0,     0,     0,    75,
-      76,    77,    95,     0,     0,    96,     0,     0,    97,    98,
-       0,     0,     0,    78,    79,     0,     0,     0,    99,     0,
-       0,    80,    81,    82,   100,     0,     0,     0,     0,   212,
-      83,    84,     0,    85,     0,     0,     0,     0,    86,     0,
-       0,     0,     0,     0,    87,     0,     0,    88,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    89,    90,     0,     0,     0,     0,    91,     0,     0,
-      92,     0,     0,    93,     0,     0,     0,     0,     0,    33,
-      73,    34,    74,     0,     0,     0,     0,     0,     0,    94,
-       0,     0,     0,     0,     0,     0,    75,    76,     0,    95,
-       0,     0,    96,     0,     0,    97,    98,     0,     0,     0,
-      78,    79,     0,     0,     0,    99,     0,     0,    80,    81,
-      82,   100,     0,     0,     0,     0,   101,    83,    84,     0,
-      85,     0,     0,     0,     0,    86,     0,     0,     0,     0,
-       0,    87,     0,     0,    88,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    89,    90,
-       0,     0,     0,     0,    91,     0,     0,    92,     0,     0,
-      93,     0,     0,     0,     0,     0,    33,    73,    34,    74,
-       0,     0,     0,     0,     0,     0,    94,     0,     0,     0,
-       0,     0,     0,    75,    76,     0,    95,     0,     0,    96,
-       0,     0,    97,    98,     0,     0,     0,    78,    79,     0,
-       0,     0,    99,   151,     0,    80,    81,    82,   100,     0,
-       0,     0,     0,   101,    83,    84,     0,    85,     0,     0,
-       0,     0,    86,     0,     0,     0,     0,     0,    87,     0,
-       0,    88,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    89,    90,     0,     0,     0,
-       0,    91,     0,     0,    92,     0,     0,    93,     0,     0,
-       0,     0,     0,    33,    73,    34,    74,     0,     0,     0,
-       0,     0,   160,    94,     0,     0,     0,     0,     0,     0,
-      75,    76,     0,    95,     0,     0,    96,     0,     0,    97,
-      98,     0,     0,     0,    78,    79,     0,     0,     0,    99,
-       0,     0,    80,    81,    82,   100,     0,     0,     0,     0,
-     101,    83,    84,     0,    85,     0,     0,     0,     0,    86,
-       0,     0,     0,     0,     0,    87,     0,     0,    88,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    89,    90,     0,     0,     0,     0,    91,     0,
-       0,    92,     0,     0,    93,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      94,     0,    33,    73,    34,    74,     0,    10,     0,     0,
-      95,     0,     0,    96,     0,     0,    97,    98,     0,    75,
-      76,     0,     0,     0,     0,     0,    99,     0,     0,     0,
-       0,     0,   100,    78,    79,     0,     0,   101,     0,     0,
-       0,    80,    81,    82,     0,     0,     0,     0,     0,     0,
-      83,    84,     0,    85,     0,     0,     0,     0,    86,     0,
-       0,     0,     0,   211,    87,     0,     0,    88,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    89,    90,     0,     0,     0,     0,    91,     0,     0,
-      92,     0,     0,    93,     0,     0,     0,     0,     0,    33,
-      73,    34,    74,     0,     0,     0,     0,     0,     0,    94,
-       0,     0,     0,     0,     0,     0,    75,   184,     0,    95,
-       0,     0,    96,     0,     0,    97,    98,     0,     0,     0,
-      78,    79,     0,     0,     0,    99,     0,     0,    80,    81,
-      82,   100,     0,     0,     0,     0,   212,    83,    84,     0,
-      85,     0,     0,     0,     0,    86,     0,     0,     0,     0,
-       0,    87,     0,     0,    88,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    89,    90,
-       0,     0,     0,     0,    91,     0,     0,    92,     0,     0,
-      93,     0,     0,     0,     0,     0,    33,    73,    34,    74,
-       0,     0,     0,     0,     0,     0,    94,     0,     0,     0,
-       0,     0,     0,    75,    76,     0,    95,     0,     0,    96,
-       0,     0,    97,    98,     0,     0,     0,    78,    79,     0,
-       0,     0,    99,     0,     0,    80,    81,    82,   100,     0,
-       0,     0,     0,   101,    83,    84,     0,    85,     0,     0,
-       0,     0,    86,     0,     0,     0,     0,     0,    87,     0,
-       0,    88,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    89,    90,    73,     0,    74,
-       0,    91,     0,     0,    92,     0,     0,    93,     0,     0,
-       0,     0,     0,    75,   184,     0,     0,     0,     0,     0,
-       0,     0,     0,    94,     0,     0,     0,    78,    79,     0,
-       0,     0,     0,    95,     0,     0,    96,    82,     0,    97,
-      98,     0,     0,     0,    83,    84,     0,    85,     0,    99,
-       0,     0,    86,     0,     0,   100,     0,     0,     0,     0,
-     101,    88,     0,     0,     0,     0,     0,     0,    78,    79,
-       0,     0,     0,     0,     0,    89,    90,     0,    82,     0,
-       0,     0,     0,     0,    92,    83,    84,    93,    85,     0,
-       0,     0,     0,    86,     0,     0,     0,     0,     0,     0,
-       0,     0,    88,    94,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    95,     0,     0,    89,   254,     0,    97,
-      98,     0,     0,     0,     0,    92,     0,     0,     0,    99,
-       0,     0,     0,     0,     0,   100,     0,     0,     0,     0,
-       0,     0,     0,     0,    94,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    95,     0,     0,     0,     0,     0,
-      97,    98,     0,     0,     0,     0,     0,     0,     0,     0,
-      99,     0,     0,     0,     0,     0,   100
+      36,   198,    48,   199,   223,   268,   171,    45,    49,   114,
+     288,   349,    56,    33,   273,    34,   323,   196,    33,   273,
+      34,    33,   131,    34,   273,   196,   273,   123,    63,    90,
+     154,   155,   310,    68,    69,    70,    71,    72,   300,    56,
+     374,    67,   149,   150,    66,   219,   275,   276,   277,   278,
+     279,   280,   281,   282,   283,   284,   511,   149,   150,   271,
+     149,   150,   159,   135,    56,   149,   150,   142,   537,   518,
+     145,   178,   179,   249,    10,   164,   223,    37,    33,   196,
+      34,   196,   183,    42,   117,   535,   153,   450,   270,   129,
+      33,   311,    34,   149,   150,    64,    48,   160,   512,   130,
+     519,   168,    49,   536,   173,   299,   175,   301,   285,    43,
+     538,    57,   149,   150,   174,   382,   375,   219,    10,    38,
+     184,   187,   394,   206,    39,   248,   173,    64,   215,   391,
+     399,   401,   291,    90,   247,   398,   400,    33,   335,    34,
+     336,   363,   224,   218,   156,   233,   460,   227,   218,   434,
+     240,   234,    32,   494,   232,   345,   217,   235,   203,   353,
+     236,   337,   352,   451,   196,   196,   468,   223,   426,   513,
+     216,   217,   312,   446,   187,   272,   255,   256,   263,   440,
+     454,   539,   165,   232,   372,   292,   441,   165,   295,   433,
+     436,   118,   119,   354,   338,    10,   250,   200,   408,    40,
+     355,   149,   150,   411,   203,   115,   207,   380,   219,   475,
+     491,   149,   150,   413,   224,    49,    53,   251,   304,    49,
+     196,   339,   340,   240,   508,   305,   134,   208,   416,   327,
+     116,   417,   418,   306,    41,   356,   517,    73,   168,    74,
+     209,   210,   328,   509,    54,    50,   357,   225,   223,   252,
+     288,   341,   358,    75,   162,   307,    59,   442,    27,   343,
+     347,   106,    35,   187,   211,   447,   243,   342,   432,   370,
+     359,   373,   200,   253,    60,   456,   379,    61,    10,    62,
+     461,   462,   457,   383,    55,   212,   385,   196,   126,   219,
+      33,   386,    34,   232,   472,   149,   150,    49,   242,   105,
+     366,   367,   368,   419,   107,   224,   465,   297,    81,    49,
+     407,   109,   108,   232,   232,    51,   196,    52,    83,    33,
+      73,    34,    74,   180,   181,   188,    10,   474,   173,   110,
+     263,   149,   150,   245,   246,   120,    75,    76,   173,   149,
+     150,   266,   267,    33,    73,    34,    74,   290,   246,   500,
+     316,   317,   113,   430,   428,   369,   240,    78,    79,   122,
+      75,    76,   237,   324,   325,   438,    33,    73,    34,    74,
+     124,   196,   333,   334,   189,    80,   376,   377,   406,   325,
+     240,    78,    79,    75,   162,   125,   224,   240,   414,   415,
+      33,    81,    34,   238,   463,   246,    82,   464,   246,    80,
+     132,    83,   304,   126,   542,   173,   173,   149,   150,   305,
+     133,   347,   547,  -129,   138,    81,   240,   306,   476,   151,
+      82,   140,   477,   325,    10,    83,   489,   246,   139,    84,
+     490,   246,   497,   325,   498,   377,   516,   334,    81,   307,
+     487,   532,   334,   548,   246,   146,   550,   246,    83,   190,
+     143,   158,   161,    84,   170,   148,   177,   182,   197,   496,
+     264,   244,   263,   273,   287,   274,   487,   296,   298,   495,
+     309,   318,   314,    85,   239,   319,    33,    73,    34,    74,
+     322,   329,   188,    33,    73,    34,    74,   330,   263,   331,
+     332,   348,   487,    75,    76,    33,    73,    34,    74,   522,
+      75,    76,    77,   371,   378,   381,   384,    33,    73,    34,
+      74,   531,    75,    76,    78,    79,   387,   388,   389,   390,
+     392,    78,    79,   393,    75,    76,   395,   396,   402,   173,
+     403,   189,    80,    78,    79,   404,   164,   173,   424,    80,
+     409,   410,   422,   427,   435,    78,    79,   421,    81,   425,
+     448,    80,   431,    82,   437,    81,   439,   444,    83,   455,
+      82,   445,   466,    80,   469,    83,   470,    81,   473,   479,
+     480,   325,    82,    33,    73,    34,    74,    83,   481,    81,
+      33,    73,    34,    74,    82,   482,    84,   484,   492,    83,
+      75,    76,   488,    84,   493,   502,   499,    75,    76,   507,
+     515,   503,   521,   527,   141,    84,   190,   525,   529,   528,
+     530,    78,    79,    85,   533,   534,   134,    84,    78,    79,
+     541,   544,   543,   546,   545,    85,   551,   552,   553,    80,
+      33,    73,    34,    74,   453,   189,    80,    85,   412,   326,
+     429,    33,    73,    34,    74,    81,   111,    75,   162,   169,
+      82,   176,    81,   112,     1,    83,     2,    82,    75,    76,
+     443,   549,    83,   226,   523,   501,   365,   524,    78,    79,
+     269,   364,   293,   228,   229,   163,   204,   294,    10,    78,
+      79,   214,     0,    84,   478,     3,    80,     0,     0,     0,
+      84,     0,     0,     0,     0,     0,     0,    80,     0,     0,
+       4,     5,    81,    85,     0,     6,     0,    82,     0,     7,
+     190,     0,    83,    81,     0,     0,     0,     0,    82,     0,
+       0,     0,     0,    83,     0,     0,     0,     0,     8,     0,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+      84,   149,   150,     0,     0,     0,     0,     0,     0,     0,
+       0,    84,     9,     0,     0,     0,     0,     0,     0,     0,
+      85,     0,    10,     0,     0,     0,     0,     0,     0,     0,
+       0,    85,     0,     0,     0,    11,     0,     0,     0,     0,
+       0,    12,     0,    13,     0,     0,     0,     0,     0,     0,
+       0,     0,   285
 };
 
 static const yytype_int16 yycheck[] =
 {
-       4,   151,   219,   147,   143,    12,   168,    11,    12,    44,
-     180,   290,   151,     4,   262,     6,     4,     5,     6,     7,
-      29,   124,     4,     4,     6,     6,    67,     5,    32,     8,
-      29,     8,    27,    37,    38,    39,    40,    41,     7,   209,
-      28,    39,     4,     8,     6,    80,    10,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,    91,    21,    22,    59,
-       8,   242,   212,    23,    24,   168,   101,    21,    22,     7,
-      71,   210,    72,   212,   200,    28,    21,    22,    36,    67,
-     242,    31,    51,   247,    21,    22,    80,   109,    21,    22,
-     144,    76,   110,   147,   116,    29,    10,    37,   139,   125,
-      40,    41,    73,   107,   118,    68,    59,   169,   211,    97,
-      98,    85,    62,    51,    63,    79,   123,    63,   122,   123,
-     155,   125,   136,   127,   109,    88,   188,   162,    47,    48,
-     129,   125,   150,   131,   148,   170,   118,   141,   142,   242,
-     149,   125,   130,   147,   122,   123,   394,   182,   149,   288,
-     148,   321,   187,   148,   335,   196,   118,   148,   297,   298,
-     148,   378,   441,   132,   168,   291,   148,   148,   126,   173,
-     149,   419,   149,   335,   422,   339,   180,   212,   126,   183,
-     120,    95,   186,   400,   149,   149,     1,   222,     3,   138,
-     225,   151,   138,   126,   132,   149,   200,   197,   202,   203,
-     204,   138,   352,   451,   149,    10,   309,   141,    73,    47,
-      48,   355,   139,   352,     4,     0,     6,    32,    46,    21,
-      22,   365,    49,   150,     4,     3,     6,   262,   144,    74,
-     146,    30,   335,   268,    49,    50,    81,    54,   242,   243,
-     457,    46,    57,   247,    72,    90,     9,    62,    17,    18,
-      19,    56,   414,    33,   483,    82,     0,   119,    21,    22,
-       4,    78,   266,   150,   129,   148,   270,    82,   113,    33,
-     420,    73,   118,   308,    85,   310,    93,    94,   106,   508,
-     315,   420,    26,   287,   288,   429,   430,   291,   323,   392,
-      95,   118,   141,   108,   107,   445,   435,    21,    22,     5,
-     117,   106,     9,   118,   149,   133,   445,   112,   148,    53,
-      79,   414,    98,   348,    21,    22,   139,   321,   148,   134,
-     327,     7,   148,   327,     7,   142,   141,    74,   133,   144,
-      84,   335,    21,    22,    81,   339,    21,    22,   148,    86,
-     149,   150,     5,    90,     4,    34,     6,   497,    33,   149,
-     150,   355,   148,   357,   149,   150,   391,   148,   497,   394,
-       5,   365,     4,    84,     6,    73,   113,   150,   403,    58,
-     149,   150,   149,   150,    61,    35,    36,   381,   101,    21,
-      22,   149,   150,   148,   419,    45,     7,   422,   149,   150,
-     148,    33,    52,    53,     7,    55,   149,   150,   149,   150,
-      60,   149,   150,   149,   150,   549,   149,   150,   148,    69,
-     414,   149,   150,   557,   149,   150,   451,     7,   453,   149,
-     150,   149,   150,    83,    84,   429,   430,   149,   150,   149,
-     150,   435,    92,   149,   150,    11,   148,   472,     8,    20,
-       9,     4,     5,     6,     7,    64,   149,    73,   149,   102,
-     150,   111,    75,   149,   148,    87,   491,    87,    21,    22,
-      23,   121,   135,   498,   148,   136,   148,   127,   128,    64,
-       7,   100,    35,    36,    86,   100,   100,   137,     7,   483,
-      43,    44,    45,   143,     7,    42,   490,    42,   523,    52,
-      53,    77,    55,   149,    99,    27,    59,    60,   148,   148,
-     141,    95,   150,    66,   508,   148,    69,    87,   148,   148,
-      95,   149,   149,   104,    42,   519,   104,    99,    38,   102,
-      83,    84,     7,    98,    42,    91,    89,   531,   148,    92,
-     148,    19,    95,   150,   148,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,   549,    21,    22,   111,    42,
-     149,     7,   150,   557,   112,    96,   140,   149,   121,   105,
-     114,   124,   105,     9,   127,   128,     4,     5,     6,     7,
-     148,    33,    10,    70,   137,   148,   148,   103,   114,    70,
-     143,   149,     7,    21,    22,   148,   149,   384,   266,    55,
-     357,   129,   123,    56,   414,   521,   170,    35,    36,   498,
-     559,   523,   297,   210,    79,    43,    44,    45,   298,   174,
-     120,   153,   179,   223,    52,    53,   457,    55,    -1,   223,
-     159,    -1,    60,    -1,    -1,    -1,    -1,    65,    66,    -1,
-      -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    83,    84,    -1,    -1,    -1,
-      -1,    89,    -1,    -1,    92,    -1,    -1,    95,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   111,    -1,     4,     5,     6,     7,    -1,
-     118,    10,    -1,   121,    -1,    -1,   124,    -1,    -1,   127,
-     128,    -1,    21,    22,    -1,    -1,    -1,    -1,    -1,   137,
-      -1,    -1,    -1,    -1,    -1,   143,    35,    36,    -1,    -1,
-     148,    -1,    -1,    -1,    43,    44,    45,    -1,    -1,    -1,
-      -1,    -1,    -1,    52,    53,    -1,    55,    -1,    -1,    -1,
-      -1,    60,    -1,    -1,    -1,    -1,    65,    66,    -1,    -1,
-      69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    83,    84,    -1,    -1,    -1,    -1,
-      89,    -1,    -1,    92,    -1,    -1,    95,    -1,    -1,    -1,
-      -1,    -1,     4,     5,     6,     7,    -1,    -1,    -1,    -1,
-      -1,    -1,   111,    -1,    -1,    -1,    -1,    -1,    -1,    21,
-      22,    23,   121,    -1,    -1,   124,    -1,    -1,   127,   128,
-      -1,    -1,    -1,    35,    36,    -1,    -1,    -1,   137,    -1,
-      -1,    43,    44,    45,   143,    -1,    -1,    -1,    -1,   148,
-      52,    53,    -1,    55,    -1,    -1,    -1,    -1,    60,    -1,
-      -1,    -1,    -1,    -1,    66,    -1,    -1,    69,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    83,    84,    -1,    -1,    -1,    -1,    89,    -1,    -1,
-      92,    -1,    -1,    95,    -1,    -1,    -1,    -1,    -1,     4,
-       5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,   111,
-      -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    -1,   121,
-      -1,    -1,   124,    -1,    -1,   127,   128,    -1,    -1,    -1,
-      35,    36,    -1,    -1,    -1,   137,    -1,    -1,    43,    44,
-      45,   143,    -1,    -1,    -1,    -1,   148,    52,    53,    -1,
-      55,    -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,
-      -1,    66,    -1,    -1,    69,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    83,    84,
-      -1,    -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,
-      95,    -1,    -1,    -1,    -1,    -1,     4,     5,     6,     7,
-      -1,    -1,    -1,    -1,    -1,    -1,   111,    -1,    -1,    -1,
-      -1,    -1,    -1,    21,    22,    -1,   121,    -1,    -1,   124,
-      -1,    -1,   127,   128,    -1,    -1,    -1,    35,    36,    -1,
-      -1,    -1,   137,   138,    -1,    43,    44,    45,   143,    -1,
-      -1,    -1,    -1,   148,    52,    53,    -1,    55,    -1,    -1,
-      -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,    66,    -1,
-      -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    83,    84,    -1,    -1,    -1,
-      -1,    89,    -1,    -1,    92,    -1,    -1,    95,    -1,    -1,
-      -1,    -1,    -1,     4,     5,     6,     7,    -1,    -1,    -1,
-      -1,    -1,   110,   111,    -1,    -1,    -1,    -1,    -1,    -1,
-      21,    22,    -1,   121,    -1,    -1,   124,    -1,    -1,   127,
-     128,    -1,    -1,    -1,    35,    36,    -1,    -1,    -1,   137,
-      -1,    -1,    43,    44,    45,   143,    -1,    -1,    -1,    -1,
-     148,    52,    53,    -1,    55,    -1,    -1,    -1,    -1,    60,
-      -1,    -1,    -1,    -1,    -1,    66,    -1,    -1,    69,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    83,    84,    -1,    -1,    -1,    -1,    89,    -1,
-      -1,    92,    -1,    -1,    95,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     111,    -1,     4,     5,     6,     7,    -1,   118,    -1,    -1,
-     121,    -1,    -1,   124,    -1,    -1,   127,   128,    -1,    21,
-      22,    -1,    -1,    -1,    -1,    -1,   137,    -1,    -1,    -1,
-      -1,    -1,   143,    35,    36,    -1,    -1,   148,    -1,    -1,
-      -1,    43,    44,    45,    -1,    -1,    -1,    -1,    -1,    -1,
-      52,    53,    -1,    55,    -1,    -1,    -1,    -1,    60,    -1,
-      -1,    -1,    -1,    65,    66,    -1,    -1,    69,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    83,    84,    -1,    -1,    -1,    -1,    89,    -1,    -1,
-      92,    -1,    -1,    95,    -1,    -1,    -1,    -1,    -1,     4,
-       5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,   111,
-      -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    -1,   121,
-      -1,    -1,   124,    -1,    -1,   127,   128,    -1,    -1,    -1,
-      35,    36,    -1,    -1,    -1,   137,    -1,    -1,    43,    44,
-      45,   143,    -1,    -1,    -1,    -1,   148,    52,    53,    -1,
-      55,    -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,
-      -1,    66,    -1,    -1,    69,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    83,    84,
-      -1,    -1,    -1,    -1,    89,    -1,    -1,    92,    -1,    -1,
-      95,    -1,    -1,    -1,    -1,    -1,     4,     5,     6,     7,
-      -1,    -1,    -1,    -1,    -1,    -1,   111,    -1,    -1,    -1,
-      -1,    -1,    -1,    21,    22,    -1,   121,    -1,    -1,   124,
-      -1,    -1,   127,   128,    -1,    -1,    -1,    35,    36,    -1,
-      -1,    -1,   137,    -1,    -1,    43,    44,    45,   143,    -1,
-      -1,    -1,    -1,   148,    52,    53,    -1,    55,    -1,    -1,
-      -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,    66,    -1,
-      -1,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    83,    84,     5,    -1,     7,
-      -1,    89,    -1,    -1,    92,    -1,    -1,    95,    -1,    -1,
-      -1,    -1,    -1,    21,    22,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   111,    -1,    -1,    -1,    35,    36,    -1,
-      -1,    -1,    -1,   121,    -1,    -1,   124,    45,    -1,   127,
-     128,    -1,    -1,    -1,    52,    53,    -1,    55,    -1,   137,
-      -1,    -1,    60,    -1,    -1,   143,    -1,    -1,    -1,    -1,
-     148,    69,    -1,    -1,    -1,    -1,    -1,    -1,    35,    36,
-      -1,    -1,    -1,    -1,    -1,    83,    84,    -1,    45,    -1,
-      -1,    -1,    -1,    -1,    92,    52,    53,    95,    55,    -1,
-      -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    69,   111,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   121,    -1,    -1,    83,    84,    -1,   127,
-     128,    -1,    -1,    -1,    -1,    92,    -1,    -1,    -1,   137,
-      -1,    -1,    -1,    -1,    -1,   143,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,   111,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,   121,    -1,    -1,    -1,    -1,    -1,
-     127,   128,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     137,    -1,    -1,    -1,    -1,    -1,   143
+       4,   130,    12,   134,   146,   187,   107,    11,    12,    59,
+     197,   266,    29,     4,     8,     6,   238,   126,     4,     8,
+       6,     4,    72,     6,     8,   134,     8,    67,    32,    44,
+      23,    24,   223,    37,    38,    39,    40,    41,   218,    29,
+      10,    36,    21,    22,    66,   146,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,     7,    21,    22,   190,
+      21,    22,   101,    78,    29,    21,    22,    82,     7,    69,
+      85,    45,    46,   178,   109,    27,   218,    73,     4,   188,
+       6,   190,   122,    28,     5,    62,    90,    10,   189,   124,
+       4,    38,     6,    21,    22,   117,   106,   136,    49,   134,
+     100,   105,   106,    80,   108,    66,   110,    33,    72,    54,
+      49,   128,    21,    22,   109,   297,    86,   218,   109,   115,
+     124,   125,   313,   138,    66,   175,   130,   117,   143,   309,
+     317,   318,   116,   148,   174,   317,   318,     4,     5,     6,
+       7,   135,   146,   134,   137,   160,   135,   151,   134,   371,
+     165,   134,   115,   135,   158,   264,   135,   161,    57,    10,
+     164,    28,   267,    86,   273,   274,   421,   309,   355,   120,
+     135,   135,   119,   395,   178,   190,   180,   181,   182,   135,
+     402,   120,   134,   187,   285,   200,    64,   134,   203,     9,
+     377,   112,   113,    44,    61,   109,    44,   125,   329,   115,
+      51,    21,    22,   332,    57,    31,    50,   116,   309,   431,
+     466,    21,    22,   342,   218,   219,    47,    65,    67,   223,
+     329,    88,    89,   238,    34,    74,   125,    71,    36,   244,
+      56,    39,    40,    82,    77,    86,   492,     5,   242,     7,
+      84,    85,   246,    53,    75,     0,    97,   147,   390,    97,
+     437,   118,   103,    21,    22,   104,    30,   135,     0,   263,
+     264,   136,     4,   267,   108,   396,   166,   134,   369,   284,
+     121,   286,   125,   121,   130,   100,   291,   133,   109,     3,
+     409,   410,   107,   298,    26,   129,   135,   396,   126,   390,
+       4,   301,     6,   297,   425,    21,    22,   301,   136,   110,
+      17,    18,    19,   111,    33,   309,   415,    33,    76,   313,
+     325,    53,   134,   317,   318,   130,   425,   132,    86,     4,
+       5,     6,     7,    45,    46,    10,   109,     9,   332,    77,
+     334,    21,    22,   135,   136,   128,    21,    22,   342,    21,
+      22,   135,   136,     4,     5,     6,     7,   135,   136,   480,
+     135,   136,    98,   368,   358,    72,   371,    42,    43,     5,
+      21,    22,    23,   135,   136,   380,     4,     5,     6,     7,
+      89,   480,   135,   136,    59,    60,   135,   136,   135,   136,
+     395,    42,    43,    21,    22,   134,   390,   402,   135,   136,
+       4,    76,     6,    54,   135,   136,    81,   135,   136,    60,
+       7,    86,    67,   126,   533,   409,   410,    21,    22,    74,
+       7,   415,   541,    78,   134,    76,   431,    82,   433,    33,
+      81,     5,   135,   136,   109,    86,   135,   136,   134,   114,
+     135,   136,   135,   136,   135,   136,   135,   136,    76,   104,
+     455,   135,   136,   135,   136,    66,   135,   136,    86,   134,
+     134,    55,    92,   114,   134,   136,     7,   134,   134,   474,
+     134,    11,   466,     8,    20,     9,   481,    58,    66,   473,
+     136,   134,    68,   134,   135,    93,     4,     5,     6,     7,
+     135,   134,    10,     4,     5,     6,     7,    79,   492,    79,
+     134,   123,   507,    21,    22,     4,     5,     6,     7,   503,
+      21,    22,    23,   134,   124,    58,     7,     4,     5,     6,
+       7,   515,    21,    22,    42,    43,    91,    91,    91,    78,
+       7,    42,    43,     7,    21,    22,    41,    70,    41,   533,
+     135,    59,    60,    42,    43,    90,    27,   541,    86,    60,
+     134,   134,   128,    79,    86,    42,    43,   136,    76,   134,
+      90,    60,   134,    81,   134,    76,   135,    95,    86,    41,
+      81,    95,   134,    60,    37,    86,    93,    76,   134,     7,
+      89,   136,    81,     4,     5,     6,     7,    86,    41,    76,
+       4,     5,     6,     7,    81,    83,   114,    86,   134,    86,
+      21,    22,    19,   114,    41,     7,   135,    21,    22,   136,
+     103,   127,   135,    96,   101,   114,   134,    87,    96,   105,
+       9,    42,    43,   134,   134,    33,   125,   114,    42,    43,
+     134,    63,   134,    63,   105,   134,    94,   135,     7,    60,
+       4,     5,     6,     7,   400,    59,    60,   134,   334,   242,
+     361,     4,     5,     6,     7,    76,    55,    21,    22,   106,
+      81,   112,    76,    56,     1,    86,     3,    81,    21,    22,
+     390,   543,    86,   148,   505,   481,   274,   507,    42,    43,
+     188,   273,   201,   152,   157,   103,   136,   201,   109,    42,
+      43,   140,    -1,   114,   437,    32,    60,    -1,    -1,    -1,
+     114,    -1,    -1,    -1,    -1,    -1,    -1,    60,    -1,    -1,
+      47,    48,    76,   134,    -1,    52,    -1,    81,    -1,    56,
+     134,    -1,    86,    76,    -1,    -1,    -1,    -1,    81,    -1,
+      -1,    -1,    -1,    86,    -1,    -1,    -1,    -1,    75,    -1,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+     114,    21,    22,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   114,    99,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     134,    -1,   109,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   134,    -1,    -1,    -1,   122,    -1,    -1,    -1,    -1,
+      -1,   128,    -1,   130,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    72
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
-static const yytype_uint16 yystos[] =
+static const yytype_uint8 yystos[] =
 {
-       0,     1,     3,    32,    49,    50,    57,    62,    82,   108,
-     118,   134,   141,   144,   153,   154,   155,   156,   157,   158,
-     159,   181,   182,   185,   186,   189,   191,   194,   195,   196,
-     263,   264,   125,     4,     6,   194,   261,    80,   125,    73,
-     125,    85,    28,    59,   197,   261,   192,   193,   208,   261,
-       0,   144,   146,    49,    82,   194,    29,   141,   190,    30,
-     144,   147,     3,   261,   129,   183,    73,   183,   261,   261,
-     261,   261,   261,     5,     7,    21,    22,    23,    35,    36,
-      43,    44,    45,    52,    53,    55,    60,    66,    69,    83,
-      84,    89,    92,    95,   111,   121,   124,   127,   128,   137,
-     143,   148,   162,   198,   199,   200,   202,   234,   235,   236,
-     237,   238,   239,   240,   241,   242,   243,   244,   251,   254,
-     257,   261,   119,   150,    33,   148,   194,    85,   190,   197,
-     107,   196,    31,    62,     5,   122,   123,   141,   184,     5,
-     184,    98,   148,   139,   228,   229,   136,   148,   196,     7,
-       7,   138,   234,   247,   248,   148,   148,    84,   148,     5,
-     110,   234,   148,   148,    84,   194,   234,     5,    73,   201,
-     150,    21,    22,    33,   258,   261,    23,    24,   151,   259,
-      61,   110,   150,   101,    22,   237,    27,   148,   187,   188,
-     261,   193,   148,   202,   260,   261,   183,   261,   195,     7,
-      47,    48,    47,    48,   148,   184,   261,   160,   161,   261,
-      10,    65,   148,   230,   231,   232,   233,   234,   254,   148,
-     260,   230,   138,   245,   246,    63,   248,   249,   234,     7,
-      54,    78,    93,    94,   117,   142,   252,   252,   234,     7,
-     149,   149,   148,   202,   205,   206,   209,   240,   261,   228,
-     200,   261,   235,   236,    84,   162,   261,   234,   148,   261,
-     261,    23,    59,   149,   234,   250,   150,   228,    11,   149,
-     150,   184,   196,   160,    46,    72,   106,   133,   166,   261,
-     261,   173,   174,   175,   176,   177,   178,   261,   148,   169,
-     149,   150,   162,   233,   202,   230,   234,     8,     9,    10,
-      11,    12,    13,    14,    15,    16,    17,    18,    19,    79,
-     256,    20,   251,   253,   149,   126,   234,   246,   249,   234,
-      64,    33,   149,    73,    73,   149,   205,    33,   207,   208,
-      74,    81,    90,   113,   204,   150,   207,    39,   131,   203,
-      75,   210,   102,   217,   218,   149,   250,   149,   150,   188,
-     234,   261,   148,    87,    87,   148,   149,   150,     5,     7,
-      28,    67,    97,    98,   130,   148,   261,   262,   254,   255,
-     261,   135,   166,   167,   168,   160,    10,    46,    56,    95,
-     106,   112,   133,   163,   164,   165,   149,   231,   232,    17,
-      18,    19,    79,   234,   148,   202,   234,    10,    95,   149,
-     150,   136,   234,   126,    64,   162,   261,   234,     7,   149,
-     208,   100,   100,   100,    86,   205,     7,     7,   207,    42,
-      77,   211,    42,   149,    99,   219,   149,   234,   230,   148,
-     148,   260,   174,   260,   149,   150,    37,    40,    41,   120,
-     179,   150,   141,   170,    95,   148,   251,    87,   261,   163,
-     234,   148,   202,     9,   250,    95,   251,   148,   234,   149,
-     149,   149,    71,   149,   206,   104,   104,   250,   230,    99,
-     212,   250,    42,   109,   116,   220,   221,   149,   260,   260,
-     149,   149,   254,   148,   180,   166,    38,   102,   171,   230,
-     148,     9,   250,   234,   149,   253,     7,    98,    42,    91,
-     213,   224,   225,   234,    19,   149,   149,   173,   148,    42,
-     149,   261,   234,   149,   149,   149,   230,   224,     7,   140,
-     214,   215,   216,   150,    34,    58,   226,     7,    51,   132,
-     222,   112,   149,   173,    76,   109,   172,   149,   261,   216,
-     225,    96,   227,   105,   114,   105,     9,   261,   149,   148,
-      33,    68,    88,     7,    51,   132,   223,   148,   260,   148,
-      70,   114,    70,   260,   149,   217,   149,   103,   149,     7
+       0,     1,     3,    32,    47,    48,    52,    56,    75,    99,
+     109,   122,   128,   130,   139,   140,   141,   142,   143,   144,
+     145,   169,   170,   173,   174,   177,   179,   182,   183,   184,
+     251,   252,   115,     4,     6,   182,   249,    73,   115,    66,
+     115,    77,    28,    54,   185,   249,   180,   181,   196,   249,
+       0,   130,   132,    47,    75,   182,    29,   128,   178,    30,
+     130,   133,     3,   249,   117,   171,    66,   171,   249,   249,
+     249,   249,   249,     5,     7,    21,    22,    23,    42,    43,
+      60,    76,    81,    86,   114,   134,   186,   187,   188,   190,
+     222,   223,   224,   225,   226,   227,   228,   229,   230,   231,
+     232,   239,   242,   245,   249,   110,   136,    33,   134,   182,
+      77,   178,   185,    98,   184,    31,    56,     5,   112,   113,
+     128,   172,     5,   172,    89,   134,   126,   216,   217,   124,
+     134,   184,     7,     7,   125,   222,   235,   236,   134,   134,
+       5,   101,   222,   134,   182,   222,    66,   189,   136,    21,
+      22,    33,   246,   249,    23,    24,   137,   247,    55,   101,
+     136,    92,    22,   225,    27,   134,   175,   176,   249,   181,
+     134,   190,   248,   249,   171,   249,   183,     7,    45,    46,
+      45,    46,   134,   172,   249,   146,   147,   249,    10,    59,
+     134,   218,   219,   220,   221,   222,   242,   134,   248,   218,
+     125,   233,   234,    57,   236,   237,   222,    50,    71,    84,
+      85,   108,   129,   240,   240,   222,   135,   135,   134,   190,
+     193,   194,   197,   228,   249,   216,   188,   249,   223,   224,
+     148,   149,   249,   222,   134,   249,   249,    23,    54,   135,
+     222,   238,   136,   216,    11,   135,   136,   172,   184,   146,
+      44,    65,    97,   121,   154,   249,   249,   161,   162,   163,
+     164,   165,   166,   249,   134,   157,   135,   136,   148,   221,
+     190,   218,   222,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    72,   244,    20,   239,   241,
+     135,   116,   222,   234,   237,   222,    58,    33,    66,    66,
+     193,    33,   195,   196,    67,    74,    82,   104,   192,   136,
+     195,    38,   119,   191,    68,   198,   135,   136,   134,    93,
+     205,   206,   135,   238,   135,   136,   176,   222,   249,   134,
+      79,    79,   134,   135,   136,     5,     7,    28,    61,    88,
+      89,   118,   134,   249,   250,   242,   243,   249,   123,   154,
+     155,   156,   146,    10,    44,    51,    86,    97,   103,   121,
+     151,   152,   153,   135,   219,   220,    17,    18,    19,    72,
+     222,   134,   190,   222,    10,    86,   135,   136,   124,   222,
+     116,    58,   148,   222,     7,   135,   196,    91,    91,    91,
+      78,   193,     7,     7,   195,    41,    70,   199,   148,   239,
+     148,   239,    41,   135,    90,   207,   135,   222,   218,   134,
+     134,   248,   162,   248,   135,   136,    36,    39,    40,   111,
+     167,   136,   128,   158,    86,   134,   239,    79,   249,   151,
+     222,   134,   190,     9,   238,    86,   239,   134,   222,   135,
+     135,    64,   135,   194,    95,    95,   238,   218,    90,   200,
+      10,    86,   150,   150,   238,    41,   100,   107,   208,   209,
+     135,   248,   248,   135,   135,   242,   134,   168,   154,    37,
+      93,   159,   218,   134,     9,   238,   222,   135,   241,     7,
+      89,    41,    83,   201,    86,   212,   213,   222,    19,   135,
+     135,   161,   134,    41,   135,   249,   222,   135,   135,   135,
+     218,   212,     7,   127,   202,   203,   204,   136,    34,    53,
+     214,     7,    49,   120,   210,   103,   135,   161,    69,   100,
+     160,   135,   249,   204,   213,    87,   215,    96,   105,    96,
+       9,   249,   135,   134,    33,    62,    80,     7,    49,   120,
+     211,   134,   248,   134,    63,   105,    63,   248,   135,   205,
+     135,    94,   135,     7
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint16 yyr1[] =
+static const yytype_uint8 yyr1[] =
 {
-       0,   152,   153,   153,   153,   153,   153,   153,   154,   154,
-     154,   154,   154,   154,   154,   154,   154,   154,   155,   156,
-     156,   156,   156,   157,   158,   159,   160,   161,   161,   162,
-     162,   162,   162,   162,   162,   162,   162,   162,   162,   162,
-     162,   162,   162,   162,   162,   162,   162,   163,   163,   163,
-     163,   163,   163,   163,   164,   164,   165,   165,   166,   166,
-     166,   166,   167,   167,   168,   168,   169,   169,   170,   170,
-     171,   171,   172,   172,   173,   173,   174,   174,   174,   174,
-     175,   175,   175,   176,   177,   178,   179,   179,   179,   179,
-     180,   180,   181,   181,   181,   181,   182,   182,   182,   182,
-     183,   183,   183,   184,   184,   185,   186,   187,   187,   188,
-     189,   189,   190,   190,   191,   192,   192,   193,   194,   194,
-     195,   195,   196,   197,   197,   197,   198,   198,   199,   199,
-     200,   200,   200,   201,   202,   203,   203,   203,   204,   204,
-     204,   204,   204,   204,   204,   204,   205,   205,   206,   206,
-     206,   206,   206,   206,   207,   207,   208,   208,   209,   209,
-     210,   210,   211,   211,   212,   212,   213,   213,   214,   214,
-     215,   215,   216,   217,   218,   218,   219,   219,   220,   220,
-     221,   221,   222,   222,   222,   223,   223,   223,   224,   224,
-     225,   226,   226,   226,   227,   227,   227,   228,   228,   229,
-     230,   230,   231,   231,   232,   232,   233,   233,   233,   233,
-     233,   233,   233,   233,   233,   233,   233,   234,   234,   235,
-     235,   236,   236,   237,   237,   237,   237,   237,   237,   237,
-     237,   237,   237,   237,   237,   238,   238,   239,   239,   240,
-     240,   240,   240,   241,   241,   241,   241,   242,   243,   243,
-     244,   244,   245,   245,   246,   247,   247,   248,   249,   249,
-     250,   250,   251,   251,   251,   251,   251,   251,   251,   251,
-     252,   252,   252,   252,   252,   252,   253,   253,   254,   254,
-     255,   255,   256,   256,   256,   256,   256,   256,   256,   256,
-     256,   256,   257,   258,   258,   259,   259,   259,   260,   260,
-     261,   261,   262,   262,   262,   262,   263,   264,   264
+       0,   138,   139,   139,   139,   139,   139,   139,   140,   140,
+     140,   140,   140,   140,   140,   140,   140,   140,   141,   142,
+     142,   142,   142,   143,   144,   145,   146,   147,   147,   148,
+     148,   149,   149,   149,   149,   150,   150,   150,   151,   151,
+     151,   151,   151,   151,   151,   152,   152,   153,   153,   154,
+     154,   154,   154,   155,   155,   156,   156,   157,   157,   158,
+     158,   159,   159,   160,   160,   161,   161,   162,   162,   162,
+     162,   163,   163,   163,   164,   165,   166,   167,   167,   167,
+     167,   168,   168,   169,   169,   169,   169,   170,   170,   170,
+     170,   171,   171,   171,   172,   172,   173,   174,   175,   175,
+     176,   177,   177,   178,   178,   179,   180,   180,   181,   182,
+     182,   183,   183,   184,   185,   185,   185,   186,   186,   187,
+     187,   188,   188,   188,   189,   190,   191,   191,   191,   192,
+     192,   192,   192,   192,   192,   192,   192,   193,   193,   194,
+     194,   194,   194,   194,   194,   195,   195,   196,   196,   197,
+     197,   198,   198,   199,   199,   200,   200,   201,   201,   202,
+     202,   203,   203,   204,   205,   206,   206,   207,   207,   208,
+     208,   209,   209,   210,   210,   210,   211,   211,   211,   212,
+     212,   213,   214,   214,   214,   215,   215,   215,   216,   216,
+     217,   218,   218,   219,   219,   220,   220,   221,   221,   221,
+     221,   221,   221,   221,   221,   221,   221,   221,   222,   222,
+     223,   223,   224,   224,   225,   225,   225,   225,   225,   225,
+     225,   225,   225,   225,   225,   225,   226,   226,   227,   227,
+     228,   228,   228,   228,   229,   229,   230,   231,   231,   232,
+     232,   233,   233,   234,   235,

<TRUNCATED>


[06/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/meta/TypeListMetaFunctions.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeListMetaFunctions.hpp b/utility/meta/TypeListMetaFunctions.hpp
new file mode 100644
index 0000000..d908493
--- /dev/null
+++ b/utility/meta/TypeListMetaFunctions.hpp
@@ -0,0 +1,245 @@
+/**
+ * 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_UTILITY_META_TYPE_LIST_META_FUNCTIONS_HPP_
+#define QUICKSTEP_UTILITY_META_TYPE_LIST_META_FUNCTIONS_HPP_
+
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+template <typename ...Ts>
+class TypeList;
+
+namespace internal {
+
+template <typename TL, typename PosTL, typename Enable = void>
+struct ElementAtImpl;
+
+template <typename TL, typename PosTL>
+struct ElementAtImpl<TL, PosTL,
+                     std::enable_if_t<PosTL::length == 0>> {
+  using type = TL;
+};
+
+template <typename TL, typename PosTL>
+struct ElementAtImpl<TL, PosTL,
+                     std::enable_if_t<PosTL::length != 0>>
+    : ElementAtImpl<typename std::tuple_element<
+                        PosTL::head::value,
+                        typename TL::template bind_to<std::tuple>>::type,
+                    typename PosTL::tail> {};
+
+
+template <typename Out, typename Rest, typename Enable = void>
+struct UniqueImpl;
+
+template <typename Out, typename Rest>
+struct UniqueImpl<Out, Rest,
+                  std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest>
+struct UniqueImpl<Out, Rest,
+                  std::enable_if_t<Out::template contains<typename Rest::head>::value>>
+    : UniqueImpl<Out, typename Rest::tail> {};
+
+template <typename Out, typename Rest>
+struct UniqueImpl<Out, Rest,
+                  std::enable_if_t<!Out::template contains<typename Rest::head>::value>>
+    : UniqueImpl<typename Out::template push_back<typename Rest::head>,
+                 typename Rest::tail> {};
+
+
+template <typename Out, typename Rest, typename Subtrahend, typename Enable = void>
+struct SubtractImpl;
+
+template <typename Out, typename Rest, typename Subtrahend>
+struct SubtractImpl<Out, Rest, Subtrahend,
+                    std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, typename Subtrahend>
+struct SubtractImpl<Out, Rest, Subtrahend,
+                    std::enable_if_t<Subtrahend::template contains<
+                        typename Rest::head>::value>>
+    : SubtractImpl<Out, typename Rest::tail, Subtrahend> {};
+
+template <typename Out, typename Rest, typename Subtrahend>
+struct SubtractImpl<Out, Rest, Subtrahend,
+                    std::enable_if_t<!Subtrahend::template contains<
+                        typename Rest::head>::value>>
+    : SubtractImpl<typename Out::template push_back<typename Rest::head>,
+                   typename Rest::tail, Subtrahend> {};
+
+
+template <typename LeftTL, typename RightTL>
+struct CartesianProductImpl {
+  template <typename LeftT>
+  struct LeftHelper {
+    template <typename RightT>
+    struct RightHelper {
+      using type = TypeList<LeftT, RightT>;
+    };
+    using type = typename RightTL::template map<RightHelper>;
+  };
+  using type = typename LeftTL::template flatmap<LeftHelper>;
+};
+
+
+template <typename Out, typename Rest, template <typename ...> class Op,
+          typename Enable = void>
+struct FlatmapImpl;
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FlatmapImpl<Out, Rest, Op,
+                   std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FlatmapImpl<Out, Rest, Op,
+                   std::enable_if_t<Rest::length != 0>>
+    : FlatmapImpl<typename Out::template append<typename Op<typename Rest::head>::type>,
+                  typename Rest::tail, Op> {};
+
+
+template <typename Out, typename Rest, template <typename ...> class Op,
+          typename Enable = void>
+struct FilterImpl;
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FilterImpl<Out, Rest, Op,
+                  std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FilterImpl<Out, Rest, Op,
+                  std::enable_if_t<Op<typename Rest::head>::value>>
+    : FilterImpl<typename Out::template push_back<typename Rest::head>,
+                 typename Rest::tail, Op> {};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FilterImpl<Out, Rest, Op,
+                  std::enable_if_t<!Op<typename Rest::head>::value>>
+    : FilterImpl<Out, typename Rest::tail, Op> {};
+
+
+template <typename Out, typename Rest, template <typename ...> class Op,
+          typename Enable = void>
+struct FiltermapImpl;
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FiltermapImpl<Out, Rest, Op,
+                     std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FiltermapImpl<Out, Rest, Op,
+                     std::enable_if_t<Rest::length != 0 &&
+                                      IsTrait<Op<typename Rest::head>>::value>>
+    : FiltermapImpl<typename Out::template push_back<typename Op<typename Rest::head>::type>,
+                    typename Rest::tail, Op> {};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FiltermapImpl<Out, Rest, Op,
+                     std::enable_if_t<Rest::length != 0 &&
+                                      !IsTrait<Op<typename Rest::head>>::value>>
+    : FiltermapImpl<Out, typename Rest::tail, Op> {};
+
+
+template <typename Out, typename Rest, typename Enable = void>
+struct FlattenOnceImpl;
+
+template <typename Out, typename Rest>
+struct FlattenOnceImpl<Out, Rest,
+                       std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest>
+struct FlattenOnceImpl<Out, Rest,
+                       std::enable_if_t<Rest::length != 0>>
+    : FlattenOnceImpl<typename Out::template append<typename Rest::head>,
+                      typename Rest::tail> {};
+
+
+template <typename Out, typename RestL, typename RestR, typename Enable = void>
+struct ZipImpl;
+
+template <typename Out, typename RestL, typename RestR>
+struct ZipImpl<Out, RestL, RestR,
+               std::enable_if_t<RestL::length == 0 || RestR::length == 0>> {
+  static_assert(RestL::length == 0 && RestR::length == 0,
+                "Zip failed: TypeLists have unequal lengths");
+  using type = Out;
+};
+
+template <typename Out, typename RestL, typename RestR>
+struct ZipImpl<Out, RestL, RestR,
+               std::enable_if_t<RestL::length != 0 && RestR::length != 0>>
+    : ZipImpl<typename Out::template push_back<
+                  TypeList<typename RestL::head, typename RestR::head>>,
+              typename RestL::tail, typename RestR::tail> {};
+
+
+template <typename Out, typename RestL, typename RestR,
+          template <typename ...> class Op, typename Enable = void>
+struct ZipWithImpl;
+
+template <typename Out, typename RestL, typename RestR,
+          template <typename ...> class Op>
+struct ZipWithImpl<Out, RestL, RestR, Op,
+                   std::enable_if_t<RestL::length == 0 || RestR::length == 0>> {
+  static_assert(RestL::length == 0 && RestR::length == 0,
+                "ZipWith failed: TypeLists have unequal lengths");
+  using type = Out;
+};
+
+template <typename Out, typename RestL, typename RestR,
+          template <typename ...> class Op>
+struct ZipWithImpl<Out, RestL, RestR, Op,
+                   std::enable_if_t<RestL::length != 0 && RestR::length != 0>>
+    : ZipWithImpl<typename Out::template push_back<
+                      typename Op<typename RestL::head, typename RestR::head>::type>,
+                  typename RestL::tail, typename RestR::tail, Op> {};
+
+
+template <typename T, typename ...Ts>
+struct AsSequenceImpl {
+  using type = Sequence<T, static_cast<T>(Ts::value)...>;
+};
+
+}  // namespace internal
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_TYPE_LIST_META_FUNCTIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/utility/tests/TemplateUtil_unittest.cpp
----------------------------------------------------------------------
diff --git a/utility/tests/TemplateUtil_unittest.cpp b/utility/tests/TemplateUtil_unittest.cpp
deleted file mode 100644
index ce5d662..0000000
--- a/utility/tests/TemplateUtil_unittest.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "utility/TemplateUtil.hpp"
-
-#include <memory>
-#include <string>
-#include <sstream>
-#include <tuple>
-#include <utility>
-
-#include "utility/Macros.hpp"
-
-#include "gtest/gtest.h"
-
-namespace quickstep {
-
-class SomeArgType {
- public:
-  explicit SomeArgType(const std::string &value)
-      : value_(value) {
-  }
-
-  SomeArgType(SomeArgType &&arg)
-      : value_(std::move(arg.value_)) {
-  }
-
-  std::string toString() const {
-    return value_;
-  }
-
- private:
-  const std::string value_;
-
-  DISALLOW_COPY_AND_ASSIGN(SomeArgType);
-};
-
-class BaseClass {
- public:
-  virtual std::string toString() const = 0;
-};
-
-template <bool c1, bool c2, bool c3, bool c4, bool c5, bool c6>
-class SomeClass : public BaseClass {
- public:
-  SomeClass(const int a1, SomeArgType &&a2)
-      : a1_(a1), a2_(std::forward<SomeArgType>(a2)) {
-  }
-
-  std::string toString() const override {
-    std::ostringstream oss;
-    oss << "{ ";
-    if (c1) {
-      oss << "c1 ";
-    }
-    if (c2) {
-      oss << "c2 ";
-    }
-    if (c3) {
-      oss << "c3 ";
-    }
-    if (c4) {
-      oss << "c4 ";
-    }
-    if (c5) {
-      oss << "c5 ";
-    }
-    if (c6) {
-      oss << "c6 ";
-    }
-    oss << "} " << a1_ << " " << a2_.toString();
-    return oss.str();
-  }
-
- private:
-  const int a1_;
-  const SomeArgType a2_;
-};
-
-void RunTest(const bool c1, const bool c2, const bool c3,
-             const bool c4, const bool c5, const bool c6,
-             const std::string &expected) {
-  // arg should be perfectly forwarded.
-  SomeArgType arg("xyz");
-
-  std::unique_ptr<BaseClass> base(
-      CreateBoolInstantiatedInstance<SomeClass, BaseClass>(std::forward_as_tuple(10, std::move(arg)),
-                                                           c1, c2, c3, c4, c5, c6));
-  EXPECT_STREQ(expected.c_str(), base->toString().c_str());
-}
-
-TEST(TemplateUtilTest, TemplateUtilTest) {
-  RunTest(true, false, true, false, true, false, "{ c1 c3 c5 } 10 xyz");
-  RunTest(true, true, true, true, true, true, "{ c1 c2 c3 c4 c5 c6 } 10 xyz");
-  RunTest(false, false, true, true, false, false, "{ c3 c4 } 10 xyz");
-  RunTest(false, false, false, false, false, false, "{ } 10 xyz");
-}
-
-}  // namespace quickstep


[12/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/OperationUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationUtil.hpp b/types/operations/OperationUtil.hpp
new file mode 100644
index 0000000..076dc0c
--- /dev/null
+++ b/types/operations/OperationUtil.hpp
@@ -0,0 +1,334 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTIL_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTIL_HPP_
+
+#include <cstddef>
+#include <list>
+#include <string>
+#include <type_traits>
+
+#include "catalog/CatalogTypedefs.hpp"
+#include "types/Type.hpp"
+#include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename FunctorT, typename ...SpecArgs>
+struct FunctorSpecializer {
+  template <bool specialize = (sizeof...(SpecArgs) != 0),
+            typename EnableT = void>
+  struct Implementation;
+
+  typedef Implementation<> type;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool specialize>
+struct FunctorSpecializer<FunctorT, SpecArgs...>
+    ::Implementation<specialize, std::enable_if_t<specialize>> {
+  template <typename ...FuncArgs>
+  inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) {
+    return functor.template apply<SpecArgs...>(std::forward<FuncArgs>(args)...);
+  }
+  typedef FunctorT FunctorType;
+};
+
+template <typename FunctorT, typename ...SpecArgs>
+template <bool specialize>
+struct FunctorSpecializer<FunctorT, SpecArgs...>
+    ::Implementation<specialize, std::enable_if_t<!specialize>> {
+  template <typename ...FuncArgs>
+  inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) {
+    return functor.apply(std::forward<FuncArgs>(args)...);
+  }
+  typedef FunctorT FunctorType;
+};
+
+template <typename ColumnVectorT>
+struct ColumnVectorValueAccessor {
+  explicit ColumnVectorValueAccessor(const ColumnVectorT &column_vector_in)
+      : column_vector(column_vector_in),
+        length(column_vector.size()) {}
+
+  inline void beginIteration() {
+    pos = static_cast<std::size_t>(-1);
+  }
+
+  inline bool next() {
+    return (++pos) < length;
+  }
+
+  inline std::size_t getNumTuples() const {
+    return length;
+  }
+
+  template <bool nullable>
+  inline const void* getUntypedValue(const attribute_id) const {
+    return column_vector.template getUntypedValue<nullable>(pos);
+  }
+
+  inline TypedValue getTypedValue(const attribute_id) const {
+    return column_vector.getTypedValue(pos);
+  }
+
+  const ColumnVectorT &column_vector;
+  const std::size_t length;
+  std::size_t pos;
+};
+
+template <typename FuncSpec, typename T, typename EnableT = void>
+struct Codegen;
+
+template <typename FuncSpec, typename T>
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kNativeEmbedded>> {
+  using ColumnVectorType = NativeColumnVector;
+  using FunctorSpecializer = FuncSpec;
+
+  using NativeType = typename T::cpptype;
+  using NativeTypeConst = const typename T::cpptype;
+  using NativeTypeConstRef = const NativeType&;
+  using NativeTypeConstPtr = const NativeType*;
+
+  template <typename ArgumentGen>
+  inline static TypedValue ApplyUnaryTypedValue(
+      typename ArgumentGen::NativeTypeConstRef argument,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    return TypedValue(FuncSpec::Invoke(functor, argument));
+  }
+
+  template <typename ArgumentGen>
+  inline static void ApplyUnaryColumnVector(
+      const typename ArgumentGen::NativeTypeConstRef argument,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    *static_cast<NativeType *>(cv->getPtrForDirectWrite()) =
+        FuncSpec::Invoke(functor, argument);
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static TypedValue ApplyBinaryTypedValue(
+      typename LeftGen::NativeTypeConstRef left,
+      typename RightGen::NativeTypeConstRef right,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    return TypedValue(FuncSpec::Invoke(functor, left, right));
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static void ApplyBinaryColumnVector(
+      const typename LeftGen::NativeTypeConstRef left,
+      const typename RightGen::NativeTypeConstRef right,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    *static_cast<NativeType *>(cv->getPtrForDirectWrite()) =
+        FuncSpec::Invoke(functor, left, right);
+  }
+
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(
+      const AccessorT *accessor,
+      const attribute_id attr_id) {
+    return static_cast<NativeTypeConstPtr>(
+        accessor->template getUntypedValue<nullable>(attr_id));
+  }
+
+  inline static bool IsNull(const NativeType *value) {
+    return value == nullptr;
+  }
+
+  // Dereference: NativeTypeConstPtr& -> const NativeType&
+  inline static const NativeType& Dereference(const NativeType *value) {
+    return *value;
+  }
+
+  inline static const NativeType ToNativeValueConst(const TypedValue &value) {
+    return value.getLiteral<NativeType>();
+  }
+};
+
+template <typename FuncSpec, typename T>
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kNonNativeInline>> {
+  using ColumnVectorType = NativeColumnVector;
+  using FunctorSpecializer = FuncSpec;
+
+  using NativeType = void*;
+  using NativeTypeConst = const void*;
+  using NativeTypeConstRef = const void*;
+  using NativeTypeConstPtr = const void*;
+
+  template <typename ArgumentGen>
+  inline static TypedValue ApplyUnaryTypedValue(
+      typename ArgumentGen::NativeTypeConstRef argument,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    void *result = std::malloc(result_type.maximumByteLength());
+    FuncSpec::Invoke(functor, argument, result);
+    return TypedValue::CreateWithOwnedData(T::kStaticTypeID,
+                                           result,
+                                           result_type.maximumByteLength());
+  }
+
+  template <typename ArgumentGen>
+  inline static void ApplyUnaryColumnVector(
+      const typename ArgumentGen::NativeTypeConstRef argument,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    FuncSpec::Invoke(functor, argument, cv->getPtrForDirectWrite());
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static TypedValue ApplyBinaryTypedValue(
+      typename LeftGen::NativeTypeConstRef left,
+      typename RightGen::NativeTypeConstRef right,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    void *result = std::malloc(result_type.maximumByteLength());
+    FuncSpec::Invoke(functor, left, right, result);
+    return TypedValue::CreateWithOwnedData(T::kStaticTypeID,
+                                           result,
+                                           result_type.maximumByteLength());
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static void ApplyBinaryColumnVector(
+      const typename LeftGen::NativeTypeConstRef left,
+      const typename RightGen::NativeTypeConstRef right,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    FuncSpec::Invoke(functor, left, right, cv->getPtrForDirectWrite());
+  }
+
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(
+      const AccessorT *accessor,
+      const attribute_id attr_id) {
+    return accessor->template getUntypedValue<nullable>(attr_id);
+  }
+
+  inline static bool IsNull(const void *value) {
+    return value == nullptr;
+  }
+
+  // Dereference: NativeTypeConstPtr& -> const NativeType&
+  inline static const void* Dereference(const void *value) {
+    return value;
+  }
+
+  inline static const void* ToNativeValueConst(const TypedValue &value) {
+    return value.getDataPtr();
+  }
+};
+
+template <typename FuncSpec, typename T>
+struct Codegen<FuncSpec, T, std::enable_if_t<T::kLayout == kOutOfLine>> {
+  using ColumnVectorType = IndirectColumnVector;
+  using FunctorSpecializer = FuncSpec;
+
+  using NativeType = TypedValue;
+  using NativeTypeConst = const TypedValue;
+  using NativeTypeConstRef = const TypedValue&;
+  using NativeTypeConstPtr = const TypedValue;
+
+  template <typename ArgumentGen>
+  inline static TypedValue ApplyUnaryTypedValue(
+      typename ArgumentGen::NativeTypeConstRef argument,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    return FuncSpec::Invoke(functor, argument);
+  }
+
+  template <typename ArgumentGen>
+  inline static void ApplyUnaryColumnVector(
+      const typename ArgumentGen::NativeTypeConstRef argument,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    cv->appendTypedValue(FuncSpec::Invoke(functor, argument));
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static TypedValue ApplyBinaryTypedValue(
+      typename LeftGen::NativeTypeConstRef left,
+      typename RightGen::NativeTypeConstRef right,
+      const Type &result_type,
+      const typename FuncSpec::FunctorType &functor) {
+    return FuncSpec::Invoke(functor, left, right);
+  }
+
+  template <typename LeftGen, typename RightGen>
+  inline static void ApplyBinaryColumnVector(
+      const typename LeftGen::NativeTypeConstRef left,
+      const typename RightGen::NativeTypeConstRef right,
+      const typename FuncSpec::FunctorType &functor,
+      ColumnVectorType *cv) {
+    cv->appendTypedValue(FuncSpec::Invoke(functor, left, right));
+  }
+
+  template <bool nullable, typename AccessorT>
+  inline static NativeTypeConstPtr GetValuePtr(
+      const AccessorT *accessor,
+      const attribute_id attr_id) {
+    return accessor->getTypedValue(attr_id);
+  }
+
+  inline static bool IsNull(NativeTypeConstPtr &value) {
+    return value.isNull();
+  }
+
+  // Dereference: NativeTypeConstPtr& -> const NativeType&
+  inline static const NativeType& Dereference(NativeTypeConstPtr &value) {
+    return value;
+  }
+
+  inline static const NativeType& ToNativeValueConst(const TypedValue &value) {
+    return value;
+  }
+};
+
+template <typename ...FunctorTypes>
+struct FunctorPack {
+  template <typename Dispatcher>
+  inline static std::list<OperationPtr> GenerateOperations() {
+    std::vector<std::list<OperationPtr>> op_list_groups =
+        { Dispatcher::template Generate<FunctorTypes>()... };
+
+    std::list<OperationPtr> operations;
+    for (std::list<OperationPtr> &op_list : op_list_groups) {
+      operations.splice(operations.end(), std::move(op_list));
+    }
+    return operations;
+  }
+};
+
+struct OperationPack {
+  virtual std::vector<OperationPtr> generateOperations() = 0;
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_OPERATION_UTIL_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/AddBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/AddBinaryOperation.cpp b/types/operations/binary_operations/AddBinaryOperation.cpp
deleted file mode 100644
index 8f56a61..0000000
--- a/types/operations/binary_operations/AddBinaryOperation.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "types/operations/binary_operations/AddBinaryOperation.hpp"
-
-#include <string>
-#include <utility>
-
-#include "types/DateOperatorOverloads.hpp"
-#include "types/DateType.hpp"
-#include "types/DatetimeIntervalType.hpp"
-#include "types/DatetimeLit.hpp"
-#include "types/DatetimeType.hpp"
-#include "types/IntervalLit.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/YearMonthIntervalType.hpp"
-#include "types/operations/binary_operations/ArithmeticBinaryOperators.hpp"
-#include "utility/EqualsAnyConstant.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-bool AddBinaryOperation::canApplyToTypes(const Type &left, const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:  // Fall through.
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      return (right.getSuperTypeID() == Type::kNumeric);
-    }
-    case kDate: {
-      return (right.getTypeID() == kYearMonthInterval);
-    }
-    case kDatetime: {
-      return (right.getTypeID() == kDatetimeInterval ||
-              right.getTypeID() == kYearMonthInterval);
-    }
-    case kDatetimeInterval: {
-      return (right.getTypeID() == kDatetime ||
-              right.getTypeID() == kDatetimeInterval);
-    }
-    case kYearMonthInterval: {
-      return (right.getTypeID() == kDate ||
-              right.getTypeID() == kDatetime ||
-              right.getTypeID() == kYearMonthInterval);
-    }
-    default:
-      return false;
-  }
-}
-
-const Type* AddBinaryOperation::resultTypeForArgumentTypes(const Type &left, const Type &right) const {
-  if (left.getSuperTypeID() == Type::kNumeric && right.getSuperTypeID() == Type::kNumeric) {
-    return TypeFactory::GetUnifyingType(left, right);
-  } else if ((left.getTypeID() == kDatetime && right.getTypeID() == kDatetimeInterval)  ||
-             (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetime)  ||
-             (left.getTypeID() == kDatetime && right.getTypeID() == kYearMonthInterval) ||
-             (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kDatetime)) {
-    return &(DatetimeType::Instance(left.isNullable() || right.isNullable()));
-  } else if ((left.getTypeID() == kDate && right.getTypeID() == kYearMonthInterval) ||
-             (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kDate)) {
-    return &(DateType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kDatetimeInterval && right.getTypeID() == kDatetimeInterval) {
-    return &(DatetimeIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else if (left.getTypeID() == kYearMonthInterval && right.getTypeID() == kYearMonthInterval) {
-    return &(YearMonthIntervalType::Instance(left.isNullable() || right.isNullable()));
-  } else {
-    return nullptr;
-  }
-}
-
-const Type* AddBinaryOperation::resultTypeForPartialArgumentTypes(const Type *left,
-                                                                  const Type *right) const {
-  if ((left == nullptr) && (right == nullptr)) {
-    return nullptr;
-  }
-
-  if ((left != nullptr) && (right != nullptr)) {
-    return resultTypeForArgumentTypes(*left, *right);
-  }
-
-  // Addition is commutative, so we just determine based on the known type,
-  // left or right.
-  const Type *known_type = (left != nullptr) ? left : right;
-  switch (known_type->getTypeID()) {
-    case kDouble:
-      // Double has highest precedence of the numeric types.
-      return &TypeFactory::GetType(kDouble, true);
-    case kDatetime:
-      // Datetime can be added with either interval type, and always yields
-      // Datetime.
-      return &TypeFactory::GetType(kDatetime, true);
-    case kDate:
-      // Date can be added with YearMonthInterval type only, and always yields
-      // Date.
-      return &TypeFactory::GetType(kDate, true);
-    default:
-      // Ambiguous or inapplicable.
-      return nullptr;
-  }
-}
-
-bool AddBinaryOperation::partialTypeSignatureIsPlausible(
-    const Type *result_type,
-    const Type *left_argument_type,
-    const Type *right_argument_type) const {
-  if ((left_argument_type == nullptr) && (right_argument_type == nullptr)) {
-    if (result_type == nullptr) {
-      return true;
-    } else if (!result_type->isNullable()) {
-      // Unknown arguments are assumed to be nullable, since they arise from
-      // untyped NULL literals in the parser. Therefore, a non-nullable result
-      // Type is not plausible with unknown arguments.
-      return false;
-    } else {
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(result_type->getTypeID(),
-                                           kInt,
-                                           kLong,
-                                           kFloat,
-                                           kDouble,
-                                           kDate,
-                                           kDatetime,
-                                           kDatetimeInterval,
-                                           kYearMonthInterval);
-    }
-  }
-
-  if ((left_argument_type != nullptr) && (right_argument_type != nullptr)) {
-    const Type *actual_result_type = resultTypeForArgumentTypes(*left_argument_type,
-                                                                *right_argument_type);
-    if (actual_result_type == nullptr) {
-      // Both argument Types are known, but this operation is NOT applicable to
-      // them. No matter what the result_type is, the signature is not
-      // plausible.
-      return false;
-    } else if (result_type == nullptr) {
-      return true;
-    } else {
-      return result_type->equals(*actual_result_type);
-    }
-  }
-
-  // Addition is commutative, so we just determine based on the known type,
-  // left or right.
-  const Type *known_argument_type = (left_argument_type != nullptr)
-                                    ? left_argument_type
-                                    : right_argument_type;
-  if (result_type == nullptr) {
-    return QUICKSTEP_EQUALS_ANY_CONSTANT(known_argument_type->getTypeID(),
-                                         kInt,
-                                         kLong,
-                                         kFloat,
-                                         kDouble,
-                                         kDate,
-                                         kDatetime,
-                                         kDatetimeInterval,
-                                         kYearMonthInterval);
-  }
-
-  if (!result_type->isNullable()) {
-    // One of the arguments is unknown, but it is nevertheless assumed
-    // nullable, since unknown argument Types arise from untyped NULL literals
-    // in the parser. Therefore, a non-nullable result Type is not plausible
-    // with an unknown argument.
-    return false;
-  }
-
-  switch (result_type->getTypeID()) {
-    case kInt:
-      return (known_argument_type->getTypeID() == kInt);
-    case kLong:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong);
-    case kFloat:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kFloat);
-    case kDouble:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kInt, kLong, kFloat, kDouble);
-    case kDate:
-      return (known_argument_type->getTypeID() == kDate);
-    case kDatetime:
-      return QUICKSTEP_EQUALS_ANY_CONSTANT(
-          known_argument_type->getTypeID(),
-          kDatetime, kDatetimeInterval);
-    case kDatetimeInterval:
-      return (known_argument_type->getTypeID() == kDatetimeInterval);
-    case kYearMonthInterval:
-      return (known_argument_type->getTypeID() == kYearMonthInterval);
-    default:
-      return false;
-  }
-}
-
-std::pair<const Type*, const Type*> AddBinaryOperation::pushDownTypeHint(
-    const Type *result_type_hint) const {
-  if (result_type_hint == nullptr) {
-    return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-
-  switch (result_type_hint->getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kDatetimeInterval:
-    case kYearMonthInterval:
-      // Hint the same as the result type. Note that, for numeric types, one of
-      // the argument Types can be a less precise Type and still yield the
-      // specified result Type (e.g. DoubleType + IntType = DoubleType). We
-      // choose the highest-precision suitable Type (i.e. the same as the
-      // result type) in such cases.
-      return std::pair<const Type*, const Type*>(result_type_hint, result_type_hint);
-    case kDate:
-      // Hint is ambiguous: one argument should be a Date, other has to be
-      // kYearMonthInterval, but order is not important.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-    case kDatetime:
-      // Hint is ambiguous: one argument should be a Datetime, the other should
-      // be one of the interval types, but either order is acceptable.
-      // Fortunately, the 3 types in question have syntactically distinct
-      // representations in the SQL parser, so their literals don't need
-      // disambiguation anyway.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-    default:
-      // Inapplicable.
-      return std::pair<const Type*, const Type*>(nullptr, nullptr);
-  }
-}
-
-TypedValue AddBinaryOperation::applyToChecked(const TypedValue &left,
-                                              const Type &left_type,
-                                              const TypedValue &right,
-                                              const Type &right_type) const {
-  switch (left_type.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      switch (right_type.getTypeID()) {
-        case kInt:
-        case kLong:
-        case kFloat:
-        case kDouble:
-          return applyToCheckedNumericHelper<AddFunctor>(left, left_type,
-                                                         right, right_type);
-        default:
-          break;
-      }
-      break;
-    }
-    case kDate: {
-      if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDate);
-        }
-
-        return TypedValue(left.getLiteral<DateLit>() + right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    case kDatetime: {
-      if (right_type.getTypeID() == kDatetimeInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeLit>() + right.getLiteral<DatetimeIntervalLit>());
-      } else if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeLit>() + right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      if (right_type.getTypeID() == kDatetime) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeIntervalLit>() + right.getLiteral<DatetimeLit>());
-      } else if (right_type.getTypeID() == kDatetimeInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetimeInterval);
-        }
-
-        return TypedValue(left.getLiteral<DatetimeIntervalLit>() + right.getLiteral<DatetimeIntervalLit>());
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      if (right_type.getTypeID() == kDate) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<YearMonthIntervalLit>() + right.getLiteral<DateLit>());
-      } else if (right_type.getTypeID() == kDatetime) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kDatetime);
-        }
-
-        return TypedValue(left.getLiteral<YearMonthIntervalLit>() + right.getLiteral<DatetimeLit>());
-      } else if (right_type.getTypeID() == kYearMonthInterval) {
-        if (left.isNull() || right.isNull()) {
-          return TypedValue(kYearMonthInterval);
-        }
-
-        return TypedValue(left.getLiteral<YearMonthIntervalLit>() + right.getLiteral<YearMonthIntervalLit>());
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-             << left_type.getName() << " and " << right_type.getName();
-}
-
-UncheckedBinaryOperator* AddBinaryOperation::makeUncheckedBinaryOperatorForTypes(const Type &left,
-                                                                                 const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble: {
-      if (right.getSuperTypeID() == Type::kNumeric) {
-        return makeNumericBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator>(left, right);
-      }
-      break;
-    }
-    case kDate: {
-      if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<
-            AddArithmeticUncheckedBinaryOperator,
-            DateType,
-            DateLit,
-            YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDatetime: {
-      if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
-                                                 DatetimeType,
-                                                 DatetimeLit, DatetimeIntervalLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
-                                                 DatetimeType,
-                                                 DatetimeLit, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kDatetimeInterval: {
-      if (right.getTypeID() == kDatetime) {
-        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
-                                                 DatetimeType,
-                                                 DatetimeIntervalLit, DatetimeLit>(left, right);
-      } else if (right.getTypeID() == kDatetimeInterval) {
-        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
-                                                 DatetimeIntervalType,
-                                                 DatetimeIntervalLit, DatetimeIntervalLit>(left, right);
-      }
-      break;
-    }
-    case kYearMonthInterval: {
-      if (right.getTypeID() == kDate) {
-        return makeDateBinaryOperatorOuterHelper<
-            AddArithmeticUncheckedBinaryOperator,
-            DateType,
-            YearMonthIntervalLit,
-            DateLit>(left, right);
-      } else if (right.getTypeID() == kDatetime) {
-        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
-                                                 DatetimeType,
-                                                 YearMonthIntervalLit, DatetimeLit>(left, right);
-      } else if (right.getTypeID() == kYearMonthInterval) {
-        return makeDateBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator,
-                                                 YearMonthIntervalType,
-                                                 YearMonthIntervalLit, YearMonthIntervalLit>(left, right);
-      }
-      break;
-    }
-    default:
-      break;
-  }
-
-  throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-}
-
-}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp b/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp
new file mode 100644
index 0000000..4c6f76c
--- /dev/null
+++ b/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp
@@ -0,0 +1,176 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_FUNCTOR_OVERLOADS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_FUNCTOR_OVERLOADS_HPP_
+
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <type_traits>
+#include <utility>
+
+#include "types/DateOperatorOverloads.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+// We use these functors instead of the standard-library ones, because the
+// standard-library functors in <functional> have to be instantiated for the
+// most specific argument type, which would unnecessisarily introduce
+// multiple copies of distinct template instantiations of operators.
+template <typename LeftCppType, typename RightCppType, typename EnableT = void>
+struct AddFunctorOverloads {
+  inline auto operator() (const LeftCppType &left,
+                          const RightCppType &right) const -> decltype(left + right) {
+    return left + right;
+  }
+};
+
+// NOTE(zuyu): The C++ compiler in general converts all integers to floats
+//             when doing the following operations,
+//             but we could like to return double instead.
+template <>
+struct AddFunctorOverloads<std::int64_t, float> {
+  inline double operator() (const std::int64_t &left, const float &right) const {
+    return static_cast<double>(left) + static_cast<double>(right);
+  }
+};
+
+template <>
+struct AddFunctorOverloads<float, std::int64_t> {
+  inline double operator() (const float &left, const std::int64_t &right) const {
+    return static_cast<double>(left) + static_cast<double>(right);
+  }
+};
+
+template <typename LeftCppType, typename RightCppType, typename EnableT = void>
+struct SubtractFunctorOverloads {
+  inline auto operator() (const LeftCppType &left,
+                          const RightCppType &right) const -> decltype(left - right) {
+    return left - right;
+  }
+};
+
+// NOTE(zuyu): The C++ compiler in general converts all integers to floats
+//             when doing the following operations,
+//             but we could like to return double instead.
+template <>
+struct SubtractFunctorOverloads<std::int64_t, float> {
+  inline double operator() (const std::int64_t &left, const float &right) const {
+    return static_cast<double>(left) - static_cast<double>(right);
+  }
+};
+
+template <>
+struct SubtractFunctorOverloads<float, std::int64_t> {
+  inline double operator() (const float &left, const std::int64_t &right) const {
+    return static_cast<double>(left) - static_cast<double>(right);
+  }
+};
+
+template <typename LeftCppType, typename RightCppType, typename EnableT = void>
+struct MultiplyFunctorOverloads {
+  inline auto operator() (const LeftCppType &left,
+                          const RightCppType &right) const -> decltype(left * right) {
+    return left * right;
+  }
+};
+
+// NOTE(zuyu): The C++ compiler in general converts all integers to floats
+//             when doing the following operations,
+//             but we could like to return double instead.
+template <>
+struct MultiplyFunctorOverloads<std::int64_t, float> {
+  inline double operator() (const std::int64_t &left, const float &right) const {
+    return static_cast<double>(left) * static_cast<double>(right);
+  }
+};
+
+template <>
+struct MultiplyFunctorOverloads<float, std::int64_t> {
+  inline double operator() (const float &left, const std::int64_t &right) const {
+    return static_cast<double>(left) * static_cast<double>(right);
+  }
+};
+
+template <typename LeftCppType, typename RightCppType, typename EnableT = void>
+struct DivideFunctorOverloads {
+  inline auto operator() (const LeftCppType &left,
+                          const RightCppType &right) const -> decltype(left / right) {
+    return left / right;
+  }
+};
+
+// NOTE(zuyu): The C++ compiler in general converts all integers to floats
+//             when doing the following operations,
+//             but we could like to return double instead.
+template <>
+struct DivideFunctorOverloads<std::int64_t, float> {
+  inline double operator() (const std::int64_t &left, const float &right) const {
+    return static_cast<double>(left) / static_cast<double>(right);
+  }
+};
+
+template <>
+struct DivideFunctorOverloads<float, std::int64_t> {
+  inline double operator() (const float &left, const std::int64_t &right) const {
+    return static_cast<double>(left) / static_cast<double>(right);
+  }
+};
+
+template <typename LeftCppType, typename RightCppType, typename EnableT = void>
+struct ModuloFunctorOverloads;
+
+template <typename LeftCppType, typename RightCppType>
+struct ModuloFunctorOverloads<
+    LeftCppType, RightCppType,
+    std::enable_if_t<meta::EqualsAny<LeftCppType, int, std::int64_t>::value &&
+                     meta::EqualsAny<RightCppType, int, std::int64_t>::value>> {
+  inline auto operator() (const LeftCppType &left,
+                          const RightCppType &right) const -> decltype(left % right) {
+    return left % right;
+  }
+};
+
+// NOTE(jianqiao): The C++11 standard specifies the following type signatures for fmod:
+// (1) (double, double) -> double
+// (2) (float, float) -> float
+// (3) (long double, long double) -> long double
+// (3) (Arithmetic, Arithmetic) -> double
+template <typename LeftCppType, typename RightCppType>
+struct ModuloFunctorOverloads<
+    LeftCppType, RightCppType,
+    std::enable_if_t<meta::EqualsAny<LeftCppType, float, double>::value ||
+                     meta::EqualsAny<RightCppType, float, double>::value>> {
+  inline auto operator() (const LeftCppType &left,
+                          const RightCppType &right) const -> decltype(std::fmod(left, right)) {
+    return std::fmod(left, right);
+  }
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_FUNCTOR_OVERLOADS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/ArithmeticBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryOperation.hpp b/types/operations/binary_operations/ArithmeticBinaryOperation.hpp
deleted file mode 100644
index f9a27a8..0000000
--- a/types/operations/binary_operations/ArithmeticBinaryOperation.hpp
+++ /dev/null
@@ -1,404 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATION_HPP_
-#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATION_HPP_
-
-#include <string>
-
-#include "types/DoubleType.hpp"
-#include "types/FloatType.hpp"
-#include "types/IntType.hpp"
-#include "types/LongType.hpp"
-#include "types/NumericTypeUnifier.hpp"
-#include "types/Type.hpp"
-#include "types/TypeErrors.hpp"
-#include "types/TypeFactory.hpp"
-#include "types/TypeID.hpp"
-#include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
-#include "utility/Macros.hpp"
-
-#include "glog/logging.h"
-
-namespace quickstep {
-
-/** \addtogroup Types
- *  @{
- */
-
-/**
- * @brief A BinaryOperation which applies to and yields values
- *        including numeric, datetime, and intervals.
- **/
-class ArithmeticBinaryOperation : public BinaryOperation {
- protected:
-  explicit ArithmeticBinaryOperation(const BinaryOperationID operation_id)
-      : BinaryOperation(operation_id) {
-  }
-
-  template <template <typename LeftCppType, typename RightCppType> class OperationFunctor>
-  TypedValue applyToCheckedIntegerHelper(const TypedValue &left,
-                                         const Type &left_type,
-                                         const TypedValue &right,
-                                         const Type &right_type) const;
-
-  template <template <typename LeftCppType, typename RightCppType> class OperationFunctor>
-  TypedValue applyToCheckedNumericHelper(const TypedValue &left,
-                                         const Type &left_type,
-                                         const TypedValue &right,
-                                         const Type &right_type) const;
-
-  template <template <class ResultType,
-                      typename LeftCppType, bool left_nullable,
-                      typename RightCppType, bool right_nullable> class OperatorType>
-  UncheckedBinaryOperator* makeIntegerBinaryOperatorOuterHelper(const Type &left,
-                                                                const Type &right) const;
-
-  template <template <class ResultType,
-                      typename LeftCppType, bool left_nullable,
-                      typename RightCppType, bool right_nullable> class OperatorType,
-            typename LeftType, bool left_nullable>
-  UncheckedBinaryOperator* makeIntegerBinaryOperatorInnerHelper(const Type &left,
-                                                                const Type &right) const;
-
-  template <template <class ResultType,
-                      typename LeftCppType, bool left_nullable,
-                      typename RightCppType, bool right_nullable> class OperatorType>
-  UncheckedBinaryOperator* makeNumericBinaryOperatorOuterHelper(const Type &left,
-                                                                const Type &right) const;
-
-  template <template <class ResultType,
-                      typename LeftCppType, bool left_nullable,
-                      typename RightCppType, bool right_nullable> class OperatorType,
-            typename LeftType, bool left_nullable>
-  UncheckedBinaryOperator* makeNumericBinaryOperatorInnerHelper(const Type &left,
-                                                                const Type &right) const;
-
-  template <template <typename ResultType,
-                      typename LeftCppType, bool left_nullable,
-                      typename RightCppType, bool right_nullable> class OperatorType,
-            typename ResultType,
-            typename LeftCppType,
-            typename RightCppType>
-  UncheckedBinaryOperator* makeDateBinaryOperatorOuterHelper(const Type &left,
-                                                             const Type &right) const;
-
-  template <template <typename ResultType,
-                      typename LeftCppType, bool left_nullable,
-                      typename RightCppType, bool right_nullable> class OperatorType,
-            typename ResultType,
-            typename LeftCppType,
-            bool left_nullable,
-            typename RightCppType>
-  UncheckedBinaryOperator* makeDateBinaryOperatorInnerHelper(const Type &right) const;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ArithmeticBinaryOperation);
-};
-
-/** @} */
-
-// ----------------------------------------------------------------------------
-// Templated method implementations follow:
-
-template <template <typename LeftCppType, typename RightCppType> class OperationFunctor>
-TypedValue ArithmeticBinaryOperation::applyToCheckedIntegerHelper(
-    const TypedValue &left,
-    const Type &left_type,
-    const TypedValue &right,
-    const Type &right_type) const {
-  DCHECK(left_type.getTypeID() == TypeID::kInt
-         || left_type.getTypeID() == TypeID::kLong);
-  DCHECK(right_type.getTypeID() == TypeID::kInt
-         || right_type.getTypeID() == TypeID::kLong);
-
-  const Type *unifier = TypeFactory::GetUnifyingType(left_type, right_type);
-  DCHECK(unifier != nullptr);
-
-  if (left.isNull() || right.isNull()) {
-    return unifier->makeNullValue();
-  }
-
-  const TypedValue left_coerced = unifier->coerceValue(left, left_type);
-  const TypedValue right_coerced = unifier->coerceValue(right, right_type);
-
-  switch (unifier->getTypeID()) {
-    case kInt: {
-      OperationFunctor<IntType::cpptype, IntType::cpptype> operation_functor;
-      return TypedValue(operation_functor(left_coerced.getLiteral<IntType::cpptype>(),
-                                          right_coerced.getLiteral<IntType::cpptype>()));
-    }
-    case kLong: {
-      OperationFunctor<LongType::cpptype, LongType::cpptype> operation_functor;
-      return TypedValue(operation_functor(left_coerced.getLiteral<LongType::cpptype>(),
-                                          right_coerced.getLiteral<LongType::cpptype>()));
-    }
-    default: {
-      LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-                 << left_type.getName() << " and " << right_type.getName();
-    }
-  }
-
-  QUICKSTEP_UNREACHABLE();
-}
-
-template <template <typename LeftCppType, typename RightCppType> class OperationFunctor>
-TypedValue ArithmeticBinaryOperation::applyToCheckedNumericHelper(
-    const TypedValue &left,
-    const Type &left_type,
-    const TypedValue &right,
-    const Type &right_type) const {
-  DCHECK_EQ(Type::kNumeric, left_type.getSuperTypeID());
-  DCHECK_EQ(Type::kNumeric, right_type.getSuperTypeID());
-
-  const Type *unifier = TypeFactory::GetUnifyingType(left_type, right_type);
-  DCHECK(unifier != nullptr);
-
-  if (left.isNull() || right.isNull()) {
-    return unifier->makeNullValue();
-  }
-
-  const TypedValue left_coerced = unifier->coerceValue(left, left_type);
-  const TypedValue right_coerced = unifier->coerceValue(right, right_type);
-
-  switch (unifier->getTypeID()) {
-    case kInt: {
-      OperationFunctor<IntType::cpptype, IntType::cpptype> operation_functor;
-      return TypedValue(operation_functor(left_coerced.getLiteral<IntType::cpptype>(),
-                                          right_coerced.getLiteral<IntType::cpptype>()));
-    }
-    case kLong: {
-      OperationFunctor<LongType::cpptype, LongType::cpptype> operation_functor;
-      return TypedValue(operation_functor(left_coerced.getLiteral<LongType::cpptype>(),
-                                          right_coerced.getLiteral<LongType::cpptype>()));
-    }
-    case kFloat: {
-      OperationFunctor<FloatType::cpptype, FloatType::cpptype> operation_functor;
-      return TypedValue(operation_functor(left_coerced.getLiteral<FloatType::cpptype>(),
-                                          right_coerced.getLiteral<FloatType::cpptype>()));
-    }
-    case kDouble: {
-      OperationFunctor<DoubleType::cpptype, DoubleType::cpptype> operation_functor;
-      return TypedValue(operation_functor(left_coerced.getLiteral<DoubleType::cpptype>(),
-                                          right_coerced.getLiteral<DoubleType::cpptype>()));
-    }
-    default: {
-      LOG(FATAL) << "Can not apply " << getName() << " to arguments of types "
-                 << left_type.getName() << " and " << right_type.getName();
-    }
-  }
-
-  QUICKSTEP_UNREACHABLE();
-}
-
-template <template <class ResultType,
-                    typename LeftCppType, bool left_nullable,
-                    typename RightCppType, bool right_nullable> class OperatorType>
-UncheckedBinaryOperator* ArithmeticBinaryOperation::makeIntegerBinaryOperatorOuterHelper(
-    const Type &left,
-    const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-      if (left.isNullable()) {
-        return makeIntegerBinaryOperatorInnerHelper<OperatorType, IntType, true>(
-            left, right);
-      } else {
-        return makeIntegerBinaryOperatorInnerHelper<OperatorType, IntType, false>(
-            left, right);
-      }
-    case kLong:
-      if (left.isNullable()) {
-        return makeIntegerBinaryOperatorInnerHelper<OperatorType, LongType, true>(
-            left, right);
-      } else {
-        return makeIntegerBinaryOperatorInnerHelper<OperatorType, LongType, false>(
-            left, right);
-      }
-    default:
-      throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-  }
-}
-
-template <template <class ResultType,
-                    typename LeftCppType, bool left_nullable,
-                    typename RightCppType, bool right_nullable> class OperatorType,
-          typename LeftType, bool left_nullable>
-UncheckedBinaryOperator* ArithmeticBinaryOperation::makeIntegerBinaryOperatorInnerHelper(
-    const Type &left,
-    const Type &right) const {
-  switch (right.getTypeID()) {
-    case kInt:
-      if (right.isNullable()) {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, IntType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename IntType::cpptype, true>();
-      } else {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, IntType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename IntType::cpptype, false>();
-      }
-    case kLong:
-      if (right.isNullable()) {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, LongType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename LongType::cpptype, true>();
-      } else {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, LongType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename LongType::cpptype, false>();
-      }
-    default:
-      throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-  }
-}
-
-template <template <class ResultType,
-                    typename LeftCppType, bool left_nullable,
-                    typename RightCppType, bool right_nullable> class OperatorType>
-UncheckedBinaryOperator* ArithmeticBinaryOperation::makeNumericBinaryOperatorOuterHelper(
-    const Type &left,
-    const Type &right) const {
-  switch (left.getTypeID()) {
-    case kInt:
-      if (left.isNullable()) {
-        return makeNumericBinaryOperatorInnerHelper<OperatorType, IntType, true>(
-            left, right);
-      } else {
-        return makeNumericBinaryOperatorInnerHelper<OperatorType, IntType, false>(
-            left, right);
-      }
-    case kLong:
-      if (left.isNullable()) {
-        return makeNumericBinaryOperatorInnerHelper<OperatorType, LongType, true>(
-            left, right);
-      } else {
-        return makeNumericBinaryOperatorInnerHelper<OperatorType, LongType, false>(
-            left, right);
-      }
-    case kFloat:
-      if (left.isNullable()) {
-        return makeNumericBinaryOperatorInnerHelper<OperatorType, FloatType, true>(
-            left, right);
-      } else {
-        return makeNumericBinaryOperatorInnerHelper<OperatorType, FloatType, false>(
-            left, right);
-      }
-    case kDouble:
-      if (left.isNullable()) {
-        return makeNumericBinaryOperatorInnerHelper<OperatorType, DoubleType, true>(
-            left, right);
-      } else {
-        return makeNumericBinaryOperatorInnerHelper<OperatorType, DoubleType, false>(
-            left, right);
-      }
-    default:
-      throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-  }
-}
-
-template <template <class ResultType,
-                    typename LeftCppType, bool left_nullable,
-                    typename RightCppType, bool right_nullable> class OperatorType,
-          typename LeftType, bool left_nullable>
-UncheckedBinaryOperator* ArithmeticBinaryOperation::makeNumericBinaryOperatorInnerHelper(
-    const Type &left,
-    const Type &right) const {
-  switch (right.getTypeID()) {
-    case kInt:
-      if (right.isNullable()) {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, IntType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename IntType::cpptype, true>();
-      } else {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, IntType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename IntType::cpptype, false>();
-      }
-    case kLong:
-      if (right.isNullable()) {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, LongType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename LongType::cpptype, true>();
-      } else {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, LongType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename LongType::cpptype, false>();
-      }
-    case kFloat:
-      if (right.isNullable()) {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, FloatType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename FloatType::cpptype, true>();
-      } else {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, FloatType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename FloatType::cpptype, false>();
-      }
-    case kDouble:
-      if (right.isNullable()) {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, DoubleType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename DoubleType::cpptype, true>();
-      } else {
-        return new OperatorType<typename NumericTypeUnifier<LeftType, DoubleType>::type,
-                                typename LeftType::cpptype, left_nullable,
-                                typename DoubleType::cpptype, false>();
-      }
-    default:
-      throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
-  }
-}
-
-template <template <typename ResultType,
-                    typename LeftCppType, bool left_nullable,
-                    typename RightCppType, bool right_nullable> class OperatorType,
-          typename ResultType,
-          typename LeftCppType,
-          typename RightCppType>
-UncheckedBinaryOperator* ArithmeticBinaryOperation::makeDateBinaryOperatorOuterHelper(
-    const Type &left,
-    const Type &right) const {
-  if (left.isNullable()) {
-    return makeDateBinaryOperatorInnerHelper<OperatorType, ResultType, LeftCppType, true, RightCppType>(right);
-  } else {
-    return makeDateBinaryOperatorInnerHelper<OperatorType, ResultType, LeftCppType, false, RightCppType>(right);
-  }
-}
-
-template <template <typename ResultType,
-                    typename LeftCppType, bool left_nullable,
-                    typename RightCppType, bool right_nullable> class OperatorType,
-          typename ResultType,
-          typename LeftCppType,
-          bool left_nullable,
-          typename RightCppType>
-UncheckedBinaryOperator* ArithmeticBinaryOperation::makeDateBinaryOperatorInnerHelper(
-    const Type &right) const {
-  if (right.isNullable()) {
-    return new OperatorType<ResultType, LeftCppType, left_nullable, RightCppType, true>();
-  } else {
-    return new OperatorType<ResultType, LeftCppType, left_nullable, RightCppType, false>();
-  }
-}
-
-}  // namespace quickstep
-
-#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATION_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryOperations.hpp b/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
new file mode 100644
index 0000000..fa4d926
--- /dev/null
+++ b/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
@@ -0,0 +1,182 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATIONS_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATIONS_HPP_
+
+#include <string>
+#include <tuple>
+
+#include "types/DateType.hpp"
+#include "types/DatetimeIntervalType.hpp"
+#include "types/DatetimeLit.hpp"
+#include "types/DatetimeType.hpp"
+#include "types/IntervalLit.hpp"
+#include "types/NumericTypeUnifier.hpp"
+#include "types/Type.hpp"
+#include "types/TypeErrors.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/YearMonthIntervalType.hpp"
+#include "types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp"
+#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename LeftT, typename RightT, typename ResultT,
+          template <typename LeftCppType,
+                    typename RightCppType,
+                    typename EnableT = void> class FunctorOverloadsT,
+          typename FunctorNameT>
+struct ArithmeticBinaryFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
+  ArithmeticBinaryFunctor() : spec() {}
+  inline typename ResultT::cpptype apply(const typename LeftT::cpptype &left,
+                                         const typename RightT::cpptype &right) const {
+    return spec(left, right);
+  }
+  inline static std::string GetName() {
+    return FunctorNameT::ToString();
+  }
+  const FunctorOverloadsT<typename LeftT::cpptype,
+                          typename RightT::cpptype> spec;
+};
+
+template <typename LeftT, typename RightT, typename ResultT>
+using AddFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                           AddFunctorOverloads,
+                                           meta::StringLiteral<'+'>>;
+
+template <typename LeftT, typename RightT, typename ResultT>
+using SubtractFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                                SubtractFunctorOverloads,
+                                                meta::StringLiteral<'-'>>;
+
+template <typename LeftT, typename RightT, typename ResultT>
+using MultiplyFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                                MultiplyFunctorOverloads,
+                                                meta::StringLiteral<'*'>>;
+
+template <typename LeftT, typename RightT, typename ResultT>
+using DivideFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                              DivideFunctorOverloads,
+                                              meta::StringLiteral<'/'>>;
+
+template <typename LeftT, typename RightT, typename ResultT>
+using ModuloFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
+                                              ModuloFunctorOverloads,
+                                              meta::StringLiteral<'%'>>;
+
+// ----------------------------------------------------------------------------
+// Packs of functors:
+
+using AddBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        AddFunctor, NumericTypeUnifier>,
+// Date
+    AddFunctor<DateType, YearMonthIntervalType, DateType>,
+    AddFunctor<YearMonthIntervalType, DateType, DateType>,
+// Datetime
+    AddFunctor<DatetimeType, DatetimeIntervalType, DatetimeType>,
+    AddFunctor<DatetimeType, YearMonthIntervalType, DatetimeType>,
+    AddFunctor<DatetimeIntervalType, DatetimeType, DatetimeType>,
+    AddFunctor<YearMonthIntervalType, DatetimeType, DatetimeType>,
+// DatetimeInterval
+    AddFunctor<DatetimeIntervalType, DatetimeIntervalType, DatetimeIntervalType>,
+// YearMonthInterval
+    AddFunctor<YearMonthIntervalType, YearMonthIntervalType, YearMonthIntervalType>
+>;
+
+using SubtractBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        SubtractFunctor, NumericTypeUnifier>,
+// Date
+    SubtractFunctor<DateType, YearMonthIntervalType, DateType>,
+    // TODO(quickstep-team):
+    // Implement SubtractFunctor<DateType, DateType, YearMonthIntervalType>,
+// Datetime
+    SubtractFunctor<DatetimeType, DatetimeIntervalType, DatetimeType>,
+    SubtractFunctor<DatetimeType, YearMonthIntervalType, DatetimeType>,
+    SubtractFunctor<DatetimeType, DatetimeType, DatetimeIntervalType>,
+// DatetimeInterval
+    SubtractFunctor<DatetimeIntervalType, DatetimeIntervalType, DatetimeIntervalType>,
+// YearMonthInterval
+    SubtractFunctor<YearMonthIntervalType, YearMonthIntervalType, YearMonthIntervalType>
+>;
+
+using MultiplyBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        MultiplyFunctor, NumericTypeUnifier>,
+// DatetimeInterval and YearMonthInterval
+    BinaryFunctorCrossProductPack<
+        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        MultiplyFunctor, meta::PairSelectorLeft>,
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
+        MultiplyFunctor, meta::PairSelectorRight>
+>;
+
+using DivideBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        DivideFunctor, NumericTypeUnifier>,
+// DatetimeInterval and YearMonthInterval
+    BinaryFunctorCrossProductPack<
+        std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        DivideFunctor, meta::PairSelectorLeft>
+>;
+
+using ModuloBinaryFunctorPack = FunctorPack<
+// Numeric
+    BinaryFunctorCrossProductPack<
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        std::tuple<IntType, LongType, FloatType, DoubleType>,
+        ModuloFunctor, NumericTypeUnifier>
+>;
+
+using ArithmeticBinaryFunctorPack = FunctorPack<
+    AddBinaryFunctorPack,
+    SubtractBinaryFunctorPack,
+    MultiplyBinaryFunctorPack,
+    DivideBinaryFunctorPack,
+    ModuloBinaryFunctorPack
+>;
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_OPERATIONS_BINARY_OPERATIONS_ARITHMETIC_BINARY_OPERATIONS_HPP_


[23/38] incubator-quickstep git commit: Updates for adding generic types

Posted by ji...@apache.org.
Updates for adding generic types


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/d6a51acf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/d6a51acf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/d6a51acf

Branch: refs/heads/refactor-type
Commit: d6a51acf8837201db70ad146146e6254e6dab2d5
Parents: 98a8e61
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Mon Oct 2 00:26:05 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 cli/PrintToScreen.cpp                           |   2 +-
 compression/CompressionDictionaryBuilder.cpp    |   3 +-
 compression/CompressionDictionaryBuilder.hpp    |   6 +-
 .../aggregation/AggregationHandleAvg.hpp        |   8 +-
 .../aggregation/AggregationHandleMax.hpp        |   6 +-
 .../aggregation/AggregationHandleMin.hpp        |   6 +-
 .../aggregation/AggregationHandleSum.hpp        |   7 +-
 expressions/scalar/ScalarBinaryExpression.cpp   |   2 +-
 expressions/scalar/ScalarCaseExpression.cpp     |   2 +-
 expressions/scalar/ScalarLiteral.cpp            |   2 +-
 expressions/scalar/ScalarUnaryExpression.cpp    |   2 +-
 parser/ParseLiteralValue.cpp                    |   2 +-
 parser/SqlLexer.lpp                             |   2 +
 parser/SqlParser.ypp                            |   2 +
 query_optimizer/expressions/ScalarLiteral.cpp   |   2 +-
 query_optimizer/resolver/Resolver.cpp           |  10 +-
 relational_operators/TableExportOperator.cpp    |   2 +-
 storage/LinearOpenAddressingHashTable.hpp       |  18 +-
 storage/SeparateChainingHashTable.hpp           |  18 +-
 .../SimpleScalarSeparateChainingHashTable.hpp   |  18 +-
 storage/TupleStorageSubBlock.cpp                |   3 +-
 types/ArrayType.cpp                             |  46 +++
 types/ArrayType.hpp                             |  78 +++++
 types/AsciiStringSuperType.hpp                  |   2 +-
 types/BoolType.cpp                              |  12 +-
 types/BoolType.hpp                              |   8 +-
 types/CMakeLists.txt                            |   4 +
 types/CharType.cpp                              |  12 +-
 types/CharType.hpp                              |  10 +-
 types/DateType.cpp                              |   6 +-
 types/DateType.hpp                              |   6 +-
 types/DatetimeIntervalType.cpp                  |   6 +-
 types/DatetimeIntervalType.hpp                  |   6 +-
 types/DatetimeType.cpp                          |   6 +-
 types/DatetimeType.hpp                          |   6 +-
 types/DoubleType.cpp                            |  12 +-
 types/DoubleType.hpp                            |   8 +-
 types/FloatType.cpp                             |  12 +-
 types/FloatType.hpp                             |   8 +-
 types/GenericValue.cpp                          |   0
 types/GenericValue.hpp                          | 118 +++++++
 types/IntType.cpp                               |  12 +-
 types/IntType.hpp                               |   8 +-
 types/LongType.cpp                              |  12 +-
 types/LongType.hpp                              |   8 +-
 types/MetaType.cpp                              |  36 +++
 types/MetaType.hpp                              |  67 ++++
 types/NullType.hpp                              |  14 +-
 types/NumericSuperType.hpp                      |   5 +-
 types/ParameterizedPodLit.hpp                   |   0
 types/Type.cpp                                  |   2 +-
 types/Type.hpp                                  | 103 +++---
 types/Type.proto                                |   5 +
 types/TypeFactory.cpp                           |   5 +-
 types/TypeID.cpp                                |   2 +
 types/TypeID.hpp                                |  32 +-
 types/TypeIDSelectors.hpp                       |  62 ++--
 types/TypeRegistrar.hpp                         |  81 +++--
 types/TypeSynthesizer.hpp                       | 314 ++++++++++++++++---
 types/TypeUtil.hpp                              |   4 +-
 types/TypedValue.hpp                            |  22 ++
 types/VarCharType.cpp                           |  12 +-
 types/VarCharType.hpp                           |  10 +-
 types/YearMonthIntervalType.cpp                 |   6 +-
 types/YearMonthIntervalType.hpp                 |   6 +-
 types/containers/ColumnVector.hpp               |  24 +-
 types/operations/OperationUtil.hpp              |  12 +-
 .../BinaryOperationWrapper.hpp                  |   6 +-
 .../operations/comparisons/BasicComparison.hpp  |  23 +-
 .../unary_operations/CastOperation.cpp          |  10 +-
 .../unary_operations/UnaryOperationWrapper.hpp  |   2 +-
 utility/CMakeLists.txt                          |   7 +-
 utility/CharStream.hpp                          | 106 +++++++
 73 files changed, 1154 insertions(+), 353 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/cli/PrintToScreen.cpp
----------------------------------------------------------------------
diff --git a/cli/PrintToScreen.cpp b/cli/PrintToScreen.cpp
index bb64c93..59f3454 100644
--- a/cli/PrintToScreen.cpp
+++ b/cli/PrintToScreen.cpp
@@ -158,7 +158,7 @@ void PrintToScreen::printTuple(const TupleStorageSubBlock &tuple_store,
               *width_it,
               "NULL");
     } else {
-      attr_it->getType().printValueToFile(value, out, *width_it);
+      attr_it->getType().printTypedValueToFile(value, out, *width_it);
     }
 
     fputc('|', out);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/compression/CompressionDictionaryBuilder.cpp
----------------------------------------------------------------------
diff --git a/compression/CompressionDictionaryBuilder.cpp b/compression/CompressionDictionaryBuilder.cpp
index 905af91..4123541 100644
--- a/compression/CompressionDictionaryBuilder.cpp
+++ b/compression/CompressionDictionaryBuilder.cpp
@@ -121,7 +121,8 @@ void CompressionDictionaryBuilder::buildDictionary(void *location) {
 bool CompressionDictionaryBuilder::insertEntryInternal(const TypedValue &value,
                                                        bool by_reference) {
   DCHECK(!built_);
-  DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//  DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (type_is_nullable_ && value.isNull()) {
     last_insert_was_null_ = !null_value_present_;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/compression/CompressionDictionaryBuilder.hpp
----------------------------------------------------------------------
diff --git a/compression/CompressionDictionaryBuilder.hpp b/compression/CompressionDictionaryBuilder.hpp
index cad6852..9c92ecc 100644
--- a/compression/CompressionDictionaryBuilder.hpp
+++ b/compression/CompressionDictionaryBuilder.hpp
@@ -114,7 +114,8 @@ class CompressionDictionaryBuilder {
    *        value.
    **/
   bool containsValue(const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) {
       return null_value_present_;
     }
@@ -133,7 +134,8 @@ class CompressionDictionaryBuilder {
    * @return The code that maps to value.
    **/
   inline std::uint32_t getCodeForValue(const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     DCHECK(containsValue(value));
     DCHECK(built_);
     if (value.isNull()) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/expressions/aggregation/AggregationHandleAvg.hpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleAvg.hpp b/expressions/aggregation/AggregationHandleAvg.hpp
index 970561c..5dd4205 100644
--- a/expressions/aggregation/AggregationHandleAvg.hpp
+++ b/expressions/aggregation/AggregationHandleAvg.hpp
@@ -117,7 +117,8 @@ class AggregationHandleAvg : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(AggregationStateAvg *state,
                               const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) return;
 
     SpinMutexLock lock(state->mutex_);
@@ -127,8 +128,9 @@ class AggregationHandleAvg : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(const TypedValue &value,
                               std::uint8_t *byte_ptr) const {
-    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
-    if (value.isNull()) return;
+//    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+   // TODO(refactor-type): fix signature.
+   if (value.isNull()) return;
     TypedValue *sum_ptr =
         reinterpret_cast<TypedValue *>(byte_ptr + blank_state_.sum_offset_);
     std::int64_t *count_ptr =

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/expressions/aggregation/AggregationHandleMax.hpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleMax.hpp b/expressions/aggregation/AggregationHandleMax.hpp
index 8f8c0d8..7f55cc7 100644
--- a/expressions/aggregation/AggregationHandleMax.hpp
+++ b/expressions/aggregation/AggregationHandleMax.hpp
@@ -98,13 +98,15 @@ class AggregationHandleMax : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(AggregationStateMax *state,
                               const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     compareAndUpdate(static_cast<AggregationStateMax *>(state), value);
   }
 
   inline void iterateUnaryInl(const TypedValue &value,
                               std::uint8_t *byte_ptr) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     TypedValue *max_ptr = reinterpret_cast<TypedValue *>(byte_ptr);
     compareAndUpdate(max_ptr, value);
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/expressions/aggregation/AggregationHandleMin.hpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleMin.hpp b/expressions/aggregation/AggregationHandleMin.hpp
index 0e62be5..c997788 100644
--- a/expressions/aggregation/AggregationHandleMin.hpp
+++ b/expressions/aggregation/AggregationHandleMin.hpp
@@ -100,13 +100,15 @@ class AggregationHandleMin : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(AggregationStateMin *state,
                               const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     compareAndUpdate(state, value);
   }
 
   inline void iterateUnaryInl(const TypedValue &value,
                               std::uint8_t *byte_ptr) const {
-    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     TypedValue *min_ptr = reinterpret_cast<TypedValue *>(byte_ptr);
     compareAndUpdate(min_ptr, value);
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/expressions/aggregation/AggregationHandleSum.hpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleSum.hpp b/expressions/aggregation/AggregationHandleSum.hpp
index ba4fa9b..72a4673 100644
--- a/expressions/aggregation/AggregationHandleSum.hpp
+++ b/expressions/aggregation/AggregationHandleSum.hpp
@@ -113,7 +113,8 @@ class AggregationHandleSum : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(AggregationStateSum *state,
                               const TypedValue &value) const {
-    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) return;
 
     SpinMutexLock lock(state->mutex_);
@@ -123,8 +124,10 @@ class AggregationHandleSum : public AggregationConcreteHandle {
 
   inline void iterateUnaryInl(const TypedValue &value,
                               std::uint8_t *byte_ptr) const {
-    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+//    DCHECK(value.isPlausibleInstanceOf(argument_type_.getSignature()));
+    // TODO(refactor-type): fix signature.
     if (value.isNull()) return;
+
     TypedValue *sum_ptr =
         reinterpret_cast<TypedValue *>(byte_ptr + blank_state_.sum_offset_);
     bool *null_ptr =

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/expressions/scalar/ScalarBinaryExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarBinaryExpression.cpp b/expressions/scalar/ScalarBinaryExpression.cpp
index 2f0a0d4..78d16a3 100644
--- a/expressions/scalar/ScalarBinaryExpression.cpp
+++ b/expressions/scalar/ScalarBinaryExpression.cpp
@@ -427,7 +427,7 @@ void ScalarBinaryExpression::getFieldStringItems(
     if (static_value_->isNull()) {
       inline_field_values->emplace_back("NULL");
     } else {
-      inline_field_values->emplace_back(type_.printValueToString(*static_value_));
+      inline_field_values->emplace_back(type_.printTypedValueToString(*static_value_));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/expressions/scalar/ScalarCaseExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarCaseExpression.cpp b/expressions/scalar/ScalarCaseExpression.cpp
index 6847425..6fd2c0f 100644
--- a/expressions/scalar/ScalarCaseExpression.cpp
+++ b/expressions/scalar/ScalarCaseExpression.cpp
@@ -540,7 +540,7 @@ void ScalarCaseExpression::getFieldStringItems(
     if (static_value_.isNull()) {
       inline_field_values->emplace_back("NULL");
     } else {
-      inline_field_values->emplace_back(type_.printValueToString(static_value_));
+      inline_field_values->emplace_back(type_.printTypedValueToString(static_value_));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/expressions/scalar/ScalarLiteral.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarLiteral.cpp b/expressions/scalar/ScalarLiteral.cpp
index 808953d..53ba827 100644
--- a/expressions/scalar/ScalarLiteral.cpp
+++ b/expressions/scalar/ScalarLiteral.cpp
@@ -89,7 +89,7 @@ void ScalarLiteral::getFieldStringItems(
   if (internal_literal_.isNull()) {
     inline_field_values->emplace_back("NULL");
   } else {
-    inline_field_values->emplace_back(type_.printValueToString(internal_literal_));
+    inline_field_values->emplace_back(type_.printTypedValueToString(internal_literal_));
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/expressions/scalar/ScalarUnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarUnaryExpression.cpp b/expressions/scalar/ScalarUnaryExpression.cpp
index c2fd931..3e83a6a 100644
--- a/expressions/scalar/ScalarUnaryExpression.cpp
+++ b/expressions/scalar/ScalarUnaryExpression.cpp
@@ -183,7 +183,7 @@ void ScalarUnaryExpression::getFieldStringItems(
     if (static_value_->isNull()) {
       inline_field_values->emplace_back("NULL");
     } else {
-      inline_field_values->emplace_back(type_.printValueToString(*static_value_));
+      inline_field_values->emplace_back(type_.printTypedValueToString(*static_value_));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/parser/ParseLiteralValue.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseLiteralValue.cpp b/parser/ParseLiteralValue.cpp
index d4753ab..04e8a55 100644
--- a/parser/ParseLiteralValue.cpp
+++ b/parser/ParseLiteralValue.cpp
@@ -87,7 +87,7 @@ TypedValue NumericParseLiteralValue::concretize(
     const Type **concretized_type) const {
   TypedValue parsed_value;
   if ((type_hint != nullptr)
-      && (type_hint->getSuperTypeID() == Type::kNumeric)
+      && (type_hint->getSuperTypeID() == SuperTypeID::kNumeric)
       && (type_hint->parseValueFromString(numeric_string_, &parsed_value))) {
     *concretized_type = &(type_hint->getNonNullableVersion());
     return parsed_value;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/parser/SqlLexer.lpp
----------------------------------------------------------------------
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index 020673c..9a63483 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -302,6 +302,8 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "<="               return TOKEN_LEQ;
   ">="               return TOKEN_GEQ;
   "::"               return TOKEN_DOUBLECOLON;
+  "{"                return TOKEN_LBRACE;
+  "}"                return TOKEN_RBRACE;
 
   [-+*/%(),.;]       return yytext[0];
   [\[\]]             return yytext[0];

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/parser/SqlParser.ypp
----------------------------------------------------------------------
diff --git a/parser/SqlParser.ypp b/parser/SqlParser.ypp
index 0d19a4c..156e9e7 100644
--- a/parser/SqlParser.ypp
+++ b/parser/SqlParser.ypp
@@ -301,6 +301,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_JOIN;
 %token TOKEN_KEY;
 %token TOKEN_LAST;
+%token TOKEN_LBRACE;
 %token TOKEN_LEFT;
 %token TOKEN_LIMIT;
 %token TOKEN_LONG;
@@ -323,6 +324,7 @@ void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string
 %token TOKEN_PRIORITY;
 %token TOKEN_QUIT;
 %token TOKEN_RANGE;
+%token TOKEN_RBRACE;
 %token TOKEN_REAL;
 %token TOKEN_REFERENCES;
 %token TOKEN_REGEXP;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/query_optimizer/expressions/ScalarLiteral.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/expressions/ScalarLiteral.cpp b/query_optimizer/expressions/ScalarLiteral.cpp
index d2ab527..278e2cc 100644
--- a/query_optimizer/expressions/ScalarLiteral.cpp
+++ b/query_optimizer/expressions/ScalarLiteral.cpp
@@ -85,7 +85,7 @@ void ScalarLiteral::getFieldStringItems(
   if (value_.isNull()) {
     inline_field_values->push_back("NULL");
   } else {
-    inline_field_values->push_back(value_type_.printValueToString(value_));
+    inline_field_values->push_back(value_type_.printTypedValueToString(value_));
   }
 
   inline_field_names->push_back("type");

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 53fa000..959fc7e 100644
--- a/query_optimizer/resolver/Resolver.cpp
+++ b/query_optimizer/resolver/Resolver.cpp
@@ -1014,8 +1014,8 @@ L::LogicalPtr Resolver::resolveInsertSelection(
       cast_expressions.emplace_back(selection_attributes[aid]);
     } else {
       // TODO(jianqiao): implement Cast operation for non-numeric types.
-      if (destination_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
-          selection_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
+      if (destination_type.getSuperTypeID() == SuperTypeID::kNumeric &&
+          selection_type.getSuperTypeID() == SuperTypeID::kNumeric &&
           destination_type.isSafelyCoercibleFrom(selection_type)) {
         // Add cast operation
 //        const E::AttributeReferencePtr attr = selection_attributes[aid];
@@ -1547,8 +1547,8 @@ L::LogicalPtr Resolver::resolveSetOperations(
       const Type &current_type = attribute_matrix[opid][aid]->getValueType();
       const Type &possible_type = possible_attribute->getValueType();
       if (!possible_type.equals(current_type)) {
-        if (possible_type.getSuperTypeID() == Type::SuperTypeID::kNumeric &&
-            current_type.getSuperTypeID() == Type::SuperTypeID::kNumeric) {
+        if (possible_type.getSuperTypeID() == SuperTypeID::kNumeric &&
+            current_type.getSuperTypeID() == SuperTypeID::kNumeric) {
           if (possible_type.isSafelyCoercibleFrom(current_type)) {
             // Cast current_type to possible_type.
             // Possible_attribute remain the same, nothing needs to change.
@@ -2072,7 +2072,7 @@ E::WindowInfo Resolver::resolveWindow(const ParseWindow &parse_window,
     // needed because -1 might not make sense in this case.
     if (!parse_frame_info->is_row &&
         (order_by_attributes.empty() ||
-         order_by_attributes[0]->getValueType().getSuperTypeID() != Type::SuperTypeID::kNumeric)) {
+         order_by_attributes[0]->getValueType().getSuperTypeID() != SuperTypeID::kNumeric)) {
       THROW_SQL_ERROR_AT(&parse_window)
           << "A numeric attribute should be specified as the first ORDER BY "
           << "attribute in FRAME mode";

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/relational_operators/TableExportOperator.cpp
----------------------------------------------------------------------
diff --git a/relational_operators/TableExportOperator.cpp b/relational_operators/TableExportOperator.cpp
index f6a73bf..419398f 100644
--- a/relational_operators/TableExportOperator.cpp
+++ b/relational_operators/TableExportOperator.cpp
@@ -326,7 +326,7 @@ void TableExportToStringWorkOrder::writeToString(ValueAccessor *accessor,
       if (value.isNull()) {
         return null_string_;
       } else {
-        return value_types[idx]->printValueToString(value);
+        return value_types[idx]->printTypedValueToString(value);
       }
     });
     output->push_back('\n');

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/storage/LinearOpenAddressingHashTable.hpp
----------------------------------------------------------------------
diff --git a/storage/LinearOpenAddressingHashTable.hpp b/storage/LinearOpenAddressingHashTable.hpp
index 044ec6f..34e60d6 100644
--- a/storage/LinearOpenAddressingHashTable.hpp
+++ b/storage/LinearOpenAddressingHashTable.hpp
@@ -567,7 +567,8 @@ const ValueT* LinearOpenAddressingHashTable<ValueT, resizable, serializable, for
     ::getSingle(const TypedValue &key) const {
   DEBUG_ASSERT(!allow_duplicate_keys);
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = this->AdjustHash(key.getHash());
   for (std::size_t bucket_num = hash_code % header_->num_buckets;
@@ -639,7 +640,8 @@ template <typename ValueT,
 void LinearOpenAddressingHashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
     ::getAll(const TypedValue &key, std::vector<const ValueT*> *values) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = this->AdjustHash(key.getHash());
   for (std::size_t bucket_num = hash_code % header_->num_buckets;
@@ -714,7 +716,8 @@ HashTablePutResult
                       const ValueT &value,
                       HashTablePreallocationState *prealloc_state) {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
   DEBUG_ASSERT(prealloc_state == nullptr);
 
   // TODO(chasseur): If allow_duplicate_keys is true, avoid storing more than
@@ -831,7 +834,8 @@ ValueT* LinearOpenAddressingHashTable<ValueT, resizable, serializable, force_key
                      const ValueT &initial_value) {
   DEBUG_ASSERT(!allow_duplicate_keys);
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   // Block is do/while(false) so we can use break.
   do {
@@ -1040,7 +1044,8 @@ bool LinearOpenAddressingHashTable<ValueT, resizable, serializable, force_key_co
                          const ValueT **value,
                          std::size_t *entry_num) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (*entry_num == 0) {
     *entry_num = hash_code % header_->num_buckets;
@@ -1116,7 +1121,8 @@ template <typename ValueT,
 bool LinearOpenAddressingHashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
     ::hasKey(const TypedValue &key) const {
   DCHECK_EQ(1u, this->key_types_.size());
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = this->AdjustHash(key.getHash());
   for (std::size_t bucket_num = hash_code % header_->num_buckets;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/storage/SeparateChainingHashTable.hpp
----------------------------------------------------------------------
diff --git a/storage/SeparateChainingHashTable.hpp b/storage/SeparateChainingHashTable.hpp
index 2403623..d60e40b 100644
--- a/storage/SeparateChainingHashTable.hpp
+++ b/storage/SeparateChainingHashTable.hpp
@@ -565,7 +565,8 @@ const ValueT* SeparateChainingHashTable<ValueT, resizable, serializable, force_k
     ::getSingle(const TypedValue &key) const {
   DEBUG_ASSERT(!allow_duplicate_keys);
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHash();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -621,7 +622,8 @@ template <typename ValueT,
 void SeparateChainingHashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
     ::getAll(const TypedValue &key, std::vector<const ValueT*> *values) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHash();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -680,7 +682,8 @@ HashTablePutResult
                       const ValueT &value,
                       HashTablePreallocationState *prealloc_state) {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (prealloc_state == nullptr) {
     // Early check for a free bucket.
@@ -822,7 +825,8 @@ ValueT* SeparateChainingHashTable<ValueT, resizable, serializable, force_key_cop
                      const ValueT &initial_value) {
   DEBUG_ASSERT(!allow_duplicate_keys);
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (variable_key_size > 0) {
     // Don't allocate yet, since the key may already be present. However, we
@@ -988,7 +992,8 @@ bool SeparateChainingHashTable<ValueT, resizable, serializable, force_key_copy,
                          const ValueT **value,
                          std::size_t *entry_num) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (*entry_num == 0) {
     *entry_num = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -1066,7 +1071,8 @@ template <typename ValueT,
 bool SeparateChainingHashTable<ValueT, resizable, serializable, force_key_copy, allow_duplicate_keys>
     ::hasKey(const TypedValue &key) const {
   DEBUG_ASSERT(this->key_types_.size() == 1);
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHash();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/storage/SimpleScalarSeparateChainingHashTable.hpp
----------------------------------------------------------------------
diff --git a/storage/SimpleScalarSeparateChainingHashTable.hpp b/storage/SimpleScalarSeparateChainingHashTable.hpp
index 81f2044..1a515e3 100644
--- a/storage/SimpleScalarSeparateChainingHashTable.hpp
+++ b/storage/SimpleScalarSeparateChainingHashTable.hpp
@@ -563,7 +563,8 @@ const ValueT* SimpleScalarSeparateChainingHashTable<ValueT,
                                                     allow_duplicate_keys>
     ::getSingle(const TypedValue &key) const {
   DCHECK(!allow_duplicate_keys);
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHashScalarLiteral();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -593,7 +594,8 @@ void SimpleScalarSeparateChainingHashTable<ValueT,
                                            force_key_copy,
                                            allow_duplicate_keys>
     ::getAll(const TypedValue &key, std::vector<const ValueT*> *values) const {
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHashScalarLiteral();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -626,7 +628,8 @@ HashTablePutResult
                       const std::size_t variable_key_size,
                       const ValueT &value,
                       HashTablePreallocationState *prealloc_state) {
-  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DEBUG_ASSERT(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (prealloc_state == nullptr) {
     // Early check for a free bucket.
@@ -682,7 +685,8 @@ ValueT* SimpleScalarSeparateChainingHashTable<ValueT,
                      const std::size_t variable_key_size,
                      const ValueT &initial_value) {
   DCHECK(!allow_duplicate_keys);
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
   DCHECK_EQ(0u, variable_key_size);
 
   const std::size_t hash_code = key.getHashScalarLiteral();
@@ -752,7 +756,8 @@ bool SimpleScalarSeparateChainingHashTable<ValueT,
                          const std::size_t hash_code,
                          const ValueT **value,
                          std::size_t *entry_num) const {
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   if (*entry_num == 0) {
     *entry_num = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);
@@ -792,7 +797,8 @@ bool SimpleScalarSeparateChainingHashTable<ValueT,
                                            allow_duplicate_keys>
     ::hasKey(const TypedValue &key) const {
   DCHECK_EQ(1u, this->key_types_.size());
-  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+//  DCHECK(key.isPlausibleInstanceOf(this->key_types_.front()->getSignature()));
+  // TODO(refactor-type): fix signature.
 
   const std::size_t hash_code = key.getHashScalarLiteral();
   std::size_t bucket_ref = slots_[hash_code % header_->num_slots].load(std::memory_order_relaxed);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/storage/TupleStorageSubBlock.cpp
----------------------------------------------------------------------
diff --git a/storage/TupleStorageSubBlock.cpp b/storage/TupleStorageSubBlock.cpp
index f2eef49..50b84ca 100644
--- a/storage/TupleStorageSubBlock.cpp
+++ b/storage/TupleStorageSubBlock.cpp
@@ -101,7 +101,8 @@ void TupleStorageSubBlock::paranoidInsertTypeCheck(const Tuple &tuple) {
   CatalogRelationSchema::const_iterator attr_it = relation_.begin();
 
   while (value_it != tuple.end()) {
-    assert(value_it->isPlausibleInstanceOf(attr_it->getType().getSignature()));
+//    assert(value_it->isPlausibleInstanceOf(attr_it->getType().getSignature()));
+    // TODO(refactor-type): fix signature.
 
     ++value_it;
     ++attr_it;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/ArrayType.cpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.cpp b/types/ArrayType.cpp
new file mode 100644
index 0000000..198e580
--- /dev/null
+++ b/types/ArrayType.cpp
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/ArrayType.hpp"
+
+#include <string>
+
+#include "types/TypeID.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+std::string ArrayType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
+
+  const std::vector<UntypedLiteral*> &literals = castValueToLiteral(value);
+  std::string ret = "{";
+  if (!literals.empty()) {
+    ret.append(element_type_.printValueToString(literals.front()));
+    for (std::size_t i = 1; i < literals.size(); ++i) {
+      ret.append(", ");
+      ret.append(element_type_.printValueToString(literals.at(i)));
+    }
+  }
+  ret.append("}");
+  return ret;
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/ArrayType.hpp
----------------------------------------------------------------------
diff --git a/types/ArrayType.hpp b/types/ArrayType.hpp
new file mode 100644
index 0000000..1c66ed2
--- /dev/null
+++ b/types/ArrayType.hpp
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_ARRAY_TYPE_HPP_
+#define QUICKSTEP_TYPES_ARRAY_TYPE_HPP_
+
+#include <cstddef>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class TypedValue;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class ArrayType : public TypeSynthesizer<kArray> {
+ public:
+  int getPrintWidth() const override {
+    return 16;
+  }
+
+  std::string printValueToString(const UntypedLiteral *value) const override;
+
+  bool parseValueFromString(const std::string &value_string,
+                            TypedValue *value) const override {
+    return false;
+  }
+
+ private:
+  ArrayType(const bool nullable, const std::vector<GenericValue> &parameters)
+      : TypeSynthesizer<kArray>(nullable, 0, 0x1000, parameters),
+        element_type_(ExtractType(parameters)) {
+    // TODO(refactor-type): Possibly infinite maximum size.
+    // TODO(refactor-type): Validate parameters.
+  }
+
+  static const Type& ExtractType(const std::vector<GenericValue> &parameters) {
+    DCHECK_EQ(1u, parameters.size());
+    const GenericValue &value = parameters.front();
+    DCHECK(value.getType().getTypeID() == kMetaType);
+    return *static_cast<const Type*>(value.getValue());
+  }
+
+  const Type &element_type_;
+
+  QUICKSTEP_SYNTHESIZE_TYPE(ArrayType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_ARRAY_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/AsciiStringSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp
index 959c288..b6abcdf 100644
--- a/types/AsciiStringSuperType.hpp
+++ b/types/AsciiStringSuperType.hpp
@@ -42,7 +42,7 @@ class AsciiStringSuperType : public TypeSynthesizer<type_id> {
     if (original_type.isNullable() && !this->nullable_) {
       return false;
     }
-    return (original_type.getSuperTypeID() == Type::kAsciiString)
+    return (original_type.getSuperTypeID() == SuperTypeID::kAsciiString)
            || (original_type.getTypeID() == kNullType);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/BoolType.cpp
----------------------------------------------------------------------
diff --git a/types/BoolType.cpp b/types/BoolType.cpp
index 83cf060..9680770 100644
--- a/types/BoolType.cpp
+++ b/types/BoolType.cpp
@@ -30,21 +30,21 @@
 
 namespace quickstep {
 
-std::string BoolType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string BoolType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  return value.getLiteral<bool>() ? "true" : "false";
+  return castValueToLiteral(value) ? "true" : "false";
 }
 
-void BoolType::printValueToFile(const TypedValue &value,
+void BoolType::printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*s",
                static_cast<int>(padding),
-               value.getLiteral<bool>() ? "true" : "false");
+               castValueToLiteral(value) ? "true" : "false");
 }
 
 bool BoolType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/BoolType.hpp
----------------------------------------------------------------------
diff --git a/types/BoolType.hpp b/types/BoolType.hpp
index f149e76..2ba380a 100644
--- a/types/BoolType.hpp
+++ b/types/BoolType.hpp
@@ -48,9 +48,9 @@ class BoolType : public NumericSuperType<kBool> {
     return 5;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -61,9 +61,7 @@ class BoolType : public NumericSuperType<kBool> {
   explicit BoolType(const bool nullable)
       : NumericSuperType<kBool>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(BoolType);
+  QUICKSTEP_SYNTHESIZE_TYPE(BoolType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 325c6ea..07f9d97 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -32,6 +32,7 @@ QS_PROTOBUF_GENERATE_CPP(types_TypedValue_proto_srcs types_TypedValue_proto_hdrs
 QS_PROTOBUF_GENERATE_CPP(types_Type_proto_srcs types_Type_proto_hdrs Type.proto)
 
 # Declare micro-libs:
+add_library(quickstep_types_ArrayType ArrayType.cpp ArrayType.hpp)
 add_library(quickstep_types_AsciiStringSuperType ../empty_src.cpp AsciiStringSuperType.hpp)
 add_library(quickstep_types_BoolType BoolType.cpp BoolType.hpp)
 add_library(quickstep_types_CharType CharType.cpp CharType.hpp)
@@ -42,16 +43,19 @@ add_library(quickstep_types_DatetimeLit ../empty_src.cpp DatetimeLit.hpp)
 add_library(quickstep_types_DatetimeType DatetimeType.cpp DatetimeType.hpp)
 add_library(quickstep_types_DoubleType DoubleType.cpp DoubleType.hpp)
 add_library(quickstep_types_FloatType FloatType.cpp FloatType.hpp)
+add_library(quickstep_types_GenericValue GenericValue.cpp GenericValue.hpp)
 add_library(quickstep_types_IntType IntType.cpp IntType.hpp)
 add_library(quickstep_types_IntervalLit ../empty_src.cpp IntervalLit.hpp)
 add_library(quickstep_types_IntervalParser IntervalParser.cpp IntervalParser.hpp)
 add_library(quickstep_types_LongType LongType.cpp LongType.hpp)
+add_library(quickstep_types_MetaType MetaType.cpp MetaType.hpp)
 add_library(quickstep_types_NullCoercibilityCheckMacro ../empty_src.cpp NullCoercibilityCheckMacro.hpp)
 add_library(quickstep_types_NullLit ../empty_src.cpp NullLit.hpp)
 add_library(quickstep_types_NullType ../empty_src.cpp NullType.hpp)
 add_library(quickstep_types_NumericSuperType ../empty_src.cpp NumericSuperType.hpp)
 add_library(quickstep_types_NumericTypeSafeCoercibility ../empty_src.cpp NumericTypeSafeCoercibility.hpp)
 add_library(quickstep_types_NumericTypeUnifier ../empty_src.cpp NumericTypeUnifier.hpp)
+add_library(quickstep_types_ParameterizedPodLit ../empty_src.cpp ParameterizedPodLit.hpp)
 add_library(quickstep_types_Type Type.cpp Type.hpp)
 add_library(quickstep_types_TypeErrors ../empty_src.cpp TypeErrors.hpp)
 add_library(quickstep_types_TypeFactory TypeFactory.cpp TypeFactory.hpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/CharType.cpp
----------------------------------------------------------------------
diff --git a/types/CharType.cpp b/types/CharType.cpp
index 2ed469b..ea3d00e 100644
--- a/types/CharType.cpp
+++ b/types/CharType.cpp
@@ -65,17 +65,17 @@ string CharType::getName() const {
   return name;
 }
 
-std::string CharType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string CharType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  const char *cstr = static_cast<const char*>(value.getOutOfLineData());
+  const char *cstr = static_cast<const char*>(castValueToLiteral(value).getOutOfLineData());
   return std::string(cstr, strnlen(cstr, length_));
 }
 
-void CharType::printValueToFile(const TypedValue &value,
+void CharType::printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
   DCHECK_EQ(length_, static_cast<decltype(length_)>(static_cast<int>(length_)))
       << "Can not convert CHAR Type's maximum length " << length_
       << " to int for fprintf()";
@@ -84,7 +84,7 @@ void CharType::printValueToFile(const TypedValue &value,
                "%*.*s",
                padding,
                static_cast<int>(length_),
-               static_cast<const char*>(value.getOutOfLineData()));
+               castValueToLiteral(value).getOutOfLineData());
 }
 
 bool CharType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index c90a8da..32b0c7a 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -53,9 +53,9 @@ class CharType : public AsciiStringSuperType<kChar> {
     return length_;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -66,12 +66,10 @@ class CharType : public AsciiStringSuperType<kChar> {
                          const Type &original_type) const override;
 
  private:
-  CharType(const std::size_t length, const bool nullable)
+  CharType(const bool nullable, const std::size_t length)
       : AsciiStringSuperType<kChar>(nullable, length, length, length) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(CharType);
+  QUICKSTEP_SYNTHESIZE_TYPE(CharType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/DateType.cpp
----------------------------------------------------------------------
diff --git a/types/DateType.cpp b/types/DateType.cpp
index de1e554..dcd779d 100644
--- a/types/DateType.cpp
+++ b/types/DateType.cpp
@@ -45,10 +45,10 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string DateType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string DateType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  const DateLit literal = value.getLiteral<DateLit>();
+  const DateLit &literal = castValueToLiteral(value);
   const std::int32_t year = literal.year;
 
   char datebuf[DateLit::kIsoChars + 1];

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index 088c125..b7d1820 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -47,7 +47,7 @@ class DateType : public TypeSynthesizer<kDate> {
     return DateLit::kIsoChars;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
   /**
    * @note value_string is expected to be in (possibly extended) ISO-8601
@@ -68,9 +68,7 @@ class DateType : public TypeSynthesizer<kDate> {
   explicit DateType(const bool nullable)
       : TypeSynthesizer<kDate>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(DateType);
+  QUICKSTEP_SYNTHESIZE_TYPE(DateType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/DatetimeIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.cpp b/types/DatetimeIntervalType.cpp
index 2c77f89..e419ce3 100644
--- a/types/DatetimeIntervalType.cpp
+++ b/types/DatetimeIntervalType.cpp
@@ -46,10 +46,10 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string DatetimeIntervalType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string DatetimeIntervalType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  std::int64_t subseconds = value.getLiteral<DatetimeIntervalLit>().interval_ticks;
+  std::int64_t subseconds = castValueToLiteral(value).interval_ticks;
   const bool negative_interval = subseconds < 0;
   if (negative_interval) {
     subseconds = -subseconds;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index d22f965..bf36609 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -47,7 +47,7 @@ class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
     return DatetimeIntervalLit::kPrintingChars;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
   TypedValue makeZeroValue() const override {
     return TypedValue(DatetimeIntervalLit{0});
@@ -60,9 +60,7 @@ class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
   explicit DatetimeIntervalType(const bool nullable)
       : TypeSynthesizer<kDatetimeInterval>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(DatetimeIntervalType);
+  QUICKSTEP_SYNTHESIZE_TYPE(DatetimeIntervalType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/DatetimeType.cpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.cpp b/types/DatetimeType.cpp
index 723da61..11ffae9 100644
--- a/types/DatetimeType.cpp
+++ b/types/DatetimeType.cpp
@@ -50,10 +50,10 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string DatetimeType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string DatetimeType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  const DatetimeLit literal = value.getLiteral<DatetimeLit>();
+  const DatetimeLit &literal = castValueToLiteral(value);
   const std::time_t timestamp = literal.epochTime();
   struct tm timeinfo;
   quickstep::gmtime_r(&timestamp, &timeinfo);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index 6ee15c6..924ff35 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -48,7 +48,7 @@ class DatetimeType
     return DatetimeLit::kIsoChars;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
   /**
    * @note value_string is expected to be in (possibly extended) ISO-8601
@@ -77,9 +77,7 @@ class DatetimeType
   explicit DatetimeType(const bool nullable)
       : TypeSynthesizer<kDatetime>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(DatetimeType);
+  QUICKSTEP_SYNTHESIZE_TYPE(DatetimeType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/DoubleType.cpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.cpp b/types/DoubleType.cpp
index f5c2650..fb50957 100644
--- a/types/DoubleType.cpp
+++ b/types/DoubleType.cpp
@@ -38,15 +38,15 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string DoubleType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string DoubleType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
   char printbuffer[kPrintWidth + 1];
   int written = snprintf(printbuffer,
                          sizeof(printbuffer),
                          "%.*g",
                          std::numeric_limits<double>::max_digits10,
-                         value.getLiteral<double>());
+                         castValueToLiteral(value));
   DCHECK_GE(written, 0) << "snprintf() encountered an encoding error";
   DCHECK_LT(static_cast<std::size_t>(written), sizeof(printbuffer))
       << "snprintf() would have written a string of length " << written
@@ -54,16 +54,16 @@ std::string DoubleType::printValueToString(const TypedValue &value) const {
   return std::string(printbuffer);
 }
 
-void DoubleType::printValueToFile(const TypedValue &value,
+void DoubleType::printValueToFile(const UntypedLiteral *value,
                                   FILE *file,
                                   const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*.*g",
                padding,
                std::numeric_limits<double>::max_digits10,
-               value.getLiteral<double>());
+               castValueToLiteral(value));
 }
 
 bool DoubleType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index 05bec64..ddba4e3 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -46,9 +46,9 @@ class DoubleType : public NumericSuperType<kDouble> {
     return kPrintWidth;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -74,9 +74,7 @@ class DoubleType : public NumericSuperType<kDouble> {
   explicit DoubleType(const bool nullable)
       : NumericSuperType<kDouble>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(DoubleType);
+  QUICKSTEP_SYNTHESIZE_TYPE(DoubleType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/FloatType.cpp
----------------------------------------------------------------------
diff --git a/types/FloatType.cpp b/types/FloatType.cpp
index be22770..ca741a6 100644
--- a/types/FloatType.cpp
+++ b/types/FloatType.cpp
@@ -38,15 +38,15 @@ using std::snprintf;
 
 namespace quickstep {
 
-std::string FloatType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string FloatType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
   char printbuffer[kPrintWidth + 1];
   int written = snprintf(printbuffer,
                          sizeof(printbuffer),
                          "%.*g",
                          std::numeric_limits<float>::max_digits10,
-                         value.getLiteral<float>());
+                         castValueToLiteral(value));
   DCHECK_GE(written, 0) << "snprintf() encountered an encoding error";
   DCHECK_LT(static_cast<std::size_t>(written), sizeof(printbuffer))
       << "snprintf() would have written a string of length " << written
@@ -54,16 +54,16 @@ std::string FloatType::printValueToString(const TypedValue &value) const {
   return std::string(printbuffer);
 }
 
-void FloatType::printValueToFile(const TypedValue &value,
+void FloatType::printValueToFile(const UntypedLiteral *value,
                                  FILE *file,
                                  const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*.*g",
                static_cast<int>(padding),
                std::numeric_limits<float>::max_digits10,
-               value.getLiteral<float>());
+               castValueToLiteral(value));
 }
 
 bool FloatType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 6c8466d..68a636b 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -46,9 +46,9 @@ class FloatType : public NumericSuperType<kFloat> {
     return kPrintWidth;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -74,9 +74,7 @@ class FloatType : public NumericSuperType<kFloat> {
   explicit FloatType(const bool nullable)
       : NumericSuperType<kFloat>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(FloatType);
+  QUICKSTEP_SYNTHESIZE_TYPE(FloatType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/GenericValue.cpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.cpp b/types/GenericValue.cpp
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/GenericValue.hpp
----------------------------------------------------------------------
diff --git a/types/GenericValue.hpp b/types/GenericValue.hpp
new file mode 100644
index 0000000..61529d6
--- /dev/null
+++ b/types/GenericValue.hpp
@@ -0,0 +1,118 @@
+/**
+ * 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_GENERIC_VALUE_HPP_
+#define QUICKSTEP_TYPES_GENERIC_VALUE_HPP_
+
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "utility/HashPair.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class GenericValue {
+ public:
+  GenericValue(const Type &type, const UntypedLiteral *value, const bool owns)
+      : type_(type), value_(value), owns_(owns) {}
+
+  template <typename TypeClass>
+  GenericValue(const TypeClass &type, const typename TypeClass::cpptype &value)
+      : type_(type), value_(type.cloneValue(&value)), owns_(true) {}
+
+  GenericValue(const GenericValue &other)
+      : type_(other.type_),
+        value_(other.owns_ ? type_.cloneValue(other.value_) : other.value_),
+        owns_(other.owns_) {}
+
+  GenericValue(GenericValue &&other)
+      : type_(other.type_),
+        value_(other.value_),
+        owns_(other.owns_) {
+    other.owns_ = false;
+  }
+
+  ~GenericValue() {
+    if (owns_ && value_ != nullptr) {
+      type_.destroyValue(const_cast<void*>(value_));
+    }
+  }
+
+  inline bool isNull() const {
+    DCHECK(value_ != nullptr || type_.isNullable());
+    return value_ == nullptr;
+  }
+
+  inline bool isReference() const {
+    return !owns_;
+  }
+
+  inline const Type& getType() const {
+    return type_;
+  }
+
+  inline const UntypedLiteral* getValue() const {
+    return value_;
+  }
+
+  template <TypeID type_id>
+  inline const typename TypeIDTrait<type_id>::cpptype& getLiteral() const {
+    DCHECK_EQ(type_id, type_.getTypeID());
+    return *static_cast<typename TypeIDTrait<type_id>::cpptype*>(value_);
+  }
+
+  inline void ensureNotReference() {
+    if (isReference()) {
+      value_ = type_.cloneValue(value_);
+      owns_ = true;
+    }
+  }
+
+  inline bool operator==(const GenericValue &other) const {
+    return type_.equals(other.type_) &&
+           type_.checkValuesEqual(value_, other.value_);
+  }
+
+  inline std::size_t getHash() const {
+    return CombineHashes(type_.getHash(), type_.hashValue(value_));
+  }
+
+ private:
+  const Type &type_;
+  const UntypedLiteral *value_;
+  bool owns_;
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_GENERIC_VALUE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/IntType.cpp
----------------------------------------------------------------------
diff --git a/types/IntType.cpp b/types/IntType.cpp
index 1005aa9..8e3aff1 100644
--- a/types/IntType.cpp
+++ b/types/IntType.cpp
@@ -29,21 +29,21 @@
 
 namespace quickstep {
 
-std::string IntType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string IntType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  return std::to_string(value.getLiteral<int>());
+  return std::to_string(castValueToLiteral(value));
 }
 
-void IntType::printValueToFile(const TypedValue &value,
+void IntType::printValueToFile(const UntypedLiteral *value,
                                FILE *file,
                                const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*d",
                static_cast<int>(padding),
-               value.getLiteral<int>());
+               castValueToLiteral(value));
 }
 
 bool IntType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index 84cc7ce..d83c257 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -48,9 +48,9 @@ class IntType : public NumericSuperType<kInt> {
     return std::numeric_limits<int>::digits10 + 2;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -61,9 +61,7 @@ class IntType : public NumericSuperType<kInt> {
   explicit IntType(const bool nullable)
       : NumericSuperType<kInt>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(IntType);
+  QUICKSTEP_SYNTHESIZE_TYPE(IntType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/LongType.cpp
----------------------------------------------------------------------
diff --git a/types/LongType.cpp b/types/LongType.cpp
index 334821d..82dce39 100644
--- a/types/LongType.cpp
+++ b/types/LongType.cpp
@@ -35,21 +35,21 @@
 
 namespace quickstep {
 
-std::string LongType::printValueToString(const TypedValue &value) const {
-  DCHECK(!value.isNull());
+std::string LongType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
 
-  return std::to_string(value.getLiteral<std::int64_t>());
+  return std::to_string(castValueToLiteral(value));
 }
 
-void LongType::printValueToFile(const TypedValue &value,
+void LongType::printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding) const {
-  DCHECK(!value.isNull());
+  DCHECK(value != nullptr);
 
   std::fprintf(file,
                "%*" PRId64,
                static_cast<int>(padding),
-               value.getLiteral<std::int64_t>());
+               castValueToLiteral(value));
 }
 
 bool LongType::parseValueFromString(const std::string &value_string,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index e52a166..7561975 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -49,9 +49,9 @@ class LongType : public NumericSuperType<kLong> {
     return std::numeric_limits<std::int64_t>::digits10 + 2;
   }
 
-  std::string printValueToString(const TypedValue &value) const override;
+  std::string printValueToString(const UntypedLiteral *value) const override;
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override;
 
@@ -62,9 +62,7 @@ class LongType : public NumericSuperType<kLong> {
   explicit LongType(const bool nullable)
       : NumericSuperType<kLong>(nullable) {}
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(LongType);
+  QUICKSTEP_SYNTHESIZE_TYPE(LongType);
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/MetaType.cpp
----------------------------------------------------------------------
diff --git a/types/MetaType.cpp b/types/MetaType.cpp
new file mode 100644
index 0000000..01fc3a0
--- /dev/null
+++ b/types/MetaType.cpp
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/MetaType.hpp"
+
+#include <string>
+
+#include "types/TypeID.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+std::string MetaType::printValueToString(const UntypedLiteral *value) const {
+  DCHECK(value != nullptr);
+
+  return castValueToLiteral(value)->getName();
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/MetaType.hpp
----------------------------------------------------------------------
diff --git a/types/MetaType.hpp b/types/MetaType.hpp
new file mode 100644
index 0000000..0c3952b
--- /dev/null
+++ b/types/MetaType.hpp
@@ -0,0 +1,67 @@
+/**
+ * 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_META_TYPE_HPP_
+#define QUICKSTEP_TYPES_META_TYPE_HPP_
+
+#include <cstddef>
+#include <string>
+
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class TypedValue;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+class MetaType : public TypeSynthesizer<kMetaType> {
+ public:
+  int getPrintWidth() const override {
+    return 16;
+  }
+
+  std::string printValueToString(const UntypedLiteral *value) const override;
+
+  bool parseValueFromString(const std::string &value_string,
+                            TypedValue *value) const override {
+    return false;
+  }
+
+ private:
+  MetaType(const bool nullable)
+      : TypeSynthesizer<kMetaType>(nullable, sizeof(TypeID), 0x100) {
+    // TODO(refactor-type): Possibly infinite maximum size.
+  }
+
+  QUICKSTEP_SYNTHESIZE_TYPE(MetaType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_META_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index 7491ca7..8dd237e 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -17,8 +17,8 @@
  * under the License.
  **/
 
-#ifndef QUICKSTEP_TYPES_NULLTYPE_HPP_
-#define QUICKSTEP_TYPES_NULLTYPE_HPP_
+#ifndef QUICKSTEP_TYPES_NULL_TYPE_HPP_
+#define QUICKSTEP_TYPES_NULL_TYPE_HPP_
 
 #include <cstddef>
 #include <cstdio>
@@ -69,11 +69,11 @@ class NullType : public TypeSynthesizer<kNullType> {
     return 0;
   }
 
-  std::string printValueToString(const TypedValue &value) const override {
+  std::string printValueToString(const UntypedLiteral *value) const override {
     LOG(FATAL) << "NullType is not printable";
   }
 
-  void printValueToFile(const TypedValue &value,
+  void printValueToFile(const UntypedLiteral *value,
                         FILE *file,
                         const int padding = 0) const override {
     LOG(FATAL) << "NullType is not printable";
@@ -92,13 +92,11 @@ class NullType : public TypeSynthesizer<kNullType> {
     DCHECK(nullable);
   }
 
-  template <typename, bool> friend class TypeInstance;
-
-  DISALLOW_COPY_AND_ASSIGN(NullType);
+  QUICKSTEP_SYNTHESIZE_TYPE(NullType);
 };
 
 /** @} */
 
 }  // namespace quickstep
 
-#endif  // QUICKSTEP_TYPES_NULLTYPE_HPP_
+#endif  // QUICKSTEP_TYPES_NULL_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index abe8b87..6576cbf 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -22,6 +22,7 @@
 
 #include <cstddef>
 #include <unordered_set>
+#include <utility>
 
 #include "types/NullCoercibilityCheckMacro.hpp"
 #include "types/NumericTypeSafeCoercibility.hpp"
@@ -54,7 +55,7 @@ class NumericSuperType : public TypeSynthesizer<type_id> {
 
   bool isCoercibleFrom(const Type &original_type) const override {
     QUICKSTEP_NULL_COERCIBILITY_CHECK();
-    return (original_type.getSuperTypeID() == Type::kNumeric);
+    return (original_type.getSuperTypeID() == SuperTypeID::kNumeric);
   }
 
   TypedValue makeZeroValue() const override {
@@ -63,7 +64,7 @@ class NumericSuperType : public TypeSynthesizer<type_id> {
 
   TypedValue coerceValue(const TypedValue &original_value,
                          const Type &original_type) const override {
-    if (original_type.getSuperTypeID() != Type::kNumeric) {
+    if (original_type.getSuperTypeID() != SuperTypeID::kNumeric) {
       LOG(FATAL) << "Attempted to coerce Type " << original_type.getName()
                  << " (not recognized as a numeric Type) to " << Type::getName();
     }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/ParameterizedPodLit.hpp
----------------------------------------------------------------------
diff --git a/types/ParameterizedPodLit.hpp b/types/ParameterizedPodLit.hpp
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index b69cb65..34678c7 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -53,7 +53,7 @@ std::size_t Type::estimateAverageByteLength() const {
   }
 }
 
-void Type::printValueToFile(const TypedValue &value,
+void Type::printValueToFile(const UntypedLiteral *value,
                             FILE *file,
                             const int padding) const {
   std::fprintf(file, "%*s", padding, printValueToString(value).c_str());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index bf6c167..47f00e6 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -24,10 +24,13 @@
 #include <cstdint>
 #include <cstdio>
 #include <string>
+#include <vector>
 
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "types/TypedValue.hpp"
+#include "utility/CharStream.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
@@ -93,15 +96,6 @@ struct YearMonthIntervalLit;
 class Type {
  public:
   /**
-   * @brief Categories of intermediate supertypes.
-   **/
-  enum SuperTypeID {
-    kNumeric = 0,  // Fixed-length numeric types (Int, Long, Float, Double)
-    kAsciiString,  // ASCII strings (Char, VarChar)
-    kOther         // Others (Date, Datetime, DatetimeInterval, YearMonthInterval)
-  };
-
-  /**
    * @brief Virtual destructor.
    **/
   virtual ~Type() {
@@ -142,23 +136,6 @@ class Type {
   }
 
   /**
-   * @brief Get this Type's signature.
-   *
-   * @note The signature does not necessarily uniquely identify this Type. It
-   *       merely provides some basic information for debugging that can be
-   *       passed to TypedValue::isPlausibleInstanceOf().
-   *
-   * @return This Type's signature.
-   **/
-  inline TypeSignature getSignature() const {
-    TypeSignature sig;
-    sig.id = type_id_;
-    sig.nullable = nullable_;
-    sig.length = parameter_;
-    return sig;
-  }
-
-  /**
    * @brief Get a nullable (but otherwise identical) version of this type.
    *
    * @return This Type's nullable counterpart (or this Type itself if already
@@ -313,34 +290,19 @@ class Type {
    **/
   virtual int getPrintWidth() const = 0;
 
-  /**
-   * @brief "Print" a value of this Type as a human-readable string.
-   * @warning It is an error to call this with a NULL value. This method prints
-   *          non-NULL values only.
-   *
-   * @param value A value of this Type.
-   * @return The human-readable string representation of value.
-   **/
-  virtual std::string printValueToString(const TypedValue &value) const = 0;
 
-  /**
-   * @brief Print the human-readable string representation of a value of this
-   *        type to a FILE stream.
-   * @warning It is an error to call this with a NULL value. This method prints
-   *          non-NULL values only.
-   *
-   * @param value A value of this Type.
-   * @param file An open FILE stream to print to.
-   * @param padding If nonzero, left-pad the printed value with spaces up to
-   *        this length. If padding is less than the number of characters
-   *        needed to print the value, then more than padding characters will
-   *        be printed (see getPrintWidth() for information about how long a
-   *        printed string may be).
-   **/
-  virtual void printValueToFile(const TypedValue &value,
+  virtual std::string printValueToString(const UntypedLiteral *value) const = 0;
+
+
+  virtual void printValueToFile(const UntypedLiteral *value,
                                 FILE *file,
                                 const int padding = 0) const;
 
+  virtual std::string printTypedValueToString(const TypedValue &value) const = 0;
+
+  virtual void printTypedValueToFile(const TypedValue &value,
+                                     FILE *file,
+                                     const int padding = 0) const = 0;
   /**
    * @brief Make a TypedValue of this Type.
    *
@@ -439,17 +401,51 @@ class Type {
   virtual TypedValue coerceValue(const TypedValue &original_value,
                                  const Type &original_type) const;
 
+  virtual std::size_t getHash() const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+
+  virtual bool checkValuesEqual(const UntypedLiteral *lhs,
+                                const UntypedLiteral *rhs) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual UntypedLiteral* cloneValue(const UntypedLiteral *value) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual std::size_t hashValue(const UntypedLiteral *value) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual void destroyValue(UntypedLiteral *value_ptr) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual CharStream marshallValue(const UntypedLiteral *value) const {
+    LOG(FATAL) << "Not implemented";
+  }
+
+  virtual UntypedLiteral* unmarshallValue(const void *data,
+                                          const std::size_t length) const {
+    LOG(FATAL) << "Not implemented";
+
+  }
+
+  virtual UntypedLiteral* unmarshallValue(const TypedValue &value) const = 0;
+
+  virtual UntypedLiteral* unmarshallValue(TypedValue &&value) const = 0;
+
  protected:
   Type(const SuperTypeID super_type_id,
        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 parameter = 0)
+       const std::size_t maximum_byte_length)
       : 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) {
   }
@@ -457,7 +453,6 @@ 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_;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index ed8df36..b93f894 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -27,5 +27,10 @@ message Type {
   required TypeID type_id = 1;
   required bool nullable = 2;
   optional uint64 length = 3;
+  repeated GenericValue parameters = 4;
 }
 
+message GenericValue {
+  required Type type = 1;
+  required bytes data = 2;
+}

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index 223d487..d60f701 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -22,6 +22,7 @@
 #include <cstddef>
 #include <string>
 
+#include "types/GenericValue.hpp"
 #include "types/Type.hpp"
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
@@ -42,7 +43,7 @@ const Type& TypeFactory::GetType(const TypeID id,
       << "Called TypeFactory::GetType() for a type which requires "
       << " a length parameter without specifying one.";
 
-  return *InvokeOnTypeID<TypeIDSelectorNonParameterized>(
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kCxxInlinePod>>(
       id,
       [&](auto id) -> const Type* {  // NOLINT(build/c++11)
     return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable);
@@ -56,7 +57,7 @@ const Type& TypeFactory::GetType(const TypeID id,
       << "Provided a length parameter to TypeFactory::GetType() for "
       << "a type which does not take one.";
 
-  return *InvokeOnTypeID<TypeIDSelectorParameterized>(
+  return *InvokeOnTypeID<TypeIDSelectorMemoryLayout<kParInlinePod, kParOutOfLinePod>>(
       id,
       [&](auto id) -> const Type* {  // NOLINT(build/c++11)
     return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, length);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/TypeID.cpp
----------------------------------------------------------------------
diff --git a/types/TypeID.cpp b/types/TypeID.cpp
index afc9c2b..ce29455 100644
--- a/types/TypeID.cpp
+++ b/types/TypeID.cpp
@@ -33,6 +33,8 @@ const char *kTypeNames[] = {
   "Datetime",
   "DatetimeInterval",
   "YearMonthInterval",
+  "Array",
+  "MetaType",
   "NullType"
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/TypeID.hpp
----------------------------------------------------------------------
diff --git a/types/TypeID.hpp b/types/TypeID.hpp
index ecbdc9b..8203253 100644
--- a/types/TypeID.hpp
+++ b/types/TypeID.hpp
@@ -29,11 +29,20 @@
 namespace quickstep {
 
 /**
+ * @brief Categories of intermediate supertypes.
+ **/
+enum class SuperTypeID {
+  kNumeric = 0,  // Fixed-length numeric types (Int, Long, Float, Double)
+  kAsciiString,  // ASCII strings (Char, VarChar)
+  kOther         // Others (Date, Datetime, DatetimeInterval, YearMonthInterval)
+};
+
+/**
  * @brief Concrete Types.
  *
  * @note TypedValue assumes that this doesn't exceed 64 TypeIDs.
  **/
-enum TypeID : int {
+enum TypeID {
   kBool = 0,
   kInt,
   kLong,
@@ -45,15 +54,17 @@ enum TypeID : int {
   kDatetime,
   kDatetimeInterval,
   kYearMonthInterval,
+  kArray,
+  kMetaType,
   kNullType,
   kNumTypeIDs  // Not a real TypeID, exists for counting purposes.
 };
 
 enum MemoryLayout {
-  kCxxNativePod,
-  kParNativePod,
-  kParIndirectPod,
-  kGeneric
+  kCxxInlinePod,
+  kParInlinePod,
+  kParOutOfLinePod,
+  kCxxGeneric
 };
 
 /**
@@ -99,4 +110,15 @@ class TypeIDFactory {
 
 }  // namespace quickstep
 
+namespace std {
+
+template <>
+struct hash<quickstep::TypeID> {
+  size_t operator()(const quickstep::TypeID &arg) const {
+    return static_cast<typename std::underlying_type<quickstep::TypeID>::type>(arg);
+  }
+};
+
+}  // namespace std
+
 #endif  // QUICKSTEP_TYPES_TYPE_ID_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d6a51acf/types/TypeIDSelectors.hpp
----------------------------------------------------------------------
diff --git a/types/TypeIDSelectors.hpp b/types/TypeIDSelectors.hpp
index d75a887..6e4a2b0 100644
--- a/types/TypeIDSelectors.hpp
+++ b/types/TypeIDSelectors.hpp
@@ -23,6 +23,7 @@
 #include <type_traits>
 
 #include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
 #include "utility/meta/Common.hpp"
 
 #include "glog/logging.h"
@@ -42,7 +43,7 @@ struct TypeIDSelectorParameterized;
 struct TypeIDSelectorNonParameterized;
 
 template <TypeID ...candidates>
-struct TypeIDSelectorEqualsAny;
+struct TypeIDSelector;
 
 
 // Forward declaration
@@ -76,14 +77,14 @@ template <typename TypeIDConstant, typename FunctorT>
 struct TypeIDSelectorNumeric::Implementation<
     TypeIDConstant, FunctorT,
     std::enable_if_t<TypeIDTrait<TypeIDConstant::value>
-                         ::kStaticSuperTypeID == Type::kNumeric>> {
+                         ::kStaticSuperTypeID == SuperTypeID::kNumeric>> {
   inline static auto Invoke(const FunctorT &functor) {
     return functor(TypeIDConstant());
   }
 };
 
 template <TypeID ...candidates>
-struct TypeIDSelectorEqualsAny {
+struct TypeIDSelector {
   template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
   struct Implementation {
 #pragma GCC diagnostic push
@@ -99,7 +100,7 @@ struct TypeIDSelectorEqualsAny {
 
 template <TypeID ...candidates>
 template <typename TypeIDConstant, typename FunctorT>
-struct TypeIDSelectorEqualsAny<candidates...>::Implementation<
+struct TypeIDSelector<candidates...>::Implementation<
     TypeIDConstant, FunctorT,
     std::enable_if_t<
         meta::EqualsAny<TypeIDConstant,
@@ -109,10 +110,8 @@ struct TypeIDSelectorEqualsAny<candidates...>::Implementation<
   }
 };
 
-namespace internal {
-
-template <bool require_parameterized>
-struct TypeIDSelectorParameterizedHelper {
+template <MemoryLayout ...candidates>
+struct TypeIDSelectorMemoryLayout {
   template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
   struct Implementation {
 #pragma GCC diagnostic push
@@ -126,24 +125,49 @@ struct TypeIDSelectorParameterizedHelper {
   };
 };
 
-template <bool require_non_parameterized>
+template <MemoryLayout ...candidates>
 template <typename TypeIDConstant, typename FunctorT>
-struct TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementation<
+struct TypeIDSelectorMemoryLayout<candidates...>::Implementation<
     TypeIDConstant, FunctorT,
-    std::enable_if_t<TypeIDTrait<TypeIDConstant::value>::kParameterized
-                         ^ require_non_parameterized>> {
+    std::enable_if_t<
+        meta::EqualsAny<
+            std::integral_constant<MemoryLayout,
+                                   TypeIDTrait<TypeIDConstant::value>::kMemoryLayout>,
+            std::integral_constant<MemoryLayout, candidates>...>::value>> {
   inline static auto Invoke(const FunctorT &functor) {
     return functor(TypeIDConstant());
   }
 };
 
-}  // namespace internal
-
-struct TypeIDSelectorNonParameterized
-    : internal::TypeIDSelectorParameterizedHelper<true> {};
-
-struct TypeIDSelectorParameterized
-    : internal::TypeIDSelectorParameterizedHelper<false> {};
+//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>::kIsParPod
+//                         ^ require_non_parameterized>> {
+//  inline static auto Invoke(const FunctorT &functor) {
+//    return functor(TypeIDConstant());
+//  }
+//};
+//
+//}  // namespace internal
 
 /** @} */
 



[26/38] incubator-quickstep git commit: Add array expression

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/preprocessed/SqlLexer_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.cpp b/parser/preprocessed/SqlLexer_gen.cpp
index 0904d7c..05d2d3c 100644
--- a/parser/preprocessed/SqlLexer_gen.cpp
+++ b/parser/preprocessed/SqlLexer_gen.cpp
@@ -592,8 +592,8 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 166
-#define YY_END_OF_BUFFER 167
+#define YY_NUM_RULES 168
+#define YY_END_OF_BUFFER 169
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -601,73 +601,73 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_accept[592] =
+static const flex_int16_t yy_accept[594] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  167,    2,    2,  165,  165,  164,  163,  165,
-      142,  138,  141,  138,  138,  161,  165,  133,  130,  134,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  139,    4,    5,    5,    3,
-      157,  157,  154,  158,  158,  152,  159,  159,  156,    1,
-      164,  131,  162,  161,  161,  161,    0,  137,  135,  132,
-      136,  160,  160,  160,  160,   10,  160,  160,  160,   23,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
-
-      160,  140,  160,  160,  160,  160,  160,  160,  160,  160,
-      160,  160,  160,  160,   59,   68,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  160,   82,   83,  160,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  114,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,    4,    5,    3,  157,
-      153,  158,  151,  151,  143,  145,  146,  147,  148,  149,
-      150,  151,  159,  155,  162,  161,    0,  161,    6,    7,
-      160,    9,   11,  160,  160,   15,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  160,   34,  160,  160,
-
-      160,  160,  160,  160,  160,  160,   44,  160,  160,  160,
-      160,  160,  160,   51,  160,  160,  160,  160,  160,  160,
-      160,  160,  160,   63,  160,   70,  160,  160,  160,  160,
-      160,  160,  160,   78,  160,   81,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,   99,
-      160,  160,  104,  105,  160,  160,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
-      160,  143,  145,  144,  160,  160,  160,  160,  160,  160,
-      160,   20,   21,   24,  160,  160,  160,   29,  160,  160,
-      160,   32,  160,  160,  160,   38,  160,  160,   42,   43,
-
-      160,  160,  160,  160,  160,  160,  160,   53,   54,  160,
-       56,  160,   58,  160,  160,  160,  160,   67,   69,   71,
-       72,   73,  160,   75,  160,  160,   79,  160,  160,   86,
-      160,  160,  160,  160,  160,   93,  160,   95,  160,  160,
-      160,  101,  160,  160,  160,  160,  160,  160,  160,  160,
-      111,  112,  115,  160,  160,  160,  160,  160,  160,  160,
-      160,  124,  160,  160,  127,  128,  143,  144,    8,  160,
-      160,  160,  160,  160,  160,  160,   26,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
-      160,   47,   48,   49,  160,  160,   55,  160,   60,   61,
-
-      160,  160,  160,   74,  160,   77,   80,   84,   85,  160,
-      160,  160,  160,  160,   94,  160,  160,   98,  160,  160,
-      160,  160,  160,  160,  160,  110,  160,  160,  160,  118,
-      160,  160,  121,  160,  160,  125,  160,  160,  160,  160,
-       14,  160,  160,  160,  160,  160,   27,  160,   30,  160,
-      160,  160,  160,  160,   37,  160,  160,   41,   45,  160,
-      160,  160,   57,   62,  160,  160,  160,   76,  160,  160,
-      160,  160,  160,  160,   97,  160,  102,  103,  160,  107,
-      108,  160,  160,  160,  160,  119,  120,  122,  160,  126,
-      160,  160,   13,  160,  160,  160,  160,  160,  160,   22,
-
-       31,  160,   35,   36,  160,  160,   46,  160,   52,   64,
-      160,  160,  160,   89,  160,   91,  160,  160,  160,  160,
-      160,  160,  160,  160,  123,  160,  160,  160,  160,  160,
-      160,  160,  160,   33,  160,   40,  160,  160,   66,  160,
-      160,   92,  160,  160,  106,  160,  160,  160,  160,  160,
-       12,  160,  160,  160,  160,   25,  160,  160,   50,   65,
-       87,   90,  160,  160,  109,  113,  160,  117,  129,   16,
-      160,  160,  160,   28,   39,   88,   96,  160,  160,  160,
-       18,   19,  160,  116,  160,  160,  160,  100,  160,   17,
-        0
+        0,    0,  169,    2,    2,  167,  167,  166,  165,  167,
+      144,  140,  143,  140,  140,  163,  167,  133,  130,  134,
+      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
+      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
+      162,  162,  162,  162,  162,  141,  138,  139,    4,    5,
+        5,    3,  159,  159,  156,  160,  160,  154,  161,  161,
+      158,    1,  166,  131,  164,  163,  163,  163,    0,  137,
+      135,  132,  136,  162,  162,  162,  162,   10,  162,  162,
+      162,   23,  162,  162,  162,  162,  162,  162,  162,  162,
+
+      162,  162,  162,  142,  162,  162,  162,  162,  162,  162,
+      162,  162,  162,  162,  162,  162,   59,   68,  162,  162,
+      162,  162,  162,  162,  162,  162,  162,  162,  162,   82,
+       83,  162,  162,  162,  162,  162,  162,  162,  162,  162,
+      162,  162,  162,  162,  162,  162,  162,  162,  114,  162,
+      162,  162,  162,  162,  162,  162,  162,  162,    4,    5,
+        3,  159,  155,  160,  153,  153,  145,  147,  148,  149,
+      150,  151,  152,  153,  161,  157,  164,  163,    0,  163,
+        6,    7,  162,    9,   11,  162,  162,   15,  162,  162,
+      162,  162,  162,  162,  162,  162,  162,  162,  162,   34,
+
+      162,  162,  162,  162,  162,  162,  162,  162,   44,  162,
+      162,  162,  162,  162,  162,   51,  162,  162,  162,  162,
+      162,  162,  162,  162,  162,   63,  162,   70,  162,  162,
+      162,  162,  162,  162,  162,   78,  162,   81,  162,  162,
+      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
+      162,   99,  162,  162,  104,  105,  162,  162,  162,  162,
+      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
+      162,  162,  162,  145,  147,  146,  162,  162,  162,  162,
+      162,  162,  162,   20,   21,   24,  162,  162,  162,   29,
+      162,  162,  162,   32,  162,  162,  162,   38,  162,  162,
+
+       42,   43,  162,  162,  162,  162,  162,  162,  162,   53,
+       54,  162,   56,  162,   58,  162,  162,  162,  162,   67,
+       69,   71,   72,   73,  162,   75,  162,  162,   79,  162,
+      162,   86,  162,  162,  162,  162,  162,   93,  162,   95,
+      162,  162,  162,  101,  162,  162,  162,  162,  162,  162,
+      162,  162,  111,  112,  115,  162,  162,  162,  162,  162,
+      162,  162,  162,  124,  162,  162,  127,  128,  145,  146,
+        8,  162,  162,  162,  162,  162,  162,  162,   26,  162,
+      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
+      162,  162,  162,   47,   48,   49,  162,  162,   55,  162,
+
+       60,   61,  162,  162,  162,   74,  162,   77,   80,   84,
+       85,  162,  162,  162,  162,  162,   94,  162,  162,   98,
+      162,  162,  162,  162,  162,  162,  162,  110,  162,  162,
+      162,  118,  162,  162,  121,  162,  162,  125,  162,  162,
+      162,  162,   14,  162,  162,  162,  162,  162,   27,  162,
+       30,  162,  162,  162,  162,  162,   37,  162,  162,   41,
+       45,  162,  162,  162,   57,   62,  162,  162,  162,   76,
+      162,  162,  162,  162,  162,  162,   97,  162,  102,  103,
+      162,  107,  108,  162,  162,  162,  162,  119,  120,  122,
+      162,  126,  162,  162,   13,  162,  162,  162,  162,  162,
+
+      162,   22,   31,  162,   35,   36,  162,  162,   46,  162,
+       52,   64,  162,  162,  162,   89,  162,   91,  162,  162,
+      162,  162,  162,  162,  162,  162,  123,  162,  162,  162,
+      162,  162,  162,  162,  162,   33,  162,   40,  162,  162,
+       66,  162,  162,   92,  162,  162,  106,  162,  162,  162,
+      162,  162,   12,  162,  162,  162,  162,   25,  162,  162,
+       50,   65,   87,   90,  162,  162,  109,  113,  162,  117,
+      129,   16,  162,  162,  162,   28,   39,   88,   96,  162,
+      162,  162,   18,   19,  162,  116,  162,  162,  162,  100,
+      162,   17,    0
 
     } ;
 
@@ -686,7 +686,7 @@ static const YY_CHAR yy_ec[256] =
 
        51,   52,   53,   54,   55,   56,   57,   58,   59,   60,
        61,   62,   63,   64,   65,   66,   67,   68,   69,   70,
-       71,   43,    1,    1,    1,    1,    1,    1,    1,    1,
+       71,   43,   72,    1,   73,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -703,7 +703,7 @@ static const YY_CHAR yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static const YY_CHAR yy_meta[72] =
+static const YY_CHAR yy_meta[74] =
     {   0,
         1,    1,    2,    1,    1,    3,    1,    4,    1,    5,
         5,    6,    6,    5,    1,    1,    1,    7,    7,    7,
@@ -712,158 +712,158 @@ static const YY_CHAR yy_meta[72] =
         8,    8,    8,    1,    9,   10,    7,    7,    7,    7,
         7,    7,    8,    8,    8,    8,    8,    8,    8,    8,
         8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
-        8
+        8,    1,    1
     } ;
 
-static const flex_int16_t yy_base[607] =
+static const flex_int16_t yy_base[609] =
     {   0,
-        0,    1,   46,    0,  117,  162,    2,    3,  127,  128,
-        6,   10,  148, 1317, 1317,    0, 1317,   13, 1317,  131,
-     1317, 1317, 1317,  136,    6,  129,  125,    4, 1317,   28,
-      124,  159,  213,  165,  167,  263,   92,  158,  163,   96,
-      107,  214,  160,  186,  219,  221,  155,  281,  274,  325,
-      257,  186,  209,    0,  219, 1317,   27,    4,   19,    0,
-        0,    0,   17,    0,    0,  389,    0,    0,    8,    0,
-       22, 1317,    0,  293,  325,  343,   18, 1317, 1317, 1317,
-     1317,    0,  223,  265,  234,  242,  260,  292,  288,    0,
-      299,  330,  337,  324,  334,  324,  325,  380,  325,  331,
-
-      346, 1317,  348,  364,  378,  376,  371,  378,  382,  386,
-      390,  389,  386,  385,  435,    0,  402,  389,  400,  435,
-      433,  431,  433,  436,  431,  440,  447,    0,  452,  437,
-      453,  441,  442,  456,  453,  449,  465,  457,  444,  494,
-      468,  495,  500,  501,  499,  492,    0,  486,  492,  507,
-      506,  502,  500,  508,  501,  516,    0,   29,    0,    0,
-     1317,    0, 1317, 1317,   22,   24, 1317, 1317, 1317, 1317,
-     1317,    0,    0, 1317,    0,  524,   26,   28,    0,    0,
-      517,    0,  518,  501,  516,  504,  545,  544,  512,  552,
-      536,  542,  537,  562,  545,  548,  562,    0,  559,  568,
-
-      565,  568,  552,  571,  558,  570,    0,  557,  561,  561,
-      562,  581,  571,  580,  574,  576,  585,  599,  604,  597,
-      613,  614,  615,  616,  608,    0,  603,  604,  620,  617,
-      620,  607,  609,    0,  618,    0,  627,  628,  616,  617,
-      635,  636,  628,  620,  638,  634,  659,  660,  663,  654,
-      661,  672,    0,  666,  674,  661,  669,  668,  679,  680,
-      674,  672,  673,  690,  678,  674,  693,  683,  694,  691,
-      685,   30,  125,    0,  686,  698,  717,  709,  724,  720,
-      721,    0,    0,  734,  725,  724,  718,    0,  719,  722,
-      737,  723,  731,  724,  726,  742,  739,  737,    0,    0,
-
-      730,  752,  749,  735,  736,  742,  750,    0,    0,  745,
-        0,  748,    0,  746,  762,  763,  780,    0,    0,    0,
-        0,    0,  769,    0,  772,  785,  775,  777,  778,    0,
-      788,  795,  796,  801,  785,    0,  799,    0,  787,  782,
-      787,    0,  804,  797,  809,  801,  796,  794,  797,  814,
-        0,  801,    0,  823,  817,  825,  824,  827,  843,  846,
-      844,    0,  848,  839,    0,  842,  131, 1317,    0,  852,
-      853,  839,  859,  845,  856,  860,    0,  851,  848,  864,
-      865,  857,  863,  872,  863,  872,  864,  872,  891,  878,
-      900,    0,    0,    0,  882,  901,    0,  902,    0,    0,
-
-      890,  906,  894,    0,  907,    0,    0,    0,    0,  894,
-      903,  914,  901,  911,    0,  916,  906,    0,  918,  920,
-      907,  919,  911,  910,  913,    0,  913,  916,  922,    0,
-      939,  949,    0,  936,  960,    0,  940,  951,  958,  954,
-        0,  947,  952,  970,  963,  954,    0,  974,    0,  971,
-      957,  965,  967,  960,    0,  977,  979,    0,    0,  965,
-      977,  973,    0,    0,  970,  984,  990,    0,  984,  974,
-      993,  987,  993, 1005,    0, 1009,    0,    0, 1010,    0,
-        0, 1016, 1025, 1026, 1024,    0,    0,    0, 1011,    0,
-     1016, 1018,    0, 1024, 1019, 1022, 1024, 1032, 1029,    0,
-
-        0, 1034,    0,    0, 1031, 1023,    0, 1030,    0,    0,
-     1042, 1034, 1032,    0, 1035,    0, 1026, 1049, 1051, 1050,
-     1057, 1064, 1066, 1077,    0, 1063, 1077, 1071, 1070, 1071,
-     1068, 1072, 1077,    0, 1078,    0, 1086, 1074,    0, 1081,
-     1089,    0, 1092, 1085,    0, 1094, 1086, 1087, 1100, 1097,
-        0, 1100, 1104, 1098, 1113,    0, 1108, 1122,    0,    0,
-     1116,    0, 1118, 1131,    0,    0, 1129,    0,    0,    0,
-     1124, 1138, 1126,    0,    0,    0,    0, 1125, 1141, 1128,
-        0,    0, 1144,    0, 1141, 1133, 1147,    0, 1134,    0,
-     1317, 1199, 1209, 1219, 1229, 1239, 1243, 1246, 1252, 1262,
-
-     1272, 1282, 1292, 1302, 1307, 1309
+        0,    1,   46,    0,  119,  192,    2,    3,  129,  130,
+        6,   10,  231, 1299, 1299,    0, 1299,   13, 1299,  151,
+     1299, 1299, 1299,  152,    6,  118,  132,    4, 1299,   28,
+      118,  131,  248,  188,  197,  298,  106,  124,  112,  118,
+      129,  193,  126,  123,  237,  194,  121,  195,  240,  348,
+      238,  185,  256,    0,  182, 1299, 1299, 1299,   27,    4,
+       19,    0,    0,    0,   17,    0,    0,  412,    0,    0,
+        8,    0,   22, 1299,    0,  306,  309,  326,   18, 1299,
+     1299, 1299, 1299,    0,  197,  193,  203,  214,  224,  305,
+      247,    0,  249,  325,  359,  266,  275,  261,  298,  355,
+
+      284,  288,  300, 1299,  298,  320,  342,  323,  332,  350,
+      364,  353,  360,  362,  362,  362,  405,    0,  379,  368,
+      396,  410,  410,  406,  413,  414,  409,  419,  427,    0,
+      430,  415,  432,  421,  422,  437,  432,  437,  466,  467,
+      453,  474,  477,  475,  479,  480,  478,  471,    0,  464,
+      471,  486,  485,  481,  479,  487,  479,  497,    0,   29,
+        0,    0, 1299,    0, 1299, 1299,   22,   24, 1299, 1299,
+     1299, 1299, 1299,    0,    0, 1299,    0,  534,   26,   28,
+        0,    0,  499,    0,  504,  502,  522,  509,  531,  530,
+      518,  534,  519,  522,  517,  542,  524,  527,  542,    0,
+
+      539,  548,  546,  549,  533,  553,  540,  552,    0,  539,
+      541,  543,  548,  582,  577,  585,  579,  581,  573,  587,
+      588,  580,  594,  595,  596,  598,  588,    0,  584,  585,
+      601,  598,  601,  588,  590,    0,  599,    0,  609,  610,
+      598,  597,  617,  622,  635,  621,  640,  639,  647,  648,
+      647,  637,  642,  653,    0,  647,  656,  641,  650,  649,
+      659,  660,  655,  653,  657,  668,  659,  654,  675,  681,
+      679,  697,  688,   30,  132,    0,  690,  695,  705,  697,
+      708,  703,  702,    0,    0,  715,  706,  705,  699,    0,
+      700,  703,  717,  703,  712,  705,  707,  724,  721,  719,
+
+        0,    0,  712,  732,  731,  721,  733,  742,  754,    0,
+        0,  748,    0,  752,    0,  743,  750,  751,  765,    0,
+        0,    0,    0,    0,  751,    0,  753,  766,  756,  758,
+      759,    0,  769,  774,  775,  780,  766,    0,  780,    0,
+      769,  764,  769,    0,  786,  777,  791,  787,  793,  794,
+      801,  817,    0,  805,    0,  820,  805,  813,  808,  810,
+      824,  827,  825,    0,  829,  820,    0,  823,  153, 1299,
+        0,  833,  833,  819,  840,  826,  837,  843,    0,  833,
+      830,  844,  847,  843,  860,  872,  867,  875,  868,  869,
+      879,  866,  884,    0,    0,    0,  865,  882,    0,  883,
+
+        0,    0,  871,  887,  874,    0,  889,    0,    0,    0,
+        0,  875,  883,  895,  882,  892,    0,  898,  888,    0,
+      900,  902,  887,  901,  897,  907,  913,    0,  917,  919,
+      926,    0,  936,  937,    0,  924,  944,    0,  923,  932,
+      939,  935,    0,  928,  933,  951,  944,  934,    0,  954,
+        0,  952,  938,  946,  949,  942,    0,  959,  961,    0,
+        0,  945,  959,  959,    0,    0,  967,  984,  994,    0,
+      987,  978,  990,  975,  981,  989,    0,  992,    0,    0,
+      991,    0,    0,  997, 1006, 1007, 1005,    0,    0,    0,
+      992,    0,  997,  998,    0, 1004, 1000, 1003, 1005, 1014,
+
+     1011,    0,    0, 1016,    0,    0, 1013, 1003,    0, 1012,
+        0,    0, 1028, 1031, 1032,    0, 1039,    0, 1029, 1053,
+     1048, 1038, 1045, 1048, 1049, 1058,    0, 1044, 1058, 1052,
+     1051, 1052, 1049, 1052, 1057,    0, 1059,    0, 1067, 1055,
+        0, 1063, 1071,    0, 1074, 1067,    0, 1074, 1068, 1073,
+     1097, 1097,    0, 1104, 1107, 1102, 1110,    0, 1096, 1110,
+        0,    0, 1100,    0, 1101, 1112,    0,    0, 1110,    0,
+        0,    0, 1105, 1119, 1107,    0,    0,    0,    0, 1106,
+     1122, 1108,    0,    0, 1124,    0, 1122, 1114, 1128,    0,
+     1116,    0, 1299, 1181, 1191, 1201, 1211, 1221, 1225, 1228,
+
+     1234, 1244, 1254, 1264, 1274, 1284, 1289, 1291
     } ;
 
-static const flex_int16_t yy_def[607] =
+static const flex_int16_t yy_def[609] =
     {   0,
-      592,  592,  591,    3,  593,  593,  594,  594,  595,  595,
-      596,  596,  591,  591,  591,  597,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  591,  591,  591,  591,  599,
-      600,  600,  591,  601,  601,  602,  603,  603,  591,  597,
-      591,  591,  604,  591,  591,  591,  591,  591,  591,  591,
-      591,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-
-      598,  591,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  591,  591,  599,  600,
-      591,  601,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  605,  603,  591,  604,  591,  591,  591,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  591,  591,  606,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  591,  591,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-      598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
-        0,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-
-      591,  591,  591,  591,  591,  591
+      594,  594,  593,    3,  595,  595,  596,  596,  597,  597,
+      598,  598,  593,  593,  593,  599,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  593,  593,  593,  593,  593,
+      593,  601,  602,  602,  593,  603,  603,  604,  605,  605,
+      593,  599,  593,  593,  606,  593,  593,  593,  593,  593,
+      593,  593,  593,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+
+      600,  600,  600,  593,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  593,  593,
+      601,  602,  593,  603,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  607,  605,  593,  606,  593,  593,  593,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  593,  593,  608,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  593,  593,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  600,  600,  600,
+      600,  600,    0,  593,  593,  593,  593,  593,  593,  593,
+
+      593,  593,  593,  593,  593,  593,  593,  593
     } ;
 
-static const flex_int16_t yy_nxt[1389] =
+static const flex_int16_t yy_nxt[1373] =
     {   0,
-      591,  157,   15,   15,   62,   62,  158,  158,   68,   63,
-       63,   69,   68,  174,   71,   69,   71,   74,   74,   79,
-       80,  158,  158,   71,  161,   71,  177,  177,  157,  178,
-      178,  158,  158,  272,  273,  273,  273,  178,  178,  178,
-      178,  367,  273,   81,   16,   16,   17,   18,   19,   18,
+      593,  159,   15,   15,   64,   64,  160,  160,   70,   65,
+       65,   71,   70,  176,   73,   71,   73,   76,   76,   81,
+       82,  160,  160,   73,  163,   73,  179,  179,  159,  180,
+      180,  160,  160,  274,  275,  275,  275,  180,  180,  180,
+      180,  369,  275,   83,   16,   16,   17,   18,   19,   18,
        20,   21,   22,   23,   22,   24,   25,   26,   26,   27,
        28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
        38,   39,   40,   41,   42,   43,   44,   45,   46,   47,
@@ -871,155 +871,154 @@ static const flex_int16_t yy_nxt[1389] =
        17,   17,   31,   32,   33,   34,   35,   36,   37,   38,
 
        39,   40,   41,   42,   43,   44,   45,   46,   47,   48,
-       49,   50,   51,   52,   53,   54,   55,   17,   57,   58,
-       59,   17,   17,   17,   17,   17,  112,  117,  118,   65,
-       65,   17,   17,   17,   63,   63,  273,  273,   78,   75,
-       76,   76,  273,  273,   83,   73,   72,  591,  591,  591,
-       77,  591,   84,  591,   85,  112,  117,  118,  591,   86,
-       17,   17,   17,   57,   58,   59,   17,   17,   17,   17,
-       17,   66,   66,   83,  102,  113,   17,   17,   17,   77,
-       87,   84,   97,   85,   88,  123,   98,   89,   86,  114,
-       99,  124,  135,  115,  591,  103,  100,  104,  116,  101,
-
-       90,  591,  591,  153,  113,   17,   17,  105,  591,   87,
-      591,   97,  591,   88,  123,   98,   89,  125,  114,   99,
-      124,  135,  115,  126,  103,  100,  104,  116,  101,   90,
-       91,  119,  153,  154,  155,  120,  105,   92,  132,  121,
-      156,  127,  133,  179,   93,  122,  125,   94,   95,  128,
-       96,  591,  126,  129,  182,  134,  130,  131,  591,   91,
-      119,  183,  154,  155,  120,  591,   92,  132,  121,  156,
-      127,  133,  179,   93,  122,  591,   94,   95,  128,   96,
-      106,  591,  129,  182,  134,  130,  131,  150,  107,  151,
-      183,  108,  152,  180,  109,  140,  184,  110,  136,  591,
-
-      111,  181,  137,  141,   74,   74,  138,  591,  591,  106,
-      142,  143,  139,  591,   77,  185,  150,  107,  151,  187,
-      108,  152,  180,  109,  140,  184,  110,  136,  186,  111,
-      181,  137,  141,  591,  188,  138,  176,  176,  591,  142,
-      143,  139,  144,   77,  185,  194,   77,  189,  187,  145,
-      146,  190,  195,   75,   76,   76,  147,  186,  196,  148,
-      203,  197,  149,  188,   77,  191,  198,  192,  204,  193,
-      591,  144,  591,  591,  194,   77,  189,  205,  145,  146,
-      190,  195,  591,  206,  207,  147,  591,  196,  148,  203,
-      197,  149,  164,   77,  191,  198,  192,  204,  193,  199,
-
-      165,  166,  200,  208,  210,  211,  205,  167,  201,  212,
-      213,  168,  206,  207,  209,  202,  214,  215,  216,  169,
-      217,  218,  220,  170,  219,  171,  591,  225,  199,  172,
-      226,  200,  208,  210,  211,  227,  167,  201,  212,  213,
-      168,  591,  591,  209,  202,  214,  215,  216,  169,  217,
-      218,  220,  170,  219,  171,  221,  225,  228,  172,  226,
-      229,  231,  230,  232,  227,  222,  233,  234,  235,  236,
-      223,  224,  237,  238,  239,  240,  241,  242,  244,  245,
-      249,  243,  246,  250,  221,  254,  228,  247,  248,  229,
-      231,  230,  232,  591,  222,  233,  234,  235,  236,  223,
-
-      224,  237,  238,  239,  240,  241,  242,  244,  245,  249,
-      243,  246,  250,  251,  254,  255,  247,  248,  256,  257,
-      258,  259,  252,  260,  261,  262,  264,  265,  266,  268,
-      253,  269,  263,  271,  267,  176,  176,  270,  275,  276,
-      277,  278,  251,  279,  255,   77,  284,  256,  257,  258,
-      259,  252,  260,  261,  262,  264,  265,  266,  268,  253,
-      269,  263,  271,  267,  280,  282,  270,  275,  276,  277,
-      278,  285,  279,  286,   77,  284,  281,  287,  288,  289,
-      283,  290,  291,  292,  293,  294,  295,  296,  297,  298,
-      299,  300,  301,  280,  282,  302,  303,  304,  305,  306,
-
-      285,  307,  286,  308,  309,  281,  287,  288,  289,  283,
-      290,  291,  292,  293,  294,  295,  296,  297,  298,  299,
-      300,  301,  310,  311,  302,  303,  304,  305,  306,  312,
-      307,  313,  308,  309,  314,  315,  316,  317,  319,  320,
-      321,  322,  323,  324,  325,  326,  327,  318,  328,  329,
-      330,  310,  311,  331,  332,  333,  336,  334,  312,  335,
-      313,  337,  338,  314,  315,  316,  317,  319,  320,  321,
-      322,  323,  324,  325,  326,  327,  318,  328,  329,  330,
-      339,  340,  331,  332,  333,  336,  334,  341,  335,  342,
-      337,  338,  344,  345,  346,  347,  349,  350,  351,  343,
-
-      352,  353,  354,  355,  356,  348,  357,  358,  359,  339,
-      340,  360,  361,  362,  364,  365,  341,  363,  342,  366,
-      369,  344,  345,  346,  347,  349,  350,  351,  370,  352,
-      353,  354,  355,  356,  348,  357,  358,  359,  371,  372,
-      360,  361,  362,  364,  365,  373,  363,  374,  366,  369,
-      375,  376,  377,  378,  379,  380,  381,  370,  382,  383,
-      384,  385,  386,  387,  388,  389,  390,  371,  372,  391,
-      392,  393,  394,  395,  373,  396,  374,  397,  398,  375,
-      376,  377,  378,  379,  380,  381,  399,  382,  383,  384,
-      385,  386,  387,  388,  389,  390,  400,  401,  391,  392,
-
-      393,  394,  395,  402,  396,  404,  397,  398,  405,  406,
-      407,  408,  409,  410,  403,  399,  411,  412,  413,  414,
-      415,  416,  417,  418,  419,  400,  401,  420,  421,  422,
-      423,  424,  402,  425,  404,  426,  427,  405,  406,  407,
-      408,  409,  410,  403,  428,  411,  412,  413,  414,  415,
-      416,  417,  418,  419,  429,  430,  420,  421,  422,  423,
-      424,  431,  425,  432,  426,  427,  433,  434,  435,  436,
-      437,  438,  439,  428,  440,  441,  442,  443,  445,  446,
-      444,  447,  448,  429,  430,  449,  450,  451,  452,  453,
-      431,  454,  432,  455,  456,  433,  434,  435,  436,  437,
-
-      438,  439,  457,  440,  441,  442,  443,  445,  446,  444,
-      447,  448,  458,  459,  449,  450,  451,  452,  453,  460,
-      454,  461,  455,  456,  462,  463,  464,  465,  468,  466,
-      469,  457,  467,  470,  471,  472,  473,  474,  475,  476,
-      477,  458,  459,  478,  479,  480,  481,  482,  460,  483,
-      461,  484,  485,  462,  463,  464,  465,  468,  466,  469,
-      486,  467,  470,  471,  472,  473,  474,  475,  476,  477,
-      487,  488,  478,  479,  480,  481,  482,  489,  483,  490,
-      484,  485,  491,  492,  493,  494,  495,  496,  497,  486,
-      498,  499,  500,  501,  502,  503,  504,  505,  506,  487,
-
-      488,  507,  508,  509,  510,  511,  489,  512,  490,  513,
-      514,  491,  492,  493,  494,  495,  496,  497,  515,  498,
-      499,  500,  501,  502,  503,  504,  505,  506,  516,  517,
-      507,  508,  509,  510,  511,  518,  512,  519,  513,  514,
-      520,  521,  522,  523,  524,  525,  526,  515,  527,  528,
-      529,  530,  531,  532,  533,  534,  535,  516,  517,  536,
-      537,  538,  539,  540,  518,  541,  519,  542,  543,  520,
-      521,  522,  523,  524,  525,  526,  544,  527,  528,  529,
-      530,  531,  532,  533,  534,  535,  545,  546,  536,  537,
-      538,  539,  540,  547,  541,  548,  542,  543,  549,  550,
-
-      551,  552,  553,  554,  555,  544,  556,  557,  558,  559,
-      560,  561,  562,  563,  564,  545,  546,  565,  566,  567,
-      568,  569,  547,  570,  548,  571,  572,  549,  550,  551,
-      552,  553,  554,  555,  573,  556,  557,  558,  559,  560,
-      561,  562,  563,  564,  574,  575,  565,  566,  567,  568,
-      569,  576,  570,  577,  571,  572,  578,  579,  580,  581,
-      582,  583,  584,  573,  585,  586,  587,  588,  589,  590,
-      591,  591,  591,  574,  575,  591,  591,  591,  591,  591,
-      576,  591,  577,  591,  591,  578,  579,  580,  581,  582,
-      583,  584,  591,  585,  586,  587,  588,  589,  590,   14,
-
-       14,   14,   14,   14,   14,   14,   14,   14,   14,   60,
-       60,   60,   60,   60,   60,   60,   60,   60,   60,   61,
-       61,   61,   61,   61,   61,   61,   61,   61,   61,   64,
-       64,   64,   64,   64,   64,   64,   64,   64,   64,   67,
-       67,   67,   67,   67,   67,   67,   67,   67,   67,   70,
-       70,   82,   82,   82,  591,   82,  159,  159,  159,  159,
-      591,  159,  160,  160,  160,  591,  160,  160,  160,  160,
-      160,  160,  162,  162,  162,  591,  162,  162,  162,  162,
-      591,  162,  163,  163,  163,  163,  163,  163,  163,  163,
-      163,  163,  173,  173,  591,  173,  173,  173,  173,  173,
-
-      173,  173,  175,  591,  175,  175,  175,  175,  175,  175,
-      175,  175,  274,  274,  368,  368,   13,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591
+       49,   50,   51,   52,   53,   54,   55,   57,   58,   17,
+       59,   60,   61,   17,   17,   17,   17,   17,   77,   78,
+       78,   67,   67,   17,   17,   17,   65,   65,   85,   79,
+      114,  115,  117,  275,  275,   80,   86,  118,   87,  119,
+      120,  125,   89,   88,  127,  116,   90,  126,  137,   91,
+      128,   75,   17,   17,  275,  275,   74,   85,   79,  114,
+      115,  117,   92,   68,   68,   86,  118,   87,  119,  120,
+      125,   89,   88,  127,  116,   90,  126,  137,   91,  128,
+       17,   17,   17,   59,   60,   61,   17,   17,   17,   17,
+
+       17,   92,  155,  158,  104,   99,   17,   17,   17,  100,
+      121,  134,  138,  101,  122,  135,  139,  181,  123,  102,
+      140,  182,  103,  184,  124,  105,  141,  106,  136,  183,
+      593,  155,  158,  185,   99,   17,   17,  107,  100,  121,
+      134,  138,  101,  122,  135,  139,  181,  123,  102,  140,
+      182,  103,  184,  124,  105,  141,  106,  136,  183,  129,
+      186,  142,  185,   17,   17,   93,  107,  130,  152,  143,
+      153,  131,   94,  154,  132,  133,  144,  145,  189,   95,
+      156,  157,   96,   97,  190,   98,  593,  196,  129,  186,
+      142,  593,  593,  197,   93,  198,  130,  152,  143,  153,
+
+      131,   94,  154,  132,  133,  144,  145,  189,   95,  156,
+      157,   96,   97,  190,   98,  108,  196,   76,   76,  205,
+      178,  178,  197,  109,  198,  206,  110,   79,  187,  111,
+       79,  207,  112,  208,  199,  113,   77,   78,   78,  200,
+      209,  188,  191,  593,  108,  593,  192,   79,  205,  593,
+      593,  212,  109,  593,  206,  110,   79,  187,  111,   79,
+      207,  112,  208,  199,  113,  146,  213,  210,  200,  209,
+      188,  191,  147,  148,  201,  192,   79,  202,  211,  149,
+      212,  214,  150,  203,  217,  151,  593,  193,  218,  194,
+      204,  195,  215,  219,  146,  213,  210,  220,  216,  222,
+
+      221,  147,  148,  201,  227,  593,  202,  211,  149,  228,
+      214,  150,  203,  217,  151,  166,  193,  218,  194,  204,
+      195,  215,  219,  167,  168,  223,  220,  216,  222,  221,
+      169,  229,  230,  227,  170,  224,  233,  231,  228,  232,
+      225,  226,  171,  234,  235,  236,  172,  237,  173,  238,
+      239,  240,  174,  241,  223,  242,  243,  246,  244,  169,
+      229,  230,  245,  170,  224,  233,  231,  247,  232,  225,
+      226,  171,  234,  235,  236,  172,  237,  173,  238,  239,
+      240,  174,  241,  248,  242,  243,  246,  244,  249,  250,
+      251,  245,  252,  253,  256,  257,  247,  258,  259,  260,
+
+      261,  262,  254,  263,  264,  266,  267,  268,  270,  271,
+      255,  265,  248,  269,  273,  272,  593,  249,  250,  251,
+      277,  252,  253,  256,  257,  278,  258,  259,  260,  261,
+      262,  254,  263,  264,  266,  267,  268,  270,  271,  255,
+      265,  279,  269,  273,  272,  178,  178,  280,  281,  277,
+      282,  284,  286,  287,  278,   79,  288,  289,  290,  291,
+      292,  293,  283,  294,  295,  296,  285,  297,  298,  299,
+      279,  300,  301,  302,  303,  304,  280,  281,  305,  282,
+      284,  286,  287,  306,   79,  288,  289,  290,  291,  292,
+      293,  283,  294,  295,  296,  285,  297,  298,  299,  307,
+
+      300,  301,  302,  303,  304,  308,  309,  305,  310,  311,
+      312,  313,  306,  314,  315,  316,  317,  318,  321,  319,
+      322,  323,  324,  325,  326,  327,  328,  329,  307,  320,
+      330,  331,  332,  333,  308,  309,  334,  310,  311,  312,
+      313,  335,  314,  315,  316,  317,  318,  321,  319,  322,
+      323,  324,  325,  326,  327,  328,  329,  338,  320,  330,
+      331,  332,  333,  339,  336,  334,  337,  340,  341,  342,
+      335,  343,  344,  346,  347,  348,  351,  349,  352,  353,
+      354,  355,  345,  356,  357,  360,  338,  350,  358,  361,
+      359,  362,  339,  336,  363,  337,  340,  341,  342,  366,
+
+      343,  344,  346,  347,  348,  351,  349,  352,  353,  354,
+      355,  364,  356,  357,  360,  365,  350,  358,  361,  359,
+      362,  367,  368,  363,  371,  372,  373,  374,  366,  375,
+      376,  377,  378,  379,  380,  381,  382,  383,  384,  385,
+      364,  386,  387,  388,  365,  389,  390,  391,  392,  393,
+      367,  368,  394,  371,  372,  373,  374,  395,  375,  376,
+      377,  378,  379,  380,  381,  382,  383,  384,  385,  396,
+      386,  387,  388,  397,  389,  390,  391,  392,  393,  398,
+      399,  394,  400,  401,  402,  403,  395,  406,  404,  407,
+      408,  409,  410,  411,  412,  413,  414,  415,  396,  405,
+
+      416,  417,  397,  418,  419,  420,  421,  422,  398,  399,
+      423,  400,  401,  402,  403,  424,  406,  404,  407,  408,
+      409,  410,  411,  412,  413,  414,  415,  425,  405,  416,
+      417,  426,  418,  419,  420,  421,  422,  427,  428,  423,
+      429,  430,  431,  432,  424,  433,  434,  435,  436,  437,
+      438,  439,  440,  441,  442,  443,  425,  444,  445,  447,
+      426,  446,  448,  449,  450,  451,  427,  428,  452,  429,
+      430,  431,  432,  453,  433,  434,  435,  436,  437,  438,
+      439,  440,  441,  442,  443,  454,  444,  445,  447,  455,
+      446,  448,  449,  450,  451,  456,  457,  452,  458,  459,
+
+      460,  461,  453,  462,  463,  464,  465,  466,  467,  468,
+      470,  471,  469,  472,  454,  473,  474,  475,  455,  476,
+      477,  478,  479,  480,  456,  457,  481,  458,  459,  460,
+      461,  482,  462,  463,  464,  465,  466,  467,  468,  470,
+      471,  469,  472,  483,  473,  474,  475,  484,  476,  477,
+      478,  479,  480,  485,  486,  481,  487,  488,  489,  490,
+      482,  491,  492,  493,  494,  495,  496,  497,  498,  499,
+      500,  501,  483,  502,  503,  504,  484,  505,  506,  507,
+      508,  509,  485,  486,  510,  487,  488,  489,  490,  511,
+      491,  492,  493,  494,  495,  496,  497,  498,  499,  500,
+
+      501,  512,  502,  503,  504,  513,  505,  506,  507,  508,
+      509,  514,  515,  510,  516,  517,  518,  519,  511,  520,
+      521,  522,  523,  524,  525,  526,  527,  528,  529,  530,
+      512,  531,  532,  533,  513,  534,  535,  536,  537,  538,
+      514,  515,  539,  516,  517,  518,  519,  540,  520,  521,
+      522,  523,  524,  525,  526,  527,  528,  529,  530,  541,
+      531,  532,  533,  542,  534,  535,  536,  537,  538,  543,
+      544,  539,  545,  546,  547,  548,  540,  549,  550,  551,
+      552,  553,  554,  555,  556,  557,  558,  559,  541,  560,
+      561,  562,  542,  563,  564,  565,  566,  567,  543,  544,
+
+      568,  545,  546,  547,  548,  569,  549,  550,  551,  552,
+      553,  554,  555,  556,  557,  558,  559,  570,  560,  561,
+      562,  571,  563,  564,  565,  566,  567,  572,  573,  568,
+      574,  575,  576,  577,  569,  578,  579,  580,  581,  582,
+      583,  584,  585,  586,  587,  588,  570,  589,  590,  591,
+      571,  592,  593,  593,  593,  593,  572,  573,  593,  574,
+      575,  576,  577,  593,  578,  579,  580,  581,  582,  583,
+      584,  585,  586,  587,  588,  593,  589,  590,  591,  593,
+      592,   14,   14,   14,   14,   14,   14,   14,   14,   14,
+       14,   62,   62,   62,   62,   62,   62,   62,   62,   62,
+
+       62,   63,   63,   63,   63,   63,   63,   63,   63,   63,
+       63,   66,   66,   66,   66,   66,   66,   66,   66,   66,
+       66,   69,   69,   69,   69,   69,   69,   69,   69,   69,
+       69,   72,   72,   84,   84,   84,  593,   84,  161,  161,
+      161,  161,  593,  161,  162,  162,  162,  593,  162,  162,
+      162,  162,  162,  162,  164,  164,  164,  593,  164,  164,
+      164,  164,  593,  164,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  175,  175,  593,  175,  175,  175,
+      175,  175,  175,  175,  177,  593,  177,  177,  177,  177,
+      177,  177,  177,  177,  276,  276,  370,  370,   13,  593,
+
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593
     } ;
 
-static const flex_int16_t yy_chk[1389] =
+static const flex_int16_t yy_chk[1373] =
     {   0,
-        0,  157,    1,    2,    7,    8,   58,   58,   11,    7,
-        8,   11,   12,   69,   18,   12,   18,   25,   25,   28,
-       28,   59,   59,   71,   63,   71,   77,   77,   57,   77,
-       77,  158,  158,  165,  165,  166,  166,  177,  177,  178,
-      178,  272,  272,   30,    1,    2,    3,    3,    3,    3,
+        0,  159,    1,    2,    7,    8,   60,   60,   11,    7,
+        8,   11,   12,   71,   18,   12,   18,   25,   25,   28,
+       28,   61,   61,   73,   65,   73,   79,   79,   59,   79,
+       79,  160,  160,  167,  167,  168,  168,  179,  179,  180,
+      180,  274,  274,   30,    1,    2,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
@@ -1027,150 +1026,149 @@ static const flex_int16_t yy_chk[1389] =
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
 
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
-        3,    3,    3,    3,    3,    3,    3,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,   37,   40,   41,    9,
-       10,    5,    5,    5,    9,   10,  273,  273,   27,   26,
-       26,   26,  367,  367,   31,   24,   20,   13,    0,    0,
-       26,    0,   31,    0,   31,   37,   40,   41,    0,   31,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,   26,   26,
+       26,    9,   10,    5,    5,    5,    9,   10,   31,   26,
+       37,   38,   39,  275,  275,   27,   31,   39,   31,   40,
+       41,   43,   32,   31,   44,   38,   32,   43,   47,   32,
+       44,   24,    5,    5,  369,  369,   20,   31,   26,   37,
+       38,   39,   32,    9,   10,   31,   39,   31,   40,   41,
+       43,   32,   31,   44,   38,   32,   43,   47,   32,   44,
         5,    5,    6,    6,    6,    6,    6,    6,    6,    6,
-        6,    9,   10,   31,   35,   38,    6,    6,    6,   26,
-       32,   31,   34,   31,   32,   43,   34,   32,   31,   38,
-       34,   43,   47,   39,    0,   35,   34,   35,   39,   34,
-
-       32,    0,    0,   52,   38,    6,    6,   35,    0,   32,
-        0,   34,    0,   32,   43,   34,   32,   44,   38,   34,
-       43,   47,   39,   44,   35,   34,   35,   39,   34,   32,
-       33,   42,   52,   53,   53,   42,   35,   33,   46,   42,
-       55,   45,   46,   83,   33,   42,   44,   33,   33,   45,
-       33,    0,   44,   45,   85,   46,   45,   45,    0,   33,
-       42,   86,   53,   53,   42,    0,   33,   46,   42,   55,
-       45,   46,   83,   33,   42,    0,   33,   33,   45,   33,
-       36,    0,   45,   85,   46,   45,   45,   51,   36,   51,
-       86,   36,   51,   84,   36,   49,   87,   36,   48,    0,
-
-       36,   84,   48,   49,   74,   74,   48,    0,    0,   36,
-       49,   49,   48,    0,   74,   88,   51,   36,   51,   89,
-       36,   51,   84,   36,   49,   87,   36,   48,   88,   36,
-       84,   48,   49,    0,   91,   48,   75,   75,    0,   49,
-       49,   48,   50,   74,   88,   94,   75,   92,   89,   50,
-       50,   92,   95,   76,   76,   76,   50,   88,   96,   50,
-       99,   97,   50,   91,   76,   93,   97,   93,  100,   93,
-        0,   50,    0,    0,   94,   75,   92,  101,   50,   50,
-       92,   95,    0,  103,  104,   50,    0,   96,   50,   99,
-       97,   50,   66,   76,   93,   97,   93,  100,   93,   98,
-
-       66,   66,   98,  105,  106,  107,  101,   66,   98,  108,
-      109,   66,  103,  104,  105,   98,  109,  110,  111,   66,
-      112,  113,  114,   66,  113,   66,    0,  117,   98,   66,
-      118,   98,  105,  106,  107,  119,   66,   98,  108,  109,
-       66,    0,    0,  105,   98,  109,  110,  111,   66,  112,
-      113,  114,   66,  113,   66,  115,  117,  120,   66,  118,
-      121,  122,  121,  123,  119,  115,  124,  125,  126,  127,
-      115,  115,  129,  130,  131,  132,  133,  134,  135,  136,
-      138,  134,  137,  139,  115,  141,  120,  137,  137,  121,
-      122,  121,  123,    0,  115,  124,  125,  126,  127,  115,
-
-      115,  129,  130,  131,  132,  133,  134,  135,  136,  138,
-      134,  137,  139,  140,  141,  142,  137,  137,  143,  144,
-      145,  146,  140,  148,  149,  150,  151,  152,  153,  154,
-      140,  155,  150,  156,  153,  176,  176,  155,  181,  183,
-      184,  185,  140,  186,  142,  176,  189,  143,  144,  145,
-      146,  140,  148,  149,  150,  151,  152,  153,  154,  140,
-      155,  150,  156,  153,  187,  188,  155,  181,  183,  184,
-      185,  190,  186,  191,  176,  189,  187,  192,  193,  194,
-      188,  195,  196,  197,  199,  200,  201,  202,  203,  204,
-      205,  206,  208,  187,  188,  209,  210,  211,  212,  213,
-
-      190,  214,  191,  215,  216,  187,  192,  193,  194,  188,
-      195,  196,  197,  199,  200,  201,  202,  203,  204,  205,
-      206,  208,  217,  218,  209,  210,  211,  212,  213,  219,
-      214,  220,  215,  216,  221,  222,  223,  224,  225,  227,
-      228,  229,  230,  231,  232,  233,  235,  224,  237,  238,
-      239,  217,  218,  240,  241,  242,  244,  243,  219,  243,
-      220,  245,  246,  221,  222,  223,  224,  225,  227,  228,
-      229,  230,  231,  232,  233,  235,  224,  237,  238,  239,
-      247,  248,  240,  241,  242,  244,  243,  249,  243,  250,
-      245,  246,  251,  252,  254,  255,  256,  257,  258,  250,
-
-      259,  260,  261,  262,  263,  255,  263,  264,  265,  247,
-      248,  266,  267,  268,  269,  270,  249,  268,  250,  271,
-      275,  251,  252,  254,  255,  256,  257,  258,  276,  259,
-      260,  261,  262,  263,  255,  263,  264,  265,  277,  278,
-      266,  267,  268,  269,  270,  279,  268,  280,  271,  275,
-      281,  284,  285,  286,  287,  289,  290,  276,  291,  292,
-      293,  294,  295,  296,  297,  298,  301,  277,  278,  302,
-      303,  304,  305,  306,  279,  307,  280,  310,  312,  281,
-      284,  285,  286,  287,  289,  290,  314,  291,  292,  293,
-      294,  295,  296,  297,  298,  301,  315,  316,  302,  303,
-
-      304,  305,  306,  317,  307,  323,  310,  312,  325,  326,
-      327,  328,  329,  331,  317,  314,  332,  333,  334,  335,
-      337,  339,  340,  341,  343,  315,  316,  344,  345,  346,
-      347,  348,  317,  349,  323,  350,  352,  325,  326,  327,
-      328,  329,  331,  317,  354,  332,  333,  334,  335,  337,
-      339,  340,  341,  343,  355,  356,  344,  345,  346,  347,
-      348,  357,  349,  358,  350,  352,  359,  360,  361,  363,
-      364,  366,  370,  354,  371,  372,  373,  374,  375,  376,
-      374,  378,  379,  355,  356,  380,  381,  382,  383,  384,
-      357,  385,  358,  386,  387,  359,  360,  361,  363,  364,
-
-      366,  370,  388,  371,  372,  373,  374,  375,  376,  374,
-      378,  379,  389,  390,  380,  381,  382,  383,  384,  391,
-      385,  395,  386,  387,  396,  398,  401,  402,  405,  403,
-      410,  388,  403,  411,  412,  413,  414,  416,  417,  419,
-      420,  389,  390,  421,  422,  423,  424,  425,  391,  427,
-      395,  428,  429,  396,  398,  401,  402,  405,  403,  410,
-      431,  403,  411,  412,  413,  414,  416,  417,  419,  420,
-      432,  434,  421,  422,  423,  424,  425,  435,  427,  437,
-      428,  429,  438,  439,  440,  442,  443,  444,  445,  431,
-      446,  448,  450,  451,  452,  453,  454,  456,  457,  432,
-
-      434,  460,  461,  462,  465,  466,  435,  467,  437,  469,
-      470,  438,  439,  440,  442,  443,  444,  445,  471,  446,
-      448,  450,  451,  452,  453,  454,  456,  457,  472,  473,
-      460,  461,  462,  465,  466,  474,  467,  476,  469,  470,
-      479,  482,  483,  484,  485,  489,  491,  471,  492,  494,
-      495,  496,  497,  498,  499,  502,  505,  472,  473,  506,
-      508,  511,  512,  513,  474,  515,  476,  517,  518,  479,
-      482,  483,  484,  485,  489,  491,  519,  492,  494,  495,
-      496,  497,  498,  499,  502,  505,  520,  521,  506,  508,
-      511,  512,  513,  522,  515,  523,  517,  518,  524,  526,
-
-      527,  528,  529,  530,  531,  519,  532,  533,  535,  537,
-      538,  540,  541,  543,  544,  520,  521,  546,  547,  548,
-      549,  550,  522,  552,  523,  553,  554,  524,  526,  527,
-      528,  529,  530,  531,  555,  532,  533,  535,  537,  538,
-      540,  541,  543,  544,  557,  558,  546,  547,  548,  549,
-      550,  561,  552,  563,  553,  554,  564,  567,  571,  572,
-      573,  578,  579,  555,  580,  583,  585,  586,  587,  589,
-        0,    0,    0,  557,  558,    0,    0,    0,    0,    0,
-      561,    0,  563,    0,    0,  564,  567,  571,  572,  573,
-      578,  579,    0,  580,  583,  585,  586,  587,  589,  592,
-
-      592,  592,  592,  592,  592,  592,  592,  592,  592,  593,
-      593,  593,  593,  593,  593,  593,  593,  593,  593,  594,
-      594,  594,  594,  594,  594,  594,  594,  594,  594,  595,
-      595,  595,  595,  595,  595,  595,  595,  595,  595,  596,
-      596,  596,  596,  596,  596,  596,  596,  596,  596,  597,
-      597,  598,  598,  598,    0,  598,  599,  599,  599,  599,
-        0,  599,  600,  600,  600,    0,  600,  600,  600,  600,
-      600,  600,  601,  601,  601,    0,  601,  601,  601,  601,
-        0,  601,  602,  602,  602,  602,  602,  602,  602,  602,
-      602,  602,  603,  603,    0,  603,  603,  603,  603,  603,
-
-      603,  603,  604,    0,  604,  604,  604,  604,  604,  604,
-      604,  604,  605,  605,  606,  606,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591,  591,  591,
-      591,  591,  591,  591,  591,  591,  591,  591
+
+        6,   32,   52,   55,   35,   34,    6,    6,    6,   34,
+       42,   46,   48,   34,   42,   46,   48,   85,   42,   34,
+       48,   86,   34,   87,   42,   35,   48,   35,   46,   86,
+       13,   52,   55,   88,   34,    6,    6,   35,   34,   42,
+       46,   48,   34,   42,   46,   48,   85,   42,   34,   48,
+       86,   34,   87,   42,   35,   48,   35,   46,   86,   45,
+       89,   49,   88,    6,    6,   33,   35,   45,   51,   49,
+       51,   45,   33,   51,   45,   45,   49,   49,   91,   33,
+       53,   53,   33,   33,   93,   33,    0,   96,   45,   89,
+       49,    0,    0,   97,   33,   98,   45,   51,   49,   51,
+
+       45,   33,   51,   45,   45,   49,   49,   91,   33,   53,
+       53,   33,   33,   93,   33,   36,   96,   76,   76,  101,
+       77,   77,   97,   36,   98,  102,   36,   76,   90,   36,
+       77,  103,   36,  105,   99,   36,   78,   78,   78,   99,
+      106,   90,   94,    0,   36,    0,   94,   78,  101,    0,
+        0,  108,   36,    0,  102,   36,   76,   90,   36,   77,
+      103,   36,  105,   99,   36,   50,  109,  107,   99,  106,
+       90,   94,   50,   50,  100,   94,   78,  100,  107,   50,
+      108,  110,   50,  100,  112,   50,    0,   95,  113,   95,
+      100,   95,  111,  114,   50,  109,  107,  115,  111,  116,
+
+      115,   50,   50,  100,  119,    0,  100,  107,   50,  120,
+      110,   50,  100,  112,   50,   68,   95,  113,   95,  100,
+       95,  111,  114,   68,   68,  117,  115,  111,  116,  115,
+       68,  121,  122,  119,   68,  117,  124,  123,  120,  123,
+      117,  117,   68,  125,  126,  127,   68,  128,   68,  129,
+      131,  132,   68,  133,  117,  134,  135,  137,  136,   68,
+      121,  122,  136,   68,  117,  124,  123,  138,  123,  117,
+      117,   68,  125,  126,  127,   68,  128,   68,  129,  131,
+      132,   68,  133,  139,  134,  135,  137,  136,  139,  139,
+      140,  136,  141,  142,  143,  144,  138,  145,  146,  147,
+
+      148,  150,  142,  151,  152,  153,  154,  155,  156,  157,
+      142,  152,  139,  155,  158,  157,    0,  139,  139,  140,
+      183,  141,  142,  143,  144,  185,  145,  146,  147,  148,
+      150,  142,  151,  152,  153,  154,  155,  156,  157,  142,
+      152,  186,  155,  158,  157,  178,  178,  187,  188,  183,
+      189,  190,  191,  192,  185,  178,  193,  194,  195,  196,
+      197,  198,  189,  199,  201,  202,  190,  203,  204,  205,
+      186,  206,  207,  208,  210,  211,  187,  188,  212,  189,
+      190,  191,  192,  213,  178,  193,  194,  195,  196,  197,
+      198,  189,  199,  201,  202,  190,  203,  204,  205,  214,
+
+      206,  207,  208,  210,  211,  215,  216,  212,  217,  218,
+      219,  220,  213,  221,  222,  223,  224,  225,  227,  226,
+      229,  230,  231,  232,  233,  234,  235,  237,  214,  226,
+      239,  240,  241,  242,  215,  216,  243,  217,  218,  219,
+      220,  244,  221,  222,  223,  224,  225,  227,  226,  229,
+      230,  231,  232,  233,  234,  235,  237,  246,  226,  239,
+      240,  241,  242,  247,  245,  243,  245,  248,  249,  250,
+      244,  251,  252,  253,  254,  256,  258,  257,  259,  260,
+      261,  262,  252,  263,  264,  266,  246,  257,  265,  267,
+      265,  268,  247,  245,  269,  245,  248,  249,  250,  271,
+
+      251,  252,  253,  254,  256,  258,  257,  259,  260,  261,
+      262,  270,  263,  264,  266,  270,  257,  265,  267,  265,
+      268,  272,  273,  269,  277,  278,  279,  280,  271,  281,
+      282,  283,  286,  287,  288,  289,  291,  292,  293,  294,
+      270,  295,  296,  297,  270,  298,  299,  300,  303,  304,
+      272,  273,  305,  277,  278,  279,  280,  306,  281,  282,
+      283,  286,  287,  288,  289,  291,  292,  293,  294,  307,
+      295,  296,  297,  308,  298,  299,  300,  303,  304,  309,
+      312,  305,  314,  316,  317,  318,  306,  325,  319,  327,
+      328,  329,  330,  331,  333,  334,  335,  336,  307,  319,
+
+      337,  339,  308,  341,  342,  343,  345,  346,  309,  312,
+      347,  314,  316,  317,  318,  348,  325,  319,  327,  328,
+      329,  330,  331,  333,  334,  335,  336,  349,  319,  337,
+      339,  350,  341,  342,  343,  345,  346,  351,  352,  347,
+      354,  356,  357,  358,  348,  359,  360,  361,  362,  363,
+      365,  366,  368,  372,  373,  374,  349,  375,  376,  377,
+      350,  376,  378,  380,  381,  382,  351,  352,  383,  354,
+      356,  357,  358,  384,  359,  360,  361,  362,  363,  365,
+      366,  368,  372,  373,  374,  385,  375,  376,  377,  386,
+      376,  378,  380,  381,  382,  387,  388,  383,  389,  390,
+
+      391,  392,  384,  393,  397,  398,  400,  403,  404,  405,
+      407,  412,  405,  413,  385,  414,  415,  416,  386,  418,
+      419,  421,  422,  423,  387,  388,  424,  389,  390,  391,
+      392,  425,  393,  397,  398,  400,  403,  404,  405,  407,
+      412,  405,  413,  426,  414,  415,  416,  427,  418,  419,
+      421,  422,  423,  429,  430,  424,  431,  433,  434,  436,
+      425,  437,  439,  440,  441,  442,  444,  445,  446,  447,
+      448,  450,  426,  452,  453,  454,  427,  455,  456,  458,
+      459,  462,  429,  430,  463,  431,  433,  434,  436,  464,
+      437,  439,  440,  441,  442,  444,  445,  446,  447,  448,
+
+      450,  467,  452,  453,  454,  468,  455,  456,  458,  459,
+      462,  469,  471,  463,  472,  473,  474,  475,  464,  476,
+      478,  481,  484,  485,  486,  487,  491,  493,  494,  496,
+      467,  497,  498,  499,  468,  500,  501,  504,  507,  508,
+      469,  471,  510,  472,  473,  474,  475,  513,  476,  478,
+      481,  484,  485,  486,  487,  491,  493,  494,  496,  514,
+      497,  498,  499,  515,  500,  501,  504,  507,  508,  517,
+      519,  510,  520,  521,  522,  523,  513,  524,  525,  526,
+      528,  529,  530,  531,  532,  533,  534,  535,  514,  537,
+      539,  540,  515,  542,  543,  545,  546,  548,  517,  519,
+
+      549,  520,  521,  522,  523,  550,  524,  525,  526,  528,
+      529,  530,  531,  532,  533,  534,  535,  551,  537,  539,
+      540,  552,  542,  543,  545,  546,  548,  554,  555,  549,
+      556,  557,  559,  560,  550,  563,  565,  566,  569,  573,
+      574,  575,  580,  581,  582,  585,  551,  587,  588,  589,
+      552,  591,    0,    0,    0,    0,  554,  555,    0,  556,
+      557,  559,  560,    0,  563,  565,  566,  569,  573,  574,
+      575,  580,  581,  582,  585,    0,  587,  588,  589,    0,
+      591,  594,  594,  594,  594,  594,  594,  594,  594,  594,
+      594,  595,  595,  595,  595,  595,  595,  595,  595,  595,
+
+      595,  596,  596,  596,  596,  596,  596,  596,  596,  596,
+      596,  597,  597,  597,  597,  597,  597,  597,  597,  597,
+      597,  598,  598,  598,  598,  598,  598,  598,  598,  598,
+      598,  599,  599,  600,  600,  600,    0,  600,  601,  601,
+      601,  601,    0,  601,  602,  602,  602,    0,  602,  602,
+      602,  602,  602,  602,  603,  603,  603,    0,  603,  603,
+      603,  603,    0,  603,  604,  604,  604,  604,  604,  604,
+      604,  604,  604,  604,  605,  605,    0,  605,  605,  605,
+      605,  605,  605,  605,  606,    0,  606,  606,  606,  606,
+      606,  606,  606,  606,  607,  607,  608,  608,  593,  593,
+
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+      593,  593
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static const flex_int32_t yy_rule_can_match_eol[167] =
+static const flex_int32_t yy_rule_can_match_eol[169] =
     {   0,
 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1179,8 +1177,8 @@ static const flex_int32_t yy_rule_can_match_eol[167] =
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 
-    0, 0, 0, 1, 0, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 
+    1, 1, 0, 0, 0, 1, 0, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -1224,6 +1222,7 @@ namespace quickstep {
 
 class BinaryOperation;
 class Comparison;
+class ParseArray;
 class ParseAssignment;
 class ParseAttribute;
 class ParseAttributeDefinition;
@@ -1291,14 +1290,14 @@ class UnaryOperation;
     yycolumn += yyleng;                                   \
   }
 
-#line 1294 "SqlLexer_gen.cpp"
+#line 1293 "SqlLexer_gen.cpp"
 /* FIXME(chasseur, qzeng): Add support for hexadecimal literals. */
 /**
  * These patterns are based on the SQL-2011 standard for syntax of numeric
  * literals (Part 2, Section 5.3 of the standard).
  **/
 
-#line 1301 "SqlLexer_gen.cpp"
+#line 1300 "SqlLexer_gen.cpp"
 
 #define INITIAL 0
 #define CONDITION_SQL 1
@@ -1585,10 +1584,10 @@ YY_DECL
 		}
 
 	{
-#line 132 "../SqlLexer.lpp"
+#line 133 "../SqlLexer.lpp"
 
 
-#line 1591 "SqlLexer_gen.cpp"
+#line 1590 "SqlLexer_gen.cpp"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1615,13 +1614,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 592 )
+				if ( yy_current_state >= 594 )
 					yy_c = yy_meta[yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 591 );
+		while ( yy_current_state != 593 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1655,7 +1654,7 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 135 "../SqlLexer.lpp"
+#line 136 "../SqlLexer.lpp"
 {
     /* A forward slash character represents a system command. */
     BEGIN(CONDITION_COMMAND);
@@ -1667,7 +1666,7 @@ YY_RULE_SETUP
 case 2:
 /* rule 2 can match eol */
 YY_RULE_SETUP
-#line 143 "../SqlLexer.lpp"
+#line 144 "../SqlLexer.lpp"
 {
     /* This is a SQL command. Place the char back and process normally. */
     yyless(0);
@@ -1679,7 +1678,7 @@ YY_RULE_SETUP
 
 case 3:
 YY_RULE_SETUP
-#line 152 "../SqlLexer.lpp"
+#line 153 "../SqlLexer.lpp"
 {
     /* This is a command argument. */
     yylval->string_value_ = new quickstep::ParseString(
@@ -1689,7 +1688,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 159 "../SqlLexer.lpp"
+#line 160 "../SqlLexer.lpp"
 {
     /* Ignore whitespace. */
   }
@@ -1697,7 +1696,7 @@ YY_RULE_SETUP
 case 5:
 /* rule 5 can match eol */
 YY_RULE_SETUP
-#line 163 "../SqlLexer.lpp"
+#line 164 "../SqlLexer.lpp"
 {
     /* Newline reverts the lexer to the initial state. */
     yycolumn = 0;
@@ -1709,697 +1708,707 @@ YY_RULE_SETUP
 
 case 6:
 YY_RULE_SETUP
-#line 172 "../SqlLexer.lpp"
+#line 173 "../SqlLexer.lpp"
 return TOKEN_ADD;
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 173 "../SqlLexer.lpp"
+#line 174 "../SqlLexer.lpp"
 return TOKEN_ALL;
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 174 "../SqlLexer.lpp"
+#line 175 "../SqlLexer.lpp"
 return TOKEN_ALTER;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 175 "../SqlLexer.lpp"
+#line 176 "../SqlLexer.lpp"
 return TOKEN_AND;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 176 "../SqlLexer.lpp"
+#line 177 "../SqlLexer.lpp"
 return TOKEN_AS;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 177 "../SqlLexer.lpp"
+#line 178 "../SqlLexer.lpp"
 return TOKEN_ASC;
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 178 "../SqlLexer.lpp"
+#line 179 "../SqlLexer.lpp"
 return TOKEN_ASC;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 179 "../SqlLexer.lpp"
+#line 180 "../SqlLexer.lpp"
 return TOKEN_BETWEEN;
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 180 "../SqlLexer.lpp"
+#line 181 "../SqlLexer.lpp"
 return TOKEN_BIGINT;
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 181 "../SqlLexer.lpp"
+#line 182 "../SqlLexer.lpp"
 return TOKEN_BIT;
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 182 "../SqlLexer.lpp"
+#line 183 "../SqlLexer.lpp"
 return TOKEN_BITWEAVING;
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 183 "../SqlLexer.lpp"
+#line 184 "../SqlLexer.lpp"
 return TOKEN_BLOCKPROPERTIES;
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 184 "../SqlLexer.lpp"
+#line 185 "../SqlLexer.lpp"
 return TOKEN_BLOCKSAMPLE;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 185 "../SqlLexer.lpp"
+#line 186 "../SqlLexer.lpp"
 return TOKEN_BLOOM_FILTER;
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 186 "../SqlLexer.lpp"
+#line 187 "../SqlLexer.lpp"
 return TOKEN_CASE;
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 187 "../SqlLexer.lpp"
+#line 188 "../SqlLexer.lpp"
 return TOKEN_CAST;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 188 "../SqlLexer.lpp"
+#line 189 "../SqlLexer.lpp"
 return TOKEN_CSB_TREE;
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 189 "../SqlLexer.lpp"
+#line 190 "../SqlLexer.lpp"
 return TOKEN_BY;
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 190 "../SqlLexer.lpp"
+#line 191 "../SqlLexer.lpp"
 return TOKEN_CHARACTER;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 191 "../SqlLexer.lpp"
+#line 192 "../SqlLexer.lpp"
 return TOKEN_CHARACTER;
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 192 "../SqlLexer.lpp"
+#line 193 "../SqlLexer.lpp"
 return TOKEN_CHECK;
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 193 "../SqlLexer.lpp"
+#line 194 "../SqlLexer.lpp"
 return TOKEN_COLUMN;
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 194 "../SqlLexer.lpp"
+#line 195 "../SqlLexer.lpp"
 return TOKEN_CONSTRAINT;
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 195 "../SqlLexer.lpp"
+#line 196 "../SqlLexer.lpp"
 return TOKEN_COPY;
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 196 "../SqlLexer.lpp"
+#line 197 "../SqlLexer.lpp"
 return TOKEN_CREATE;
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 197 "../SqlLexer.lpp"
+#line 198 "../SqlLexer.lpp"
 return TOKEN_CURRENT;
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 198 "../SqlLexer.lpp"
+#line 199 "../SqlLexer.lpp"
 return TOKEN_DATE;
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 199 "../SqlLexer.lpp"
+#line 200 "../SqlLexer.lpp"
 return TOKEN_DATETIME;
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 200 "../SqlLexer.lpp"
+#line 201 "../SqlLexer.lpp"
 return TOKEN_DAY;
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 201 "../SqlLexer.lpp"
+#line 202 "../SqlLexer.lpp"
 return TOKEN_DECIMAL;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 202 "../SqlLexer.lpp"
+#line 203 "../SqlLexer.lpp"
 return TOKEN_DEFAULT;
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 203 "../SqlLexer.lpp"
+#line 204 "../SqlLexer.lpp"
 return TOKEN_DELETE;
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 204 "../SqlLexer.lpp"
+#line 205 "../SqlLexer.lpp"
 return TOKEN_DESC;
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 205 "../SqlLexer.lpp"
+#line 206 "../SqlLexer.lpp"
 return TOKEN_DESC;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 206 "../SqlLexer.lpp"
+#line 207 "../SqlLexer.lpp"
 return TOKEN_DISTINCT;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 207 "../SqlLexer.lpp"
+#line 208 "../SqlLexer.lpp"
 return TOKEN_DOUBLE;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 208 "../SqlLexer.lpp"
+#line 209 "../SqlLexer.lpp"
 return TOKEN_DROP;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 209 "../SqlLexer.lpp"
+#line 210 "../SqlLexer.lpp"
 return TOKEN_ELSE;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 210 "../SqlLexer.lpp"
+#line 211 "../SqlLexer.lpp"
 return TOKEN_END;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 211 "../SqlLexer.lpp"
+#line 212 "../SqlLexer.lpp"
 return TOKEN_EXISTS;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 212 "../SqlLexer.lpp"
+#line 213 "../SqlLexer.lpp"
 return TOKEN_EXTRACT;
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 213 "../SqlLexer.lpp"
+#line 214 "../SqlLexer.lpp"
 return TOKEN_FALSE;
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 214 "../SqlLexer.lpp"
+#line 215 "../SqlLexer.lpp"
 return TOKEN_FIRST;
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 215 "../SqlLexer.lpp"
+#line 216 "../SqlLexer.lpp"
 return TOKEN_FLOAT;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 216 "../SqlLexer.lpp"
+#line 217 "../SqlLexer.lpp"
 return TOKEN_FOLLOWING;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 217 "../SqlLexer.lpp"
+#line 218 "../SqlLexer.lpp"
 return TOKEN_FOR;
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 218 "../SqlLexer.lpp"
+#line 219 "../SqlLexer.lpp"
 return TOKEN_FOREIGN;
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 219 "../SqlLexer.lpp"
+#line 220 "../SqlLexer.lpp"
 return TOKEN_FROM;
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 220 "../SqlLexer.lpp"
+#line 221 "../SqlLexer.lpp"
 return TOKEN_FULL;
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 221 "../SqlLexer.lpp"
+#line 222 "../SqlLexer.lpp"
 return TOKEN_GROUP;
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 222 "../SqlLexer.lpp"
+#line 223 "../SqlLexer.lpp"
 return TOKEN_HASH;
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 223 "../SqlLexer.lpp"
+#line 224 "../SqlLexer.lpp"
 return TOKEN_HAVING;
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 224 "../SqlLexer.lpp"
+#line 225 "../SqlLexer.lpp"
 return TOKEN_HOUR;
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 225 "../SqlLexer.lpp"
+#line 226 "../SqlLexer.lpp"
 return TOKEN_IN;
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 226 "../SqlLexer.lpp"
+#line 227 "../SqlLexer.lpp"
 return TOKEN_INDEX;
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 227 "../SqlLexer.lpp"
+#line 228 "../SqlLexer.lpp"
 return TOKEN_INNER;
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 228 "../SqlLexer.lpp"
+#line 229 "../SqlLexer.lpp"
 return TOKEN_INSERT;
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 229 "../SqlLexer.lpp"
+#line 230 "../SqlLexer.lpp"
 return TOKEN_INTEGER;
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 230 "../SqlLexer.lpp"
+#line 231 "../SqlLexer.lpp"
 return TOKEN_INTEGER;
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 231 "../SqlLexer.lpp"
+#line 232 "../SqlLexer.lpp"
 return TOKEN_INTERSECT;
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 232 "../SqlLexer.lpp"
+#line 233 "../SqlLexer.lpp"
 return TOKEN_INTERVAL;
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 233 "../SqlLexer.lpp"
+#line 234 "../SqlLexer.lpp"
 return TOKEN_INTO;
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 234 "../SqlLexer.lpp"
+#line 235 "../SqlLexer.lpp"
 return TOKEN_IS;
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 235 "../SqlLexer.lpp"
+#line 236 "../SqlLexer.lpp"
 return TOKEN_JOIN;
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 236 "../SqlLexer.lpp"
+#line 237 "../SqlLexer.lpp"
 return TOKEN_KEY;
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 237 "../SqlLexer.lpp"
+#line 238 "../SqlLexer.lpp"
 return TOKEN_LAST;
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 238 "../SqlLexer.lpp"
+#line 239 "../SqlLexer.lpp"
 return TOKEN_LEFT;
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 239 "../SqlLexer.lpp"
+#line 240 "../SqlLexer.lpp"
 return TOKEN_LIKE;
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 240 "../SqlLexer.lpp"
+#line 241 "../SqlLexer.lpp"
 return TOKEN_LIMIT;
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 241 "../SqlLexer.lpp"
+#line 242 "../SqlLexer.lpp"
 return TOKEN_LONG;
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 242 "../SqlLexer.lpp"
+#line 243 "../SqlLexer.lpp"
 return TOKEN_MINUTE;
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 243 "../SqlLexer.lpp"
+#line 244 "../SqlLexer.lpp"
 return TOKEN_MONTH;
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 244 "../SqlLexer.lpp"
+#line 245 "../SqlLexer.lpp"
 return TOKEN_NOT;
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 245 "../SqlLexer.lpp"
+#line 246 "../SqlLexer.lpp"
 return TOKEN_NULL;
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 246 "../SqlLexer.lpp"
+#line 247 "../SqlLexer.lpp"
 return TOKEN_NULLS;
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 247 "../SqlLexer.lpp"
+#line 248 "../SqlLexer.lpp"
 return TOKEN_OFF;
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 248 "../SqlLexer.lpp"
+#line 249 "../SqlLexer.lpp"
 return TOKEN_ON;
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 249 "../SqlLexer.lpp"
+#line 250 "../SqlLexer.lpp"
 return TOKEN_OR;
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 250 "../SqlLexer.lpp"
+#line 251 "../SqlLexer.lpp"
 return TOKEN_ORDER;
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 251 "../SqlLexer.lpp"
+#line 252 "../SqlLexer.lpp"
 return TOKEN_OUTER;
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 252 "../SqlLexer.lpp"
+#line 253 "../SqlLexer.lpp"
 return TOKEN_OVER;
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 253 "../SqlLexer.lpp"
+#line 254 "../SqlLexer.lpp"
 return TOKEN_PARTITION;
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 254 "../SqlLexer.lpp"
+#line 255 "../SqlLexer.lpp"
 return TOKEN_PARTITIONS;
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 255 "../SqlLexer.lpp"
+#line 256 "../SqlLexer.lpp"
 return TOKEN_PERCENT;
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 256 "../SqlLexer.lpp"
+#line 257 "../SqlLexer.lpp"
 return TOKEN_PRECEDING;
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 257 "../SqlLexer.lpp"
+#line 258 "../SqlLexer.lpp"
 return TOKEN_PRIMARY;
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 258 "../SqlLexer.lpp"
+#line 259 "../SqlLexer.lpp"
 return TOKEN_PRIORITY;
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 259 "../SqlLexer.lpp"
+#line 260 "../SqlLexer.lpp"
 return TOKEN_QUIT;
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 260 "../SqlLexer.lpp"
+#line 261 "../SqlLexer.lpp"
 return TOKEN_RANGE;
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 261 "../SqlLexer.lpp"
+#line 262 "../SqlLexer.lpp"
 return TOKEN_REAL;
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 262 "../SqlLexer.lpp"
+#line 263 "../SqlLexer.lpp"
 return TOKEN_REFERENCES;
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 263 "../SqlLexer.lpp"
+#line 264 "../SqlLexer.lpp"
 return TOKEN_REGEXP;
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 264 "../SqlLexer.lpp"
+#line 265 "../SqlLexer.lpp"
 return TOKEN_RIGHT;
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
-#line 265 "../SqlLexer.lpp"
+#line 266 "../SqlLexer.lpp"
 return TOKEN_ROW;
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
-#line 266 "../SqlLexer.lpp"
+#line 267 "../SqlLexer.lpp"
 return TOKEN_ROW_DELIMITER;
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
-#line 267 "../SqlLexer.lpp"
+#line 268 "../SqlLexer.lpp"
 return TOKEN_ROWS;
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
-#line 268 "../SqlLexer.lpp"
+#line 269 "../SqlLexer.lpp"
 return TOKEN_SECOND;
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
-#line 269 "../SqlLexer.lpp"
+#line 270 "../SqlLexer.lpp"
 return TOKEN_SELECT;
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
-#line 270 "../SqlLexer.lpp"
+#line 271 "../SqlLexer.lpp"
 return TOKEN_SET;
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
-#line 271 "../SqlLexer.lpp"
+#line 272 "../SqlLexer.lpp"
 return TOKEN_SMA;
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
-#line 272 "../SqlLexer.lpp"
+#line 273 "../SqlLexer.lpp"
 return TOKEN_SMALLINT;
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
-#line 273 "../SqlLexer.lpp"
+#line 274 "../SqlLexer.lpp"
 return TOKEN_STDERR;
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
-#line 274 "../SqlLexer.lpp"
+#line 275 "../SqlLexer.lpp"
 return TOKEN_STDOUT;
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 275 "../SqlLexer.lpp"
+#line 276 "../SqlLexer.lpp"
 return TOKEN_SUBSTRING;
 	YY_BREAK
 case 110:
 YY_RULE_SETUP
-#line 276 "../SqlLexer.lpp"
+#line 277 "../SqlLexer.lpp"
 return TOKEN_TABLE;
 	YY_BREAK
 case 111:
 YY_RULE_SETUP
-#line 277 "../SqlLexer.lpp"
+#line 278 "../SqlLexer.lpp"
 return TOKEN_THEN;
 	YY_BREAK
 case 112:
 YY_RULE_SETUP
-#line 278 "../SqlLexer.lpp"
+#line 279 "../SqlLexer.lpp"
 return TOKEN_TIME;
 	YY_BREAK
 case 113:
 YY_RULE_SETUP
-#line 279 "../SqlLexer.lpp"
+#line 280 "../SqlLexer.lpp"
 return TOKEN_TIMESTAMP;
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
-#line 280 "../SqlLexer.lpp"
+#line 281 "../SqlLexer.lpp"
 return TOKEN_TO;
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
-#line 281 "../SqlLexer.lpp"
+#line 282 "../SqlLexer.lpp"
 return TOKEN_TRUE;
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 282 "../SqlLexer.lpp"
+#line 283 "../SqlLexer.lpp"
 return TOKEN_TUPLESAMPLE;
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
-#line 283 "../SqlLexer.lpp"
+#line 284 "../SqlLexer.lpp"
 return TOKEN_UNBOUNDED;
 	YY_BREAK
 case 118:
 YY_RULE_SETUP
-#line 284 "../SqlLexer.lpp"
+#line 285 "../SqlLexer.lpp"
 return TOKEN_UNION;
 	YY_BREAK
 case 119:
 YY_RULE_SETUP
-#line 285 "../SqlLexer.lpp"
+#line 286 "../SqlLexer.lpp"
 return TOKEN_UNIQUE;
 	YY_BREAK
 case 120:
 YY_RULE_SETUP
-#line 286 "../SqlLexer.lpp"
+#line 287 "../SqlLexer.lpp"
 return TOKEN_UPDATE;
 	YY_BREAK
 case 121:
 YY_RULE_SETUP
-#line 287 "../SqlLexer.lpp"
+#line 288 "../SqlLexer.lpp"
 return TOKEN_USING;
 	YY_BREAK
 case 122:
 YY_RULE_SETUP
-#line 288 "../SqlLexer.lpp"
+#line 289 "../SqlLexer.lpp"
 return TOKEN_VALUES;
 	YY_BREAK
 case 123:
 YY_RULE_SETUP
-#line 289 "../SqlLexer.lpp"
+#line 290 "../SqlLexer.lpp"
 return TOKEN_VARCHAR;
 	YY_BREAK
 case 124:
 YY_RULE_SETUP
-#line 290 "../SqlLexer.lpp"
+#line 291 "../SqlLexer.lpp"
 return TOKEN_WHEN;
 	YY_BREAK
 case 125:
 YY_RULE_SETUP
-#line 291 "../SqlLexer.lpp"
+#line 292 "../SqlLexer.lpp"
 return TOKEN_WHERE;
 	YY_BREAK
 case 126:
 YY_RULE_SETUP
-#line 292 "../SqlLexer.lpp"
+#line 293 "../SqlLexer.lpp"
 return TOKEN_WINDOW;
 	YY_BREAK
 case 127:
 YY_RULE_SETUP
-#line 293 "../SqlLexer.lpp"
+#line 294 "../SqlLexer.lpp"
 return TOKEN_WITH;
 	YY_BREAK
 case 128:
 YY_RULE_SETUP
-#line 294 "../SqlLexer.lpp"
+#line 295 "../SqlLexer.lpp"
 return TOKEN_YEAR;
 	YY_BREAK
 case 129:
 YY_RULE_SETUP
-#line 295 "../SqlLexer.lpp"
+#line 296 "../SqlLexer.lpp"
 return TOKEN_YEARMONTH;
 	YY_BREAK
 case 130:
 YY_RULE_SETUP
-#line 297 "../SqlLexer.lpp"
+#line 298 "../SqlLexer.lpp"
 return TOKEN_EQ;
 	YY_BREAK
 case 131:
 YY_RULE_SETUP
-#line 298 "../SqlLexer.lpp"
+#line 299 "../SqlLexer.lpp"
 return TOKEN_NEQ;
 	YY_BREAK
 case 132:
 YY_RULE_SETUP
-#line 299 "../SqlLexer.lpp"
+#line 300 "../SqlLexer.lpp"
 return TOKEN_NEQ;
 	YY_BREAK
 case 133:
 YY_RULE_SETUP
-#line 300 "../SqlLexer.lpp"
+#line 301 "../SqlLexer.lpp"
 return TOKEN_LT;
 	YY_BREAK
 case 134:
 YY_RULE_SETUP
-#line 301 "../SqlLexer.lpp"
+#line 302 "../SqlLexer.lpp"
 return TOKEN_GT;
 	YY_BREAK
 case 135:
 YY_RULE_SETUP
-#line 302 "../SqlLexer.lpp"
+#line 303 "../SqlLexer.lpp"
 return TOKEN_LEQ;
 	YY_BREAK
 case 136:
 YY_RULE_SETUP
-#line 303 "../SqlLexer.lpp"
+#line 304 "../SqlLexer.lpp"
 return TOKEN_GEQ;
 	YY_BREAK
 case 137:
 YY_RULE_SETUP
-#line 304 "../SqlLexer.lpp"
+#line 305 "../SqlLexer.lpp"
 return TOKEN_DOUBLECOLON;
 	YY_BREAK
 case 138:
 YY_RULE_SETUP
 #line 306 "../SqlLexer.lpp"
-return yytext[0];
+return TOKEN_LBRACE;
 	YY_BREAK
 case 139:
 YY_RULE_SETUP
 #line 307 "../SqlLexer.lpp"
+return TOKEN_RBRACE;
+	YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 309 "../SqlLexer.lpp"
+return yytext[0];
+	YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 310 "../SqlLexer.lpp"
 return yytext[0];
 	YY_BREAK
 /**
     * Quoted strings. Prefacing a string with an 'e' or 'E' causes escape
     * sequences to be processed (as in PostgreSQL).
     **/
-case 140:
+case 142:
 YY_RULE_SETUP
-#line 313 "../SqlLexer.lpp"
+#line 316 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED_ESCAPED);
   }
 	YY_BREAK
-case 141:
+case 143:
 YY_RULE_SETUP
-#line 318 "../SqlLexer.lpp"
+#line 321 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_SINGLE_QUOTED);
   }
 	YY_BREAK
-case 142:
+case 144:
 YY_RULE_SETUP
-#line 323 "../SqlLexer.lpp"
+#line 326 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(yylloc->first_line, yylloc->first_column);
     BEGIN(CONDITION_STRING_DOUBLE_QUOTED);
@@ -2411,7 +2420,7 @@ YY_RULE_SETUP
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED):
 case YY_STATE_EOF(CONDITION_STRING_SINGLE_QUOTED_ESCAPED):
 case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
-#line 332 "../SqlLexer.lpp"
+#line 335 "../SqlLexer.lpp"
 {
     delete yylval->string_value_;
     BEGIN(INITIAL);
@@ -2422,9 +2431,9 @@ case YY_STATE_EOF(CONDITION_STRING_DOUBLE_QUOTED):
 
 /* Process escape sequences. */
 
-case 143:
+case 145:
 YY_RULE_SETUP
-#line 342 "../SqlLexer.lpp"
+#line 345 "../SqlLexer.lpp"
 {
     /* Octal code */
     unsigned int code;
@@ -2438,9 +2447,9 @@ YY_RULE_SETUP
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 144:
+case 146:
 YY_RULE_SETUP
-#line 354 "../SqlLexer.lpp"
+#line 357 "../SqlLexer.lpp"
 {
     /* Hexadecimal code */
     unsigned int code;
@@ -2448,9 +2457,9 @@ YY_RULE_SETUP
     yylval->string_value_->push_back(code);
   }
 	YY_BREAK
-case 145:
+case 147:
 YY_RULE_SETUP
-#line 360 "../SqlLexer.lpp"
+#line 363 "../SqlLexer.lpp"
 {
     /* A numeric escape sequence that isn't correctly specified. */
     delete yylval->string_value_;
@@ -2459,58 +2468,58 @@ YY_RULE_SETUP
     return TOKEN_LEX_ERROR;
   }
 	YY_BREAK
-case 146:
+case 148:
 YY_RULE_SETUP
-#line 367 "../SqlLexer.lpp"
+#line 370 "../SqlLexer.lpp"
 {
     /* Backspace */
     yylval->string_value_->push_back('\b');
   }
 	YY_BREAK
-case 147:
+case 149:
 YY_RULE_SETUP
-#line 371 "../SqlLexer.lpp"
+#line 374 "../SqlLexer.lpp"
 {
     /* Form-feed */
     yylval->string_value_->push_back('\f');
   }
 	YY_BREAK
-case 148:
+case 150:
 YY_RULE_SETUP
-#line 375 "../SqlLexer.lpp"
+#line 378 "../SqlLexer.lpp"
 {
     /* Newline */
     yylval->string_value_->push_back('\n');
   }
 	YY_BREAK
-case 149:
+case 151:
 YY_RULE_SETUP
-#line 379 "../SqlLexer.lpp"
+#line 382 "../SqlLexer.lpp"
 {
     /* Carriage-return */
     yylval->string_value_->push_back('\r');
   }
 	YY_BREAK
-case 150:
+case 152:
 YY_RULE_SETUP
-#line 383 "../SqlLexer.lpp"
+#line 386 "../SqlLexer.lpp"
 {
     /* Horizontal Tab */
     yylval->string_value_->push_back('\t');
   }
 	YY_BREAK
-case 151:
-/* rule 151 can match eol */
+case 153:
+/* rule 153 can match eol */
 YY_RULE_SETUP
-#line 387 "../SqlLexer.lpp"
+#line 390 "../SqlLexer.lpp"
 {
     /* Any other character (including actual newline or carriage return) */
     yylval->string_value_->push_back(yytext[1]);
   }
 	YY_BREAK
-case 152:
+case 154:
 YY_RULE_SETUP
-#line 391 "../SqlLexer.lpp"
+#line 394 "../SqlLexer.lpp"
 {
     /* This should only be encountered right before an EOF. */
     delete yylval->string_value_;
@@ -2521,17 +2530,17 @@ YY_RULE_SETUP
 	YY_BREAK
 
 
-case 153:
+case 155:
 YY_RULE_SETUP
-#line 401 "../SqlLexer.lpp"
+#line 404 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('\'');
   }
 	YY_BREAK
-case 154:
+case 156:
 YY_RULE_SETUP
-#line 405 "../SqlLexer.lpp"
+#line 408 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2540,17 +2549,17 @@ YY_RULE_SETUP
 	YY_BREAK
 
 
-case 155:
+case 157:
 YY_RULE_SETUP
-#line 413 "../SqlLexer.lpp"
+#line 416 "../SqlLexer.lpp"
 {
     /* Two quotes in a row become a single quote (this is specified by the SQL standard). */
     yylval->string_value_->push_back('"');
   }
 	YY_BREAK
-case 156:
+case 158:
 YY_RULE_SETUP
-#line 417 "../SqlLexer.lpp"
+#line 420 "../SqlLexer.lpp"
 {
     /* End string */
     BEGIN(CONDITION_SQL);
@@ -2558,94 +2567,94 @@ YY_RULE_SETUP
   }
 	YY_BREAK
 
-case 157:
-/* rule 157 can match eol */
+case 159:
+/* rule 159 can match eol */
 YY_RULE_SETUP
-#line 424 "../SqlLexer.lpp"
+#line 427 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 158:
-/* rule 158 can match eol */
+case 160:
+/* rule 160 can match eol */
 YY_RULE_SETUP
-#line 429 "../SqlLexer.lpp"
+#line 432 "../SqlLexer.lpp"
 {
   /* Scan up to a quote or escape sequence. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
-case 159:
-/* rule 159 can match eol */
+case 161:
+/* rule 161 can match eol */
 YY_RULE_SETUP
-#line 434 "../SqlLexer.lpp"
+#line 437 "../SqlLexer.lpp"
 {
   /* Scan up to a quote. */
   yylval->string_value_->append(yytext, yyleng);
 }
 	YY_BREAK
 
-case 160:
+case 162:
 YY_RULE_SETUP
-#line 440 "../SqlLexer.lpp"
+#line 443 "../SqlLexer.lpp"
 {
     yylval->string_value_ = new quickstep::ParseString(
         yylloc->first_line, yylloc->first_column, std::string(yytext, yyleng));
     return TOKEN_NAME;
   }
 	YY_BREAK
-case 161:
+case 163:
 YY_RULE_SETUP
-#line 446 "../SqlLexer.lpp"
+#line 449 "../SqlLexer.lpp"
 {
     yylval->numeric_literal_value_ = new quickstep::NumericParseLiteralValue(
         yylloc->first_line, yylloc->first_column, yytext);
     return TOKEN_UNSIGNED_NUMVAL;
   }
 	YY_BREAK
-case 162:
+case 164:
 YY_RULE_SETUP
-#line 452 "../SqlLexer.lpp"
+#line 455 "../SqlLexer.lpp"
 /* comment */
 	YY_BREAK
-case 163:
-/* rule 163 can match eol */
+case 165:
+/* rule 165 can match eol */
 YY_RULE_SETUP
-#line 454 "../SqlLexer.lpp"
+#line 457 "../SqlLexer.lpp"
 { yycolumn = 0; }
 	YY_BREAK
-case 164:
+case 166:
 YY_RULE_SETUP
-#line 456 "../SqlLexer.lpp"
+#line 459 "../SqlLexer.lpp"
 ; /* ignore white space */
 	YY_BREAK
 /* CONDITION_SQL */
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(CONDITION_COMMAND):
 case YY_STATE_EOF(CONDITION_SQL):
-#line 460 "../SqlLexer.lpp"
+#line 463 "../SqlLexer.lpp"
 {
   /* All conditions except for mutli-state string extracting conditions. */
   BEGIN(INITIAL);
   return TOKEN_EOF;
 }
 	YY_BREAK
-case 165:
+case 167:
 YY_RULE_SETUP
-#line 466 "../SqlLexer.lpp"
+#line 469 "../SqlLexer.lpp"
 {
   BEGIN(INITIAL);
   quickstep_yyerror(NULL, yyscanner, NULL, "illegal character");
   return TOKEN_LEX_ERROR;
 }
 	YY_BREAK
-case 166:
+case 168:
 YY_RULE_SETUP
-#line 472 "../SqlLexer.lpp"
+#line 475 "../SqlLexer.lpp"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 2648 "SqlLexer_gen.cpp"
+#line 2657 "SqlLexer_gen.cpp"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2943,7 +2952,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 592 )
+			if ( yy_current_state >= 594 )
 				yy_c = yy_meta[yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -2972,11 +2981,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 592 )
+		if ( yy_current_state >= 594 )
 			yy_c = yy_meta[yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-	yy_is_jam = (yy_current_state == 591);
+	yy_is_jam = (yy_current_state == 593);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -3806,6 +3815,6 @@ void yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 472 "../SqlLexer.lpp"
+#line 475 "../SqlLexer.lpp"
 
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1792b9f4/parser/preprocessed/SqlLexer_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlLexer_gen.hpp b/parser/preprocessed/SqlLexer_gen.hpp
index 9990de6..6d3c441 100644
--- a/parser/preprocessed/SqlLexer_gen.hpp
+++ b/parser/preprocessed/SqlLexer_gen.hpp
@@ -733,7 +733,7 @@ extern int yylex \
 #undef yyTABLES_NAME
 #endif
 
-#line 472 "../SqlLexer.lpp"
+#line 475 "../SqlLexer.lpp"
 
 
 #line 739 "SqlLexer_gen.hpp"



[18/38] incubator-quickstep git commit: Refactor type system and operations.

Posted by ji...@apache.org.
Refactor type system and operations.


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/9b23a4d3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/9b23a4d3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/9b23a4d3

Branch: refs/heads/refactor-type
Commit: 9b23a4d3b19f9981a26f607e88ce3247988e585b
Parents: 69fd94b
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Sat Mar 4 12:11:13 2017 -0600
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Tue Oct 10 13:24:03 2017 -0500

----------------------------------------------------------------------
 expressions/CMakeLists.txt                      |    4 +-
 expressions/ExpressionFactories.cpp             |   61 +-
 expressions/Expressions.proto                   |   12 +-
 .../aggregation/AggregateFunctionAvg.cpp        |   21 +-
 .../aggregation/AggregateFunctionSum.cpp        |    9 +-
 .../aggregation/AggregationHandleAvg.cpp        |   30 +-
 .../aggregation/AggregationHandleSum.cpp        |   15 +-
 expressions/aggregation/CMakeLists.txt          |   12 +-
 expressions/predicate/CMakeLists.txt            |    1 -
 expressions/scalar/CMakeLists.txt               |   16 +-
 expressions/scalar/ScalarBinaryExpression.cpp   |  101 +-
 expressions/scalar/ScalarBinaryExpression.hpp   |   31 +-
 expressions/scalar/ScalarUnaryExpression.cpp    |  100 +-
 expressions/scalar/ScalarUnaryExpression.hpp    |   27 +-
 expressions/window_aggregation/CMakeLists.txt   |    9 +-
 .../WindowAggregateFunctionAvg.cpp              |   17 +-
 .../WindowAggregateFunctionSum.cpp              |    8 +-
 .../WindowAggregationHandle.cpp                 |    8 +-
 .../WindowAggregationHandle.hpp                 |    2 -
 .../WindowAggregationHandleAvg.cpp              |   47 +-
 parser/CMakeLists.txt                           |    6 -
 parser/ParseBasicExpressions.cpp                |  103 -
 parser/ParseBasicExpressions.hpp                |  291 +-
 parser/ParseExpression.hpp                      |    3 -
 parser/SqlLexer.lpp                             |    1 +
 parser/SqlParser.ypp                            |   93 +-
 parser/preprocessed/SqlLexer_gen.cpp            | 1111 +++---
 parser/preprocessed/SqlLexer_gen.hpp            |    2 +-
 parser/preprocessed/SqlParser_gen.cpp           | 3410 +++++++++---------
 parser/preprocessed/SqlParser_gen.hpp           |  205 +-
 query_optimizer/LogicalGenerator.cpp            |    7 +-
 .../expressions/BinaryExpression.cpp            |   85 +-
 .../expressions/BinaryExpression.hpp            |   70 +-
 query_optimizer/expressions/CMakeLists.txt      |   23 +-
 query_optimizer/expressions/Cast.cpp            |   91 -
 query_optimizer/expressions/Cast.hpp            |  125 -
 query_optimizer/expressions/UnaryExpression.cpp |   51 +-
 query_optimizer/expressions/UnaryExpression.hpp |   43 +-
 query_optimizer/resolver/CMakeLists.txt         |    6 +-
 query_optimizer/resolver/Resolver.cpp           |  378 +-
 query_optimizer/resolver/Resolver.hpp           |    9 +-
 query_optimizer/rules/CMakeLists.txt            |    4 +-
 .../rules/ReuseAggregateExpressions.cpp         |   19 +-
 query_optimizer/rules/tests/CMakeLists.txt      |    2 -
 query_optimizer/strategy/tests/CMakeLists.txt   |    2 -
 query_optimizer/tests/CMakeLists.txt            |    2 -
 query_optimizer/tests/OptimizerTest.cpp         |    2 -
 relational_operators/CMakeLists.txt             |    2 -
 storage/CMakeLists.txt                          |    5 +-
 storage/PackedPayloadHashTable.cpp              |    4 +-
 storage/SMAIndexSubBlock.cpp                    |   10 +-
 types/AsciiStringSuperType.hpp                  |   78 +
 types/BoolType.cpp                              |   63 +
 types/BoolType.hpp                              |   73 +
 types/CMakeLists.txt                            |   89 +-
 types/CharType.cpp                              |   32 -
 types/CharType.hpp                              |   77 +-
 types/DateType.cpp                              |   19 -
 types/DateType.hpp                              |   67 +-
 types/DatetimeIntervalType.cpp                  |   19 -
 types/DatetimeIntervalType.hpp                  |   67 +-
 types/DatetimeLit.hpp                           |    4 +
 types/DatetimeType.cpp                          |   19 -
 types/DatetimeType.hpp                          |   68 +-
 types/DoubleType.cpp                            |   36 -
 types/DoubleType.hpp                            |   59 +-
 types/FloatType.cpp                             |   36 -
 types/FloatType.hpp                             |   59 +-
 types/IntType.cpp                               |   35 -
 types/IntType.hpp                               |   59 +-
 types/LongType.cpp                              |   36 -
 types/LongType.hpp                              |   59 +-
 types/NullCoercibilityCheckMacro.hpp            |    5 +-
 types/NullType.hpp                              |   49 +-
 types/NumericSuperType.hpp                      |   69 +-
 types/NumericTypeSafeCoercibility.hpp           |   61 +
 types/NumericTypeUnifier.hpp                    |  102 +-
 types/Type.cpp                                  |   68 +-
 types/Type.hpp                                  |   60 +-
 types/Type.proto                                |   36 +-
 types/TypeFactory.cpp                           |  133 +-
 types/TypeFactory.hpp                           |   20 +-
 types/TypeID.cpp                                |    1 +
 types/TypeID.hpp                                |   36 +-
 types/TypeIDSelectors.hpp                       |  152 +
 types/TypeRegistrar.hpp                         |  122 +
 types/TypeSynthesizer.hpp                       |  210 ++
 types/TypeUtil.hpp                              |   70 +
 types/TypedValue.cpp                            |   47 +-
 types/TypedValue.hpp                            |   48 +-
 types/TypedValue.proto                          |   21 +-
 types/VarCharType.cpp                           |   32 -
 types/VarCharType.hpp                           |   73 +-
 types/YearMonthIntervalType.cpp                 |   19 -
 types/YearMonthIntervalType.hpp                 |   67 +-
 types/containers/ColumnVector.cpp               |    4 +
 types/containers/ColumnVector.hpp               |   22 +-
 types/operations/CMakeLists.txt                 |   43 +
 types/operations/Operation.hpp                  |   26 +-
 types/operations/Operation.proto                |   59 +-
 types/operations/OperationFactory.cpp           |  357 ++
 types/operations/OperationFactory.hpp           |  203 ++
 types/operations/OperationSignature.cpp         |   91 +
 types/operations/OperationSignature.hpp         |  182 +
 types/operations/OperationUtil.hpp              |  334 ++
 .../binary_operations/AddBinaryOperation.cpp    |  418 ---
 .../ArithmeticBinaryFunctorOverloads.hpp        |  176 +
 .../ArithmeticBinaryOperation.hpp               |  404 ---
 .../ArithmeticBinaryOperations.hpp              |  182 +
 .../ArithmeticBinaryOperators.hpp               |  848 -----
 .../AsciiStringBinaryOperations.hpp             |  130 +
 .../binary_operations/BinaryOperation.cpp       |   29 -
 .../binary_operations/BinaryOperation.hpp       |  300 +-
 .../BinaryOperationFactory.cpp                  |   93 -
 .../BinaryOperationFactory.hpp                  |   79 -
 .../binary_operations/BinaryOperationID.cpp     |   40 -
 .../binary_operations/BinaryOperationID.hpp     |   62 -
 .../BinaryOperationWrapper.hpp                  |  629 ++++
 .../operations/binary_operations/CMakeLists.txt |  187 +-
 .../binary_operations/CMathBinaryOperations.hpp |   78 +
 .../binary_operations/DivideBinaryOperation.cpp |  391 --
 .../binary_operations/DivideBinaryOperation.hpp |   93 -
 .../binary_operations/ModuloBinaryOperation.cpp |  259 --
 .../binary_operations/ModuloBinaryOperation.hpp |   93 -
 .../MultiplyBinaryOperation.cpp                 |  410 ---
 .../SubtractBinaryOperation.cpp                 |  459 ---
 .../SubtractBinaryOperation.hpp                 |   93 -
 types/operations/comparisons/CMakeLists.txt     |    6 +-
 types/operations/comparisons/Comparison.hpp     |    6 +-
 types/operations/comparisons/ComparisonUtil.hpp |   30 +-
 .../comparisons/PatternMatchingComparison.cpp   |   18 +-
 .../ArithmeticUnaryOperations.cpp               |  145 -
 .../ArithmeticUnaryOperations.hpp               |   93 +-
 .../ArithmeticUnaryOperators.hpp                |  169 -
 .../AsciiStringUnaryOperations.hpp              |  122 +
 .../operations/unary_operations/CMakeLists.txt  |  141 +-
 .../unary_operations/CMathUnaryOperations.hpp   |  116 +
 .../unary_operations/CastOperation.cpp          |  298 ++
 .../unary_operations/CastOperation.hpp          |  154 +
 .../unary_operations/DateExtractOperation.cpp   |  596 +--
 .../unary_operations/DateExtractOperation.hpp   |  193 +-
 .../unary_operations/NumericCastOperation.hpp   |  313 --
 .../unary_operations/SubstringOperation.cpp     |  198 +-
 .../unary_operations/SubstringOperation.hpp     |  286 +-
 .../unary_operations/UnaryOperation.cpp         |   20 -
 .../unary_operations/UnaryOperation.hpp         |  180 +-
 .../unary_operations/UnaryOperationFactory.cpp  |  120 -
 .../unary_operations/UnaryOperationFactory.hpp  |   79 -
 .../unary_operations/UnaryOperationID.cpp       |   32 -
 .../unary_operations/UnaryOperationID.hpp       |   63 -
 .../unary_operations/UnaryOperationWrapper.hpp  |  250 ++
 utility/CMakeLists.txt                          |   12 +-
 utility/StringUtil.cpp                          |    6 +
 utility/StringUtil.hpp                          |   12 +-
 utility/TemplateUtil.hpp                        |  198 -
 utility/meta/CMakeLists.txt                     |   41 +
 utility/meta/Common.hpp                         |  143 +
 utility/meta/Dispatchers.hpp                    |  107 +
 utility/meta/TMP.hpp                            |   28 +
 utility/meta/TransitiveClosure.hpp              |   97 +
 utility/meta/TypeList.hpp                       |  124 +
 utility/meta/TypeListMetaFunctions.hpp          |  245 ++
 utility/tests/TemplateUtil_unittest.cpp         |  115 -
 163 files changed, 9138 insertions(+), 11643 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/expressions/CMakeLists.txt b/expressions/CMakeLists.txt
index 33606cd..3d2e156 100644
--- a/expressions/CMakeLists.txt
+++ b/expressions/CMakeLists.txt
@@ -56,9 +56,9 @@ target_link_libraries(quickstep_expressions_ExpressionFactories
                       quickstep_expressions_scalar_ScalarUnaryExpression
                       quickstep_types_TypeFactory
                       quickstep_types_TypedValue
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
+                      quickstep_types_operations_OperationFactory
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_comparisons_ComparisonFactory
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_Expressions_proto
                       quickstep_types_Type_proto

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/ExpressionFactories.cpp
----------------------------------------------------------------------
diff --git a/expressions/ExpressionFactories.cpp b/expressions/ExpressionFactories.cpp
index 871db50..f8913ba 100644
--- a/expressions/ExpressionFactories.cpp
+++ b/expressions/ExpressionFactories.cpp
@@ -43,9 +43,9 @@
 #include "expressions/scalar/ScalarUnaryExpression.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypedValue.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
+#include "types/operations/OperationFactory.hpp"
+#include "types/operations/OperationSignature.hpp"
 #include "types/operations/comparisons/ComparisonFactory.hpp"
-#include "types/operations/unary_operations/UnaryOperationFactory.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
@@ -168,17 +168,43 @@ Scalar* ScalarFactory::ReconstructFromProto(const serialization::Scalar &proto,
           proto.GetExtension(serialization::ScalarAttribute::attribute_id)));
     }
     case serialization::Scalar::UNARY_EXPRESSION: {
+      std::vector<TypedValue> static_arguments;
+      const int num_static_args =
+          proto.ExtensionSize(serialization::ScalarUnaryExpression::static_arguments);
+      for (int i = 0; i < num_static_args; ++i) {
+        static_arguments.emplace_back(
+            TypedValue::ReconstructFromProto(
+                proto.GetExtension(serialization::ScalarUnaryExpression::static_arguments, i)));
+      }
+      const OperationSignaturePtr op_signature =
+          OperationSignature::ReconstructFromProto(
+              proto.GetExtension(serialization::ScalarUnaryExpression::op_signature));
       return new ScalarUnaryExpression(
-          UnaryOperationFactory::ReconstructFromProto(
-              proto.GetExtension(serialization::ScalarUnaryExpression::operation)),
-          ReconstructFromProto(proto.GetExtension(serialization::ScalarUnaryExpression::operand), database));
+          op_signature,
+          OperationFactory::Instance().getUnaryOperation(op_signature),
+          ReconstructFromProto(proto.GetExtension(serialization::ScalarUnaryExpression::operand), database),
+          std::make_shared<std::vector<TypedValue>>(std::move(static_arguments)));
     }
     case serialization::Scalar::BINARY_EXPRESSION: {
+      std::vector<TypedValue> static_arguments;
+      const int num_static_args =
+          proto.ExtensionSize(serialization::ScalarBinaryExpression::static_arguments);
+      for (int i = 0; i < num_static_args; ++i) {
+        static_arguments.emplace_back(
+            TypedValue::ReconstructFromProto(
+                proto.GetExtension(serialization::ScalarBinaryExpression::static_arguments, i)));
+      }
+      const OperationSignaturePtr op_signature =
+          OperationSignature::ReconstructFromProto(
+              proto.GetExtension(serialization::ScalarBinaryExpression::op_signature));
       return new ScalarBinaryExpression(
-          BinaryOperationFactory::ReconstructFromProto(
-              proto.GetExtension(serialization::ScalarBinaryExpression::operation)),
-          ReconstructFromProto(proto.GetExtension(serialization::ScalarBinaryExpression::left_operand), database),
-          ReconstructFromProto(proto.GetExtension(serialization::ScalarBinaryExpression::right_operand), database));
+          op_signature,
+          OperationFactory::Instance().getBinaryOperation(op_signature),
+          ReconstructFromProto(
+              proto.GetExtension(serialization::ScalarBinaryExpression::left_operand), database),
+          ReconstructFromProto(
+              proto.GetExtension(serialization::ScalarBinaryExpression::right_operand), database),
+          std::make_shared<std::vector<TypedValue>>(std::move(static_arguments)));
     }
     case serialization::Scalar::CASE_EXPRESSION: {
       const Type &result_type = TypeFactory::ReconstructFromProto(
@@ -248,22 +274,13 @@ bool ScalarFactory::ProtoIsValid(const serialization::Scalar &proto,
       break;
     }
     case serialization::Scalar::UNARY_EXPRESSION: {
-      if (proto.HasExtension(serialization::ScalarUnaryExpression::operation)
-          && proto.HasExtension(serialization::ScalarUnaryExpression::operand)) {
-        return UnaryOperationFactory::ProtoIsValid(proto.GetExtension(serialization::ScalarUnaryExpression::operation))
-               && ProtoIsValid(proto.GetExtension(serialization::ScalarUnaryExpression::operand), database);
-      }
+      // TODO
+      return true;
       break;
     }
     case serialization::Scalar::BINARY_EXPRESSION: {
-      if (proto.HasExtension(serialization::ScalarBinaryExpression::operation)
-          && proto.HasExtension(serialization::ScalarBinaryExpression::left_operand)
-          && proto.HasExtension(serialization::ScalarBinaryExpression::right_operand)) {
-        return BinaryOperationFactory::ProtoIsValid(
-                   proto.GetExtension(serialization::ScalarBinaryExpression::operation))
-               && ProtoIsValid(proto.GetExtension(serialization::ScalarBinaryExpression::left_operand), database)
-               && ProtoIsValid(proto.GetExtension(serialization::ScalarBinaryExpression::right_operand), database);
-      }
+      // TODO
+      return true;
       break;
     }
     case serialization::Scalar::CASE_EXPRESSION: {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/Expressions.proto
----------------------------------------------------------------------
diff --git a/expressions/Expressions.proto b/expressions/Expressions.proto
index 8b4611e..3a9e673 100644
--- a/expressions/Expressions.proto
+++ b/expressions/Expressions.proto
@@ -103,16 +103,18 @@ message ScalarAttribute {
 
 message ScalarUnaryExpression {
   extend Scalar {
-    optional UnaryOperation operation = 96;
-    optional Scalar operand = 97;
+    optional OperationSignature op_signature = 97;
+    optional Scalar operand = 98;
+    repeated TypedValue static_arguments = 99;
   }
 }
 
 message ScalarBinaryExpression {
   extend Scalar {
-    optional BinaryOperation operation = 128;
-    optional Scalar left_operand = 129;
-    optional Scalar right_operand = 130;
+    optional OperationSignature op_signature = 129;
+    optional Scalar left_operand = 130;
+    optional Scalar right_operand = 131;
+    repeated TypedValue static_arguments = 132;
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/aggregation/AggregateFunctionAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionAvg.cpp b/expressions/aggregation/AggregateFunctionAvg.cpp
index 040d7d9..b2b99c7 100644
--- a/expressions/aggregation/AggregateFunctionAvg.cpp
+++ b/expressions/aggregation/AggregateFunctionAvg.cpp
@@ -25,9 +25,8 @@
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
+#include "types/operations/OperationFactory.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 
 #include "glog/logging.h"
 
@@ -41,10 +40,15 @@ bool AggregateFunctionAvg::canApplyToTypes(
   }
 
   // Argument must be addable and divisible.
-  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-             .canApplyToTypes(*argument_types.front(), *argument_types.front())
-         && BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
-             .canApplyToTypes(*argument_types.front(), TypeFactory::GetType(kDouble));
+  const Type &type = *argument_types.front();
+  if (!OperationFactory::Instance()
+          .getBinaryOperation("+", {type.getTypeID(), type.getTypeID()})
+              ->canApplyTo(type, type)) {
+    return false;
+  }
+  return OperationFactory::Instance()
+      .getBinaryOperation("/", {type.getTypeID(), kDouble})
+          ->canApplyTo(type, TypeFactory::GetType(kDouble));
 }
 
 const Type* AggregateFunctionAvg::resultTypeForArgumentTypes(
@@ -67,8 +71,9 @@ const Type* AggregateFunctionAvg::resultTypeForArgumentTypes(
       break;
   }
 
-  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
-             .resultTypeForArgumentTypes(*sum_type, TypeFactory::GetType(kDouble));
+  return OperationFactory::Instance()
+      .getBinaryOperation("/", {sum_type->getTypeID(), kDouble})
+          ->getResultType(*sum_type, TypeFactory::GetType(kDouble));
 }
 
 AggregationHandle* AggregateFunctionAvg::createHandle(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/aggregation/AggregateFunctionSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregateFunctionSum.cpp b/expressions/aggregation/AggregateFunctionSum.cpp
index b62660f..11b33c0 100644
--- a/expressions/aggregation/AggregateFunctionSum.cpp
+++ b/expressions/aggregation/AggregateFunctionSum.cpp
@@ -25,9 +25,8 @@
 #include "types/Type.hpp"
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
+#include "types/operations/OperationFactory.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 
 #include "glog/logging.h"
 
@@ -41,8 +40,10 @@ bool AggregateFunctionSum::canApplyToTypes(
   }
 
   // Argument must be addable.
-  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-             .canApplyToTypes(*argument_types.front(), *argument_types.front());
+  const Type &type = *argument_types.front();
+  return OperationFactory::Instance()
+      .getBinaryOperation("+", {type.getTypeID(), type.getTypeID()})
+          ->canApplyTo(type, type);
 }
 
 const Type* AggregateFunctionSum::resultTypeForArgumentTypes(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/aggregation/AggregationHandleAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleAvg.cpp b/expressions/aggregation/AggregationHandleAvg.cpp
index 46bec1e..1324fd8 100644
--- a/expressions/aggregation/AggregationHandleAvg.cpp
+++ b/expressions/aggregation/AggregationHandleAvg.cpp
@@ -32,9 +32,8 @@
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
+#include "types/operations/OperationFactory.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 
 #include "glog/logging.h"
 
@@ -68,25 +67,24 @@ AggregationHandleAvg::AggregationHandleAvg(const Type &type)
 
   // Make operators to do arithmetic:
   // Add operator for summing argument values.
-  fast_add_operator_.reset(
-      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-          .makeUncheckedBinaryOperatorForTypes(sum_type, argument_type_));
+  fast_add_operator_.reset(OperationFactory::Instance()
+      .getBinaryOperation("+", {type_precision_id, argument_type_.getTypeID()})
+          ->makeUncheckedBinaryOperator(sum_type, argument_type_));
   // Add operator for merging states.
-  merge_add_operator_.reset(
-      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-          .makeUncheckedBinaryOperatorForTypes(sum_type, sum_type));
+  merge_add_operator_.reset(OperationFactory::Instance()
+      .getBinaryOperation("+", {type_precision_id, type_precision_id})
+          ->makeUncheckedBinaryOperator(sum_type, sum_type));
   // Divide operator for dividing sum by count to get final average.
-  divide_operator_.reset(
-      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
-          .makeUncheckedBinaryOperatorForTypes(sum_type,
-                                               TypeFactory::GetType(kDouble)));
+  divide_operator_.reset(OperationFactory::Instance()
+      .getBinaryOperation("/", {type_precision_id, kDouble})
+          ->makeUncheckedBinaryOperator(sum_type, TypeFactory::GetType(kDouble)));
 
   // Result is nullable, because AVG() over 0 values (or all NULL values) is
   // NULL.
-  result_type_ =
-      &(BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
-            .resultTypeForArgumentTypes(sum_type, TypeFactory::GetType(kDouble))
-            ->getNullableVersion());
+  result_type_ = &OperationFactory::Instance()
+      .getBinaryOperation("/", {type_precision_id, kDouble})
+          ->getResultType(sum_type, TypeFactory::GetType(kDouble))
+              ->getNullableVersion();
 }
 
 AggregationState* AggregationHandleAvg::accumulateValueAccessor(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/aggregation/AggregationHandleSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/aggregation/AggregationHandleSum.cpp b/expressions/aggregation/AggregationHandleSum.cpp
index 9f5f220..c7ee776 100644
--- a/expressions/aggregation/AggregationHandleSum.cpp
+++ b/expressions/aggregation/AggregationHandleSum.cpp
@@ -32,9 +32,8 @@
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
+#include "types/operations/OperationFactory.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 
 #include "glog/logging.h"
 
@@ -67,13 +66,13 @@ AggregationHandleSum::AggregationHandleSum(const Type &type)
 
   // Make operators to do arithmetic:
   // Add operator for summing argument values.
-  fast_operator_.reset(
-      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-          .makeUncheckedBinaryOperatorForTypes(sum_type, argument_type_));
+  fast_operator_.reset(OperationFactory::Instance()
+      .getBinaryOperation("+", {type_precision_id, argument_type_.getTypeID()})
+          ->makeUncheckedBinaryOperator(sum_type, argument_type_));
   // Add operator for merging states.
-  merge_operator_.reset(
-      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-          .makeUncheckedBinaryOperatorForTypes(sum_type, sum_type));
+  merge_operator_.reset(OperationFactory::Instance()
+      .getBinaryOperation("+", {type_precision_id, type_precision_id})
+          ->makeUncheckedBinaryOperator(sum_type, sum_type));
 
   // Result is nullable, because SUM() over 0 values (or all NULL values) is
   // NULL.

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/aggregation/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/expressions/aggregation/CMakeLists.txt b/expressions/aggregation/CMakeLists.txt
index 4220a8d..29a58c6 100644
--- a/expressions/aggregation/CMakeLists.txt
+++ b/expressions/aggregation/CMakeLists.txt
@@ -84,9 +84,8 @@ target_link_libraries(quickstep_expressions_aggregation_AggregateFunctionAvg
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
+                      quickstep_types_operations_OperationFactory
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_aggregation_AggregateFunctionCount
                       glog
@@ -135,9 +134,8 @@ target_link_libraries(quickstep_expressions_aggregation_AggregateFunctionSum
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
+                      quickstep_types_operations_OperationFactory
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_aggregation_AggregationConcreteHandle
                       glog
@@ -170,9 +168,8 @@ target_link_libraries(quickstep_expressions_aggregation_AggregationHandleAvg
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
+                      quickstep_types_operations_OperationFactory
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_aggregation_AggregationHandleCount
                       glog
@@ -228,9 +225,8 @@ target_link_libraries(quickstep_expressions_aggregation_AggregationHandleSum
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
+                      quickstep_types_operations_OperationFactory
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Macros)
 
 # Submodule all-in-one library:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/predicate/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/expressions/predicate/CMakeLists.txt b/expressions/predicate/CMakeLists.txt
index 04abfc7..def0bc5 100644
--- a/expressions/predicate/CMakeLists.txt
+++ b/expressions/predicate/CMakeLists.txt
@@ -150,7 +150,6 @@ target_link_libraries(Predicate_unittest
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/scalar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/expressions/scalar/CMakeLists.txt b/expressions/scalar/CMakeLists.txt
index 6b52231..a59635b 100644
--- a/expressions/scalar/CMakeLists.txt
+++ b/expressions/scalar/CMakeLists.txt
@@ -68,9 +68,9 @@ target_link_libraries(quickstep_expressions_scalar_ScalarBinaryExpression
                       quickstep_types_TypeErrors
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVector
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_Operation_proto
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_scalar_ScalarCaseExpression
                       quickstep_catalog_CatalogTypedefs
@@ -118,9 +118,9 @@ target_link_libraries(quickstep_expressions_scalar_ScalarUnaryExpression
                       quickstep_types_TypeErrors
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVector
+                      quickstep_types_operations_OperationSignature
                       quickstep_types_operations_Operation_proto
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_utility_Macros)
 
 # Submodule all-in-one library:
@@ -161,12 +161,8 @@ target_link_libraries(ScalarCaseExpression_unittest
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVector
                       quickstep_types_containers_ColumnVectorsValueAccessor
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_ComparisonFactory
-                      quickstep_types_operations_comparisons_ComparisonID
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
-                      quickstep_types_operations_unaryoperations_UnaryOperationID)
+                      quickstep_types_operations_comparisons_ComparisonID)
 add_test(ScalarCaseExpression_unittest ScalarCaseExpression_unittest)
 
 add_executable(Scalar_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/Scalar_unittest.cpp")
@@ -189,11 +185,7 @@ target_link_libraries(Scalar_unittest
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
-                      quickstep_types_operations_unaryoperations_NumericCastOperation
+                      quickstep_types_operations_unaryoperations_CastOperation
                       quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_utility_Macros)
 add_test(Scalar_unittest Scalar_unittest)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/scalar/ScalarBinaryExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarBinaryExpression.cpp b/expressions/scalar/ScalarBinaryExpression.cpp
index b3568f8..2f0a0d4 100644
--- a/expressions/scalar/ScalarBinaryExpression.cpp
+++ b/expressions/scalar/ScalarBinaryExpression.cpp
@@ -34,43 +34,71 @@
 #include "types/containers/ColumnVector.hpp"
 #include "types/operations/Operation.pb.h"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 
 #include "glog/logging.h"
 
 namespace quickstep {
 
-ScalarBinaryExpression::ScalarBinaryExpression(const BinaryOperation &operation,
-                                               Scalar *left_operand,
-                                               Scalar *right_operand)
-    : Scalar(*operation.resultTypeForArgumentTypes(left_operand->getType(),
-                                                   right_operand->getType())),
+ScalarBinaryExpression::ScalarBinaryExpression(
+    const OperationSignaturePtr &op_signature,
+    const BinaryOperationPtr &operation,
+    Scalar *left_operand,
+    Scalar *right_operand,
+    const std::shared_ptr<const std::vector<TypedValue>> &static_arguments)
+    : Scalar(*operation->getResultType(left_operand->getType(),
+                                       right_operand->getType(),
+                                       *static_arguments)),
+      op_signature_(op_signature),
       operation_(operation),
       left_operand_(left_operand),
-      right_operand_(right_operand) {
-  initHelper(false);
+      right_operand_(right_operand),
+      static_arguments_(static_arguments) {
+  DCHECK(operation_->canApplyTo(left_operand_->getType(),
+                                right_operand_->getType(),
+                                *static_arguments));
+  fast_operator_.reset(
+      operation_->makeUncheckedBinaryOperator(left_operand_->getType(),
+                                              right_operand_->getType(),
+                                              *static_arguments));
+  if (left_operand_->hasStaticValue() && right_operand_->hasStaticValue()) {
+    static_value_.reset(new TypedValue(
+        fast_operator_->applyToTypedValues(left_operand_->getStaticValue(),
+                                           right_operand_->getStaticValue())));
+  }
 }
 
 serialization::Scalar ScalarBinaryExpression::getProto() const {
   serialization::Scalar proto;
   proto.set_data_source(serialization::Scalar::BINARY_EXPRESSION);
-  proto.MutableExtension(serialization::ScalarBinaryExpression::operation)->CopyFrom(operation_.getProto());
-  proto.MutableExtension(serialization::ScalarBinaryExpression::left_operand)->CopyFrom(left_operand_->getProto());
-  proto.MutableExtension(serialization::ScalarBinaryExpression::right_operand)->CopyFrom(right_operand_->getProto());
-
+  proto.MutableExtension(
+      serialization::ScalarBinaryExpression::op_signature)->CopyFrom(
+          op_signature_->getProto());
+  proto.MutableExtension(
+      serialization::ScalarBinaryExpression::left_operand)->CopyFrom(
+          left_operand_->getProto());
+  proto.MutableExtension(
+      serialization::ScalarBinaryExpression::right_operand)->CopyFrom(
+          right_operand_->getProto());
+  for (const TypedValue &value : *static_arguments_) {
+    proto.AddExtension(
+        serialization::ScalarUnaryExpression::static_arguments)->CopyFrom(
+            value.getProto());
+  }
   return proto;
 }
 
 Scalar* ScalarBinaryExpression::clone() const {
-  return new ScalarBinaryExpression(operation_,
+  return new ScalarBinaryExpression(op_signature_,
+                                    operation_,
                                     left_operand_->clone(),
-                                    right_operand_->clone());
+                                    right_operand_->clone(),
+                                    static_arguments_);
 }
 
 TypedValue ScalarBinaryExpression::getValueForSingleTuple(const ValueAccessor &accessor,
                                                           const tuple_id tuple) const {
   if (fast_operator_.get() == nullptr) {
-    return static_value_.makeReferenceToThis();
+    return static_value_->makeReferenceToThis();
   } else {
     return fast_operator_->applyToTypedValues(left_operand_->getValueForSingleTuple(accessor, tuple),
                                               right_operand_->getValueForSingleTuple(accessor, tuple));
@@ -85,7 +113,7 @@ TypedValue ScalarBinaryExpression::getValueForJoinedTuples(
     const relation_id right_relation_id,
     const tuple_id right_tuple_id) const {
   if (fast_operator_.get() == nullptr) {
-    return static_value_.makeReferenceToThis();
+    return static_value_->makeReferenceToThis();
   } else {
     return fast_operator_->applyToTypedValues(
         left_operand_->getValueForJoinedTuples(left_accessor,
@@ -110,7 +138,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValues(
   if (fast_operator_.get() == nullptr) {
     return ColumnVectorPtr(
         ColumnVector::MakeVectorOfValue(getType(),
-                                        static_value_,
+                                        *static_value_,
                                         accessor->getNumTuplesVirtual()));
   } else {
     // NOTE(chasseur): We don't check if BOTH operands have a static value,
@@ -208,7 +236,7 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin(
   if (fast_operator_.get() == nullptr) {
     return ColumnVectorPtr(
         ColumnVector::MakeVectorOfValue(getType(),
-                                        static_value_,
+                                        *static_value_,
                                         joined_tuple_ids.size()));
   } else {
     if (left_operand_->hasStaticValue()) {
@@ -380,31 +408,6 @@ ColumnVectorPtr ScalarBinaryExpression::getAllValuesForJoin(
   }
 }
 
-void ScalarBinaryExpression::initHelper(bool own_children) {
-  if (operation_.canApplyToTypes(left_operand_->getType(), right_operand_->getType())) {
-    if (left_operand_->hasStaticValue() && right_operand_->hasStaticValue()) {
-      static_value_ = operation_.applyToChecked(left_operand_->getStaticValue(),
-                                                left_operand_->getType(),
-                                                right_operand_->getStaticValue(),
-                                                right_operand_->getType());
-    } else {
-      fast_operator_.reset(operation_.makeUncheckedBinaryOperatorForTypes(left_operand_->getType(),
-                                                                           right_operand_->getType()));
-    }
-  } else {
-    const Type &left_operand_type = left_operand_->getType();
-    const Type &right_operand_type = right_operand_->getType();
-    if (!own_children) {
-      left_operand_.release();
-      right_operand_.release();
-    }
-    throw OperationInapplicableToType(operation_.getName(),
-                                      2,
-                                      left_operand_type.getName().c_str(),
-                                      right_operand_type.getName().c_str());
-  }
-}
-
 void ScalarBinaryExpression::getFieldStringItems(
     std::vector<std::string> *inline_field_names,
     std::vector<std::string> *inline_field_values,
@@ -419,19 +422,17 @@ void ScalarBinaryExpression::getFieldStringItems(
                               container_child_field_names,
                               container_child_fields);
 
-  if (fast_operator_ == nullptr) {
+  if (static_value_ != nullptr) {
     inline_field_names->emplace_back("static_value");
-    if (static_value_.isNull()) {
+    if (static_value_->isNull()) {
       inline_field_values->emplace_back("NULL");
     } else {
-      inline_field_values->emplace_back(type_.printValueToString(static_value_));
+      inline_field_values->emplace_back(type_.printValueToString(*static_value_));
     }
   }
 
-  inline_field_names->emplace_back("operation");
-  inline_field_values->emplace_back(
-      kBinaryOperationNames[static_cast<std::underlying_type<BinaryOperationID>::type>(
-          operation_.getBinaryOperationID())]);
+  inline_field_names->emplace_back("op_signature");
+  inline_field_values->emplace_back(op_signature_->toString());
 
   non_container_child_field_names->emplace_back("left_operand");
   non_container_child_fields->emplace_back(left_operand_.get());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/scalar/ScalarBinaryExpression.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarBinaryExpression.hpp b/expressions/scalar/ScalarBinaryExpression.hpp
index 4ac1f62..a27c820 100644
--- a/expressions/scalar/ScalarBinaryExpression.hpp
+++ b/expressions/scalar/ScalarBinaryExpression.hpp
@@ -31,6 +31,7 @@
 #include "storage/StorageBlockInfo.hpp"
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVector.hpp"
+#include "types/operations/OperationSignature.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
 #include "utility/Macros.hpp"
 
@@ -52,18 +53,11 @@ struct SubBlocksReference;
  **/
 class ScalarBinaryExpression : public Scalar {
  public:
-  /**
-   * @brief Constructor.
-   *
-   * @param operation The binary operation to be performed.
-   * @param left_operand The left argument of the operation, which this
-   *        ScalarBinaryExpression takes ownership of.
-   * @param right_operand The right argument of the operation, which this
-   *        ScalarBinaryExpression takes ownership of.
-   **/
-  ScalarBinaryExpression(const BinaryOperation &operation,
+  ScalarBinaryExpression(const OperationSignaturePtr &op_signature,
+                         const BinaryOperationPtr &operation,
                          Scalar *left_operand,
-                         Scalar *right_operand);
+                         Scalar *right_operand,
+                         const std::shared_ptr<const std::vector<TypedValue>> &static_arguments);
 
   /**
    * @brief Destructor
@@ -91,12 +85,12 @@ class ScalarBinaryExpression : public Scalar {
       const tuple_id right_tuple_id) const override;
 
   bool hasStaticValue() const override {
-    return fast_operator_.get() == nullptr;
+    return static_value_ != nullptr;
   }
 
   const TypedValue& getStaticValue() const override {
     DCHECK(hasStaticValue());
-    return static_value_;
+    return *static_value_;
   }
 
   ColumnVectorPtr getAllValues(ValueAccessor *accessor,
@@ -121,13 +115,14 @@ class ScalarBinaryExpression : public Scalar {
       std::vector<std::vector<const Expression*>> *container_child_fields) const override;
 
  private:
-  void initHelper(bool own_children);
+  const OperationSignaturePtr op_signature_;
+  const BinaryOperationPtr operation_;
 
-  const BinaryOperation &operation_;
+  const std::unique_ptr<Scalar> left_operand_;
+  const std::unique_ptr<Scalar> right_operand_;
+  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_;
 
-  std::unique_ptr<Scalar> left_operand_;
-  std::unique_ptr<Scalar> right_operand_;
-  TypedValue static_value_;
+  std::unique_ptr<TypedValue> static_value_;
   std::unique_ptr<UncheckedBinaryOperator> fast_operator_;
 
   friend class PredicateTest;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/scalar/ScalarUnaryExpression.cpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarUnaryExpression.cpp b/expressions/scalar/ScalarUnaryExpression.cpp
index c51e38f..c2fd931 100644
--- a/expressions/scalar/ScalarUnaryExpression.cpp
+++ b/expressions/scalar/ScalarUnaryExpression.cpp
@@ -34,41 +34,62 @@
 #include "types/containers/ColumnVector.hpp"
 #include "types/operations/Operation.pb.h"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
-#include "types/operations/unary_operations/UnaryOperationID.hpp"
 
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
 #include "glog/logging.h"
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
 
 namespace quickstep {
 
 struct SubBlocksReference;
 
-ScalarUnaryExpression::ScalarUnaryExpression(const UnaryOperation &operation,
-                                             Scalar *operand)
-    : Scalar(*operation.resultTypeForArgumentType(operand->getType())),
+ScalarUnaryExpression::ScalarUnaryExpression(
+    const OperationSignaturePtr &op_signature,
+    const UnaryOperationPtr &operation,
+    Scalar *operand,
+    const std::shared_ptr<const std::vector<TypedValue>> &static_arguments)
+    : Scalar(*operation->getResultType(operand->getType(), *static_arguments)),
+      op_signature_(op_signature),
       operation_(operation),
-      operand_(operand) {
-  initHelper(false);
+      operand_(operand),
+      static_arguments_(static_arguments) {
+  DCHECK(operation_->canApplyTo(operand_->getType(), *static_arguments_));
+
+  fast_operator_.reset(
+      operation_->makeUncheckedUnaryOperator(operand_->getType(),
+                                             *static_arguments_));
+  if (operand_->hasStaticValue()) {
+    static_value_.reset(new TypedValue(
+        fast_operator_->applyToTypedValue(operand_->getStaticValue())));
+  }
 }
 
 serialization::Scalar ScalarUnaryExpression::getProto() const {
   serialization::Scalar proto;
   proto.set_data_source(serialization::Scalar::UNARY_EXPRESSION);
-  proto.MutableExtension(serialization::ScalarUnaryExpression::operation)->CopyFrom(operation_.getProto());
-  proto.MutableExtension(serialization::ScalarUnaryExpression::operand)->CopyFrom(operand_->getProto());
-
+  proto.MutableExtension(
+      serialization::ScalarUnaryExpression::op_signature)->CopyFrom(
+          op_signature_->getProto());
+  proto.MutableExtension(
+      serialization::ScalarUnaryExpression::operand)->CopyFrom(
+          operand_->getProto());
+  for (const TypedValue &value : *static_arguments_) {
+    proto.AddExtension(
+        serialization::ScalarUnaryExpression::static_arguments)->CopyFrom(
+            value.getProto());
+  }
   return proto;
 }
 
 Scalar* ScalarUnaryExpression::clone() const {
-  return new ScalarUnaryExpression(operation_, operand_->clone());
+  return new ScalarUnaryExpression(op_signature_,
+                                   operation_,
+                                   operand_->clone(),
+                                   static_arguments_);
 }
 
 TypedValue ScalarUnaryExpression::getValueForSingleTuple(const ValueAccessor &accessor,
                                                          const tuple_id tuple) const {
   if (fast_operator_.get() == nullptr) {
-    return static_value_.makeReferenceToThis();
+    return static_value_->makeReferenceToThis();
   } else {
     return fast_operator_->applyToTypedValue(operand_->getValueForSingleTuple(accessor, tuple));
   }
@@ -82,7 +103,7 @@ TypedValue ScalarUnaryExpression::getValueForJoinedTuples(
     const relation_id right_relation_id,
     const tuple_id right_tuple_id) const {
   if (fast_operator_.get() == nullptr) {
-    return static_value_.makeReferenceToThis();
+    return static_value_->makeReferenceToThis();
   } else {
     return fast_operator_->applyToTypedValue(operand_->getValueForJoinedTuples(left_accessor,
                                                                                left_relation_id,
@@ -100,7 +121,7 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValues(
   if (fast_operator_.get() == nullptr) {
     return ColumnVectorPtr(
         ColumnVector::MakeVectorOfValue(getType(),
-                                        static_value_,
+                                        *static_value_,
                                         accessor->getNumTuplesVirtual()));
   } else {
 #ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
@@ -128,27 +149,9 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValuesForJoin(
   if (fast_operator_.get() == nullptr) {
     return ColumnVectorPtr(
         ColumnVector::MakeVectorOfValue(getType(),
-                                        static_value_,
+                                        *static_value_,
                                         joined_tuple_ids.size()));
   } else {
-#ifdef QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-    const attribute_id operand_attr_id = operand_->getAttributeIdForValueAccessor();
-    if (operand_attr_id != -1) {
-      const relation_id operand_relation_id = operand_->getRelationIdForValueAccessor();
-      DCHECK_NE(operand_relation_id, -1);
-      DCHECK((operand_relation_id == left_relation_id)
-             || (operand_relation_id == right_relation_id));
-      const bool using_left_relation = (operand_relation_id == left_relation_id);
-      ValueAccessor *operand_accessor = using_left_relation ? left_accessor
-                                                            : right_accessor;
-      return ColumnVectorPtr(
-          fast_operator_->applyToValueAccessorForJoin(operand_accessor,
-                                                      using_left_relation,
-                                                      operand_attr_id,
-                                                      joined_tuple_ids));
-    }
-#endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_JOIN
-
     ColumnVectorPtr operand_result(
         operand_->getAllValuesForJoin(left_relation_id,
                                       left_accessor,
@@ -161,23 +164,6 @@ ColumnVectorPtr ScalarUnaryExpression::getAllValuesForJoin(
   }
 }
 
-void ScalarUnaryExpression::initHelper(bool own_children) {
-  if (operation_.canApplyToType(operand_->getType())) {
-    if (operand_->hasStaticValue()) {
-      static_value_ = operation_.applyToChecked(operand_->getStaticValue(),
-                                                operand_->getType());
-    } else {
-      fast_operator_.reset(operation_.makeUncheckedUnaryOperatorForType(operand_->getType()));
-    }
-  } else {
-    const Type &operand_type = operand_->getType();
-    if (!own_children) {
-      operand_.release();
-    }
-    throw OperationInapplicableToType(operation_.getName(), 1, operand_type.getName().c_str());
-  }
-}
-
 void ScalarUnaryExpression::getFieldStringItems(
     std::vector<std::string> *inline_field_names,
     std::vector<std::string> *inline_field_values,
@@ -192,19 +178,17 @@ void ScalarUnaryExpression::getFieldStringItems(
                               container_child_field_names,
                               container_child_fields);
 
-  if (fast_operator_ == nullptr) {
+  if (static_value_ != nullptr) {
     inline_field_names->emplace_back("static_value");
-    if (static_value_.isNull()) {
+    if (static_value_->isNull()) {
       inline_field_values->emplace_back("NULL");
     } else {
-      inline_field_values->emplace_back(type_.printValueToString(static_value_));
+      inline_field_values->emplace_back(type_.printValueToString(*static_value_));
     }
   }
 
-  inline_field_names->emplace_back("operation");
-  inline_field_values->emplace_back(
-      kUnaryOperationNames[static_cast<std::underlying_type<UnaryOperationID>::type>(
-          operation_.getUnaryOperationID())]);
+  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_.get());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/scalar/ScalarUnaryExpression.hpp
----------------------------------------------------------------------
diff --git a/expressions/scalar/ScalarUnaryExpression.hpp b/expressions/scalar/ScalarUnaryExpression.hpp
index 52edea7..8dc4c30 100644
--- a/expressions/scalar/ScalarUnaryExpression.hpp
+++ b/expressions/scalar/ScalarUnaryExpression.hpp
@@ -30,6 +30,8 @@
 #include "expressions/scalar/Scalar.hpp"
 #include "storage/StorageBlockInfo.hpp"
 #include "types/TypedValue.hpp"
+#include "types/containers/ColumnVector.hpp"
+#include "types/operations/OperationSignature.hpp"
 #include "types/operations/unary_operations/UnaryOperation.hpp"
 #include "utility/Macros.hpp"
 
@@ -51,14 +53,10 @@ struct SubBlocksReference;
  **/
 class ScalarUnaryExpression : public Scalar {
  public:
-  /**
-   * @brief Constructor.
-   *
-   * @param operation The unary operation to be performed.
-   * @param operand The argument of the operation, which this
-   *        ScalarUnaryExpression takes ownership of.
-   **/
-  ScalarUnaryExpression(const UnaryOperation &operation, Scalar *operand);
+  ScalarUnaryExpression(const OperationSignaturePtr &op_signature,
+                        const UnaryOperationPtr &operation,
+                        Scalar *operand,
+                        const std::shared_ptr<const std::vector<TypedValue>> &static_arguments);
 
   /**
    * @brief Destructor.
@@ -86,12 +84,12 @@ class ScalarUnaryExpression : public Scalar {
       const tuple_id right_tuple_id) const override;
 
   bool hasStaticValue() const override {
-    return fast_operator_.get() == nullptr;
+    return static_value_ != nullptr;
   }
 
   const TypedValue& getStaticValue() const override {
     DCHECK(hasStaticValue());
-    return static_value_;
+    return *static_value_;
   }
 
   ColumnVectorPtr getAllValues(ValueAccessor *accessor,
@@ -116,12 +114,13 @@ class ScalarUnaryExpression : public Scalar {
       std::vector<std::vector<const Expression*>> *container_child_fields) const override;
 
  private:
-  void initHelper(bool own_children);
+  const OperationSignaturePtr op_signature_;
+  const UnaryOperationPtr operation_;
 
-  const UnaryOperation &operation_;
+  const std::unique_ptr<Scalar> operand_;
+  const std::shared_ptr<const std::vector<TypedValue>> static_arguments_;
 
-  std::unique_ptr<Scalar> operand_;
-  TypedValue static_value_;
+  std::unique_ptr<TypedValue> static_value_;
   std::unique_ptr<UncheckedUnaryOperator> fast_operator_;
 
   friend class PredicateTest;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/window_aggregation/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/CMakeLists.txt b/expressions/window_aggregation/CMakeLists.txt
index b33a401..1b5b743 100644
--- a/expressions/window_aggregation/CMakeLists.txt
+++ b/expressions/window_aggregation/CMakeLists.txt
@@ -72,8 +72,6 @@ target_link_libraries(quickstep_expressions_windowaggregation_WindowAggregateFun
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_windowaggregation_WindowAggregateFunctionCount
                       glog
@@ -123,8 +121,6 @@ target_link_libraries(quickstep_expressions_windowaggregation_WindowAggregateFun
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_expressions_windowaggregation_WindowAggregationHandle
                       glog
@@ -138,9 +134,8 @@ target_link_libraries(quickstep_expressions_windowaggregation_WindowAggregationH
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVector
                       quickstep_types_containers_ColumnVectorsValueAccessor
+                      quickstep_types_operations_OperationFactory
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID
@@ -156,8 +151,6 @@ target_link_libraries(quickstep_expressions_windowaggregation_WindowAggregationH
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVectorsValueAccessor
                       quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_utility_Macros)
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp b/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
index 20c296b..a70a8bc 100644
--- a/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
+++ b/expressions/window_aggregation/WindowAggregateFunctionAvg.cpp
@@ -26,8 +26,6 @@
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 
 #include "glog/logging.h"
 
@@ -41,10 +39,11 @@ bool WindowAggregateFunctionAvg::canApplyToTypes(
   }
 
   // Argument must be addable and divisible.
-  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-             .canApplyToTypes(*argument_types.front(), *argument_types.front()) &&
-         BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
-             .canApplyToTypes(*argument_types.front(), TypeFactory::GetType(kDouble));
+//  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
+//             .canApplyTo(*argument_types.front(), *argument_types.front()) &&
+//         BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
+//             .canApplyTo(*argument_types.front(), TypeFactory::GetType(kDouble));
+  return false;
 }
 
 const Type* WindowAggregateFunctionAvg::resultTypeForArgumentTypes(
@@ -67,8 +66,10 @@ const Type* WindowAggregateFunctionAvg::resultTypeForArgumentTypes(
       break;
   }
 
-  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
-             .resultTypeForArgumentTypes(*sum_type, TypeFactory::GetType(kDouble));
+// TODO
+//  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
+//             .getResultType(*sum_type, TypeFactory::GetType(kDouble));
+  return nullptr;
 }
 
 WindowAggregationHandle* WindowAggregateFunctionAvg::createHandle(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregateFunctionSum.cpp b/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
index 14c51d8..e383c63 100644
--- a/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
+++ b/expressions/window_aggregation/WindowAggregateFunctionSum.cpp
@@ -26,8 +26,6 @@
 #include "types/TypeFactory.hpp"
 #include "types/TypeID.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 
 #include "glog/logging.h"
 
@@ -41,8 +39,10 @@ bool WindowAggregateFunctionSum::canApplyToTypes(
   }
 
   // Argument must be addable.
-  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-             .canApplyToTypes(*argument_types.front(), *argument_types.front());
+// TODO
+//  return BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
+//             .canApplyTo(*argument_types.front(), *argument_types.front());
+  return false;
 }
 
 const Type* WindowAggregateFunctionSum::resultTypeForArgumentTypes(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/window_aggregation/WindowAggregationHandle.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregationHandle.cpp b/expressions/window_aggregation/WindowAggregationHandle.cpp
index f26656d..7621726 100644
--- a/expressions/window_aggregation/WindowAggregationHandle.cpp
+++ b/expressions/window_aggregation/WindowAggregationHandle.cpp
@@ -30,9 +30,8 @@
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVectorsValueAccessor.hpp"
+#include "types/operations/OperationFactory.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "types/operations/comparisons/Comparison.hpp"
 
 #include "glog/logging.h"
@@ -83,8 +82,9 @@ WindowAggregationHandle::WindowAggregationHandle(
         TypeFactory::GetUnifyingType(*first_order_key_type, long_type);
 
     range_add_operator_.reset(
-        BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-            .makeUncheckedBinaryOperatorForTypes(*first_order_key_type, long_type));
+        OperationFactory::Instance().getBinaryOperation(
+            "+", {first_order_key_type->getTypeID(), kLong}, 0)
+                ->makeUncheckedBinaryOperator(*first_order_key_type, long_type));
     range_comparator_.reset(
         ComparisonFactory::GetComparison(ComparisonID::kLessOrEqual)
             .makeUncheckedComparatorForTypes(*range_compare_type_, *range_compare_type_));

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/window_aggregation/WindowAggregationHandle.hpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregationHandle.hpp b/expressions/window_aggregation/WindowAggregationHandle.hpp
index 3569123..0d5f5ca 100644
--- a/expressions/window_aggregation/WindowAggregationHandle.hpp
+++ b/expressions/window_aggregation/WindowAggregationHandle.hpp
@@ -37,8 +37,6 @@
 #include "types/operations/comparisons/ComparisonFactory.hpp"
 #include "types/operations/comparisons/ComparisonID.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
----------------------------------------------------------------------
diff --git a/expressions/window_aggregation/WindowAggregationHandleAvg.cpp b/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
index b1c6e3b..3539d03 100644
--- a/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
+++ b/expressions/window_aggregation/WindowAggregationHandleAvg.cpp
@@ -32,8 +32,6 @@
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVectorsValueAccessor.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
-#include "types/operations/binary_operations/BinaryOperationFactory.hpp"
-#include "types/operations/binary_operations/BinaryOperationID.hpp"
 #include "types/operations/comparisons/Comparison.hpp"
 
 #include "glog/logging.h"
@@ -71,28 +69,29 @@ WindowAggregationHandleAvg::WindowAggregationHandleAvg(
 
   sum_type_ = &(TypeFactory::GetType(type_id));
 
-  // Result is nullable, because AVG() over 0 values (or all NULL values) is
-  // NULL.
-  result_type_
-      = &(BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
-              .resultTypeForArgumentTypes(*sum_type_, TypeFactory::GetType(kDouble))
-                  ->getNullableVersion());
-
-  // Make operators to do arithmetic:
-  // Add operator for summing argument values.
-  fast_add_operator_.reset(
-      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
-          .makeUncheckedBinaryOperatorForTypes(*sum_type_, *argument_type));
-
-  // Subtract operator for dropping argument values off the window.
-  fast_subtract_operator_.reset(
-      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kSubtract)
-          .makeUncheckedBinaryOperatorForTypes(*sum_type_, *argument_type));
-
-  // Divide operator for dividing sum by count to get final average.
-  divide_operator_.reset(
-      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
-          .makeUncheckedBinaryOperatorForTypes(*sum_type_, TypeFactory::GetType(kDouble)));
+// TODO
+//  // Result is nullable, because AVG() over 0 values (or all NULL values) is
+//  // NULL.
+//  result_type_
+//      = &(BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
+//              .getResultType(*sum_type_, TypeFactory::GetType(kDouble))
+//                  ->getNullableVersion());
+//
+//  // Make operators to do arithmetic:
+//  // Add operator for summing argument values.
+//  fast_add_operator_.reset(
+//      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd)
+//          .makeUncheckedBinaryOperator(*sum_type_, *argument_type));
+//
+//  // Subtract operator for dropping argument values off the window.
+//  fast_subtract_operator_.reset(
+//      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kSubtract)
+//          .makeUncheckedBinaryOperator(*sum_type_, *argument_type));
+//
+//  // Divide operator for dividing sum by count to get final average.
+//  divide_operator_.reset(
+//      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kDivide)
+//          .makeUncheckedBinaryOperator(*sum_type_, TypeFactory::GetType(kDouble)));
 }
 
 ColumnVector* WindowAggregationHandleAvg::calculate(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/parser/CMakeLists.txt b/parser/CMakeLists.txt
index b3ddf30..fb7a3cd 100644
--- a/parser/CMakeLists.txt
+++ b/parser/CMakeLists.txt
@@ -366,15 +366,9 @@ target_link_libraries(quickstep_parser_SqlParser
                       quickstep_types_Type
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
-                      quickstep_types_operations_binaryoperations_BinaryOperation
-                      quickstep_types_operations_binaryoperations_BinaryOperationFactory
-                      quickstep_types_operations_binaryoperations_BinaryOperationID
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonFactory
                       quickstep_types_operations_comparisons_ComparisonID
-                      quickstep_types_operations_unaryoperations_UnaryOperation
-                      quickstep_types_operations_unaryoperations_UnaryOperationFactory
-                      quickstep_types_operations_unaryoperations_UnaryOperationID
                       quickstep_utility_PtrList
                       quickstep_utility_PtrVector)
 target_link_libraries(quickstep_parser_SqlParserWrapper

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/ParseBasicExpressions.cpp
----------------------------------------------------------------------
diff --git a/parser/ParseBasicExpressions.cpp b/parser/ParseBasicExpressions.cpp
index b0b1247..580cd09 100644
--- a/parser/ParseBasicExpressions.cpp
+++ b/parser/ParseBasicExpressions.cpp
@@ -68,54 +68,6 @@ void ParseAttribute::getFieldStringItems(
   }
 }
 
-std::string ParseUnaryExpression::getName() const {
-  return op_.getName();
-}
-
-string ParseUnaryExpression::generateName() const {
-  string name(op_.getShortName());
-  name.append(operand_->generateName());
-  return name;
-}
-
-void ParseUnaryExpression::getFieldStringItems(
-    std::vector<std::string> *inline_field_names,
-    std::vector<std::string> *inline_field_values,
-    std::vector<std::string> *non_container_child_field_names,
-    std::vector<const ParseTreeNode*> *non_container_child_fields,
-    std::vector<std::string> *container_child_field_names,
-    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
-  non_container_child_field_names->push_back("");
-  non_container_child_fields->push_back(operand_.get());
-}
-
-std::string ParseBinaryExpression::getName() const {
-  return op_.getName();
-}
-
-string ParseBinaryExpression::generateName() const {
-  string name("(");
-  name.append(left_operand_->generateName());
-  name.append(op_.getShortName());
-  name.append(right_operand_->generateName());
-  name.push_back(')');
-  return name;
-}
-
-void ParseBinaryExpression::getFieldStringItems(
-    std::vector<std::string> *inline_field_names,
-    std::vector<std::string> *inline_field_values,
-    std::vector<std::string> *non_container_child_field_names,
-    std::vector<const ParseTreeNode*> *non_container_child_fields,
-    std::vector<std::string> *container_child_field_names,
-    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const  {
-  non_container_child_field_names->push_back("left_operand");
-  non_container_child_fields->push_back(left_operand_.get());
-
-  non_container_child_field_names->push_back("right_operand");
-  non_container_child_fields->push_back(right_operand_.get());
-}
-
 std::string ParseFunctionCall::generateName() const {
   string name(name_->value());
   name.push_back('(');
@@ -175,59 +127,4 @@ void ParseFunctionCall::getFieldStringItems(
   }
 }
 
-std::string ParseExtractFunction::generateName() const {
-  std::string name;
-  name.append("EXTRACT(");
-  name.append(extract_field_->value());
-  name.append(" FROM ");
-  name.append(date_expression_->generateName());
-  name.push_back(')');
-  return name;
-}
-
-void ParseExtractFunction::getFieldStringItems(
-    std::vector<std::string> *inline_field_names,
-    std::vector<std::string> *inline_field_values,
-    std::vector<std::string> *non_container_child_field_names,
-    std::vector<const ParseTreeNode*> *non_container_child_fields,
-    std::vector<std::string> *container_child_field_names,
-    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
-  inline_field_names->push_back("unit");
-  inline_field_values->push_back(extract_field_->value());
-
-  non_container_child_field_names->push_back("date_expression");
-  non_container_child_fields->push_back(date_expression_.get());
-}
-
-std::string ParseSubstringFunction::generateName() const {
-  std::string name;
-  name.append("SUBSTRING(");
-  name.append(operand_->generateName());
-  name.append(" FROM ");
-  name.append(std::to_string(start_position_));
-  if (length_ != kDefaultLength) {
-    name.append(" FOR ");
-    name.append(std::to_string(length_));
-  }
-  name.push_back(')');
-  return name;
-}
-
-void ParseSubstringFunction::getFieldStringItems(
-    std::vector<std::string> *inline_field_names,
-    std::vector<std::string> *inline_field_values,
-    std::vector<std::string> *non_container_child_field_names,
-    std::vector<const ParseTreeNode*> *non_container_child_fields,
-    std::vector<std::string> *container_child_field_names,
-    std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const {
-  inline_field_names->push_back("start_position");
-  inline_field_values->push_back(std::to_string(start_position_));
-
-  inline_field_names->push_back("length");
-  inline_field_values->push_back(std::to_string(length_));
-
-  non_container_child_field_names->push_back("operand");
-  non_container_child_fields->push_back(operand_.get());
-}
-
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/ParseBasicExpressions.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseBasicExpressions.hpp b/parser/ParseBasicExpressions.hpp
index d8de669..4572214 100644
--- a/parser/ParseBasicExpressions.hpp
+++ b/parser/ParseBasicExpressions.hpp
@@ -36,9 +36,6 @@
 
 namespace quickstep {
 
-class BinaryOperation;
-class UnaryOperation;
-
 /** \addtogroup Parser
  *  @{
  */
@@ -173,155 +170,6 @@ class ParseAttribute : public ParseExpression {
 
 
 /**
- * @brief The parsed representation of an unary operation applied to an expression.
- **/
-class ParseUnaryExpression : public ParseExpression {
- public:
-  /**
-   * @brief Constructor.
-   *
-   * @param line_number Line number of the first token of this node in the SQL statement.
-   * @param column_number Column number of the first token of this node in the SQL statement.
-   * @param op The UnaryOperation from the quickstep type system to apply.
-   * @param operand The parsed scalar representation of the unary operation's
-   *        argument, which becomes owned by this ParseScalarUnaryExpression.
-   **/
-  ParseUnaryExpression(const int line_number,
-                       const int column_number,
-                       const UnaryOperation &op,
-                       ParseExpression *operand)
-      : ParseExpression(line_number, column_number),
-        op_(op),
-        operand_(operand) {
-  }
-
-  /**
-   * @brief Destructor.
-   */
-  ~ParseUnaryExpression() override {
-  }
-
-  ExpressionType getExpressionType() const override {
-    return kUnaryExpression;
-  }
-
-  std::string getName() const override;
-
-  /**
-   * @return The unary operation.
-   */
-  const UnaryOperation& op() const {
-    return op_;
-  }
-
-  /**
-   * @return The operand expression.
-   */
-  const ParseExpression* operand() const {
-    return operand_.get();
-  }
-
-  std::string generateName() const override;
-
- protected:
-  void getFieldStringItems(
-      std::vector<std::string> *inline_field_names,
-      std::vector<std::string> *inline_field_values,
-      std::vector<std::string> *non_container_child_field_names,
-      std::vector<const ParseTreeNode*> *non_container_child_fields,
-      std::vector<std::string> *container_child_field_names,
-      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
-
- private:
-  const UnaryOperation &op_;
-  std::unique_ptr<ParseExpression> operand_;
-
-  DISALLOW_COPY_AND_ASSIGN(ParseUnaryExpression);
-};
-
-/**
- * @brief The parsed representation of a binary operation applied to two
- *        expressions.
- **/
-class ParseBinaryExpression : public ParseExpression {
- public:
-  /**
-   * @brief Constructor.
-   *
-   * @param line_number Line number of the binary operator token in the SQL statement.
-   * @param column_number Column number of the binary operator token in the SQL statement.
-   * @param op The BinaryOperation from the quickstep type system to apply.
-   * @param left_operand The parsed scalar representation of the binary
-   *        operation's left argument, which becomes owned by this
-   *        ParseScalarBinaryExpression.
-   * @param right_operand The parsed scalar representation of the binary
-   *        operation's right argument, which becomes owned by this
-   *        ParseScalarBinaryExpression.
-   **/
-  ParseBinaryExpression(const int line_number,
-                        const int column_number,
-                        const BinaryOperation &op,
-                        ParseExpression *left_operand,
-                        ParseExpression *right_operand)
-      : ParseExpression(line_number, column_number),
-        op_(op),
-        left_operand_(left_operand),
-        right_operand_(right_operand) {
-  }
-
-  /**
-   * @brief Destructor.
-   */
-  ~ParseBinaryExpression() override {
-  }
-
-  ExpressionType getExpressionType() const override {
-    return kBinaryExpression;
-  }
-
-  std::string getName() const override;
-
-  /**
-   * @return The binary operation.
-   */
-  const BinaryOperation& op() const {
-    return op_;
-  }
-
-  /**
-   * @return The left operand expression.
-   */
-  const ParseExpression* left_operand() const {
-    return left_operand_.get();
-  }
-
-  /**
-   * @return The right operand expression.
-   */
-  const ParseExpression* right_operand() const {
-    return right_operand_.get();
-  }
-
-  std::string generateName() const override;
-
- protected:
-  void getFieldStringItems(
-      std::vector<std::string> *inline_field_names,
-      std::vector<std::string> *inline_field_values,
-      std::vector<std::string> *non_container_child_field_names,
-      std::vector<const ParseTreeNode*> *non_container_child_fields,
-      std::vector<std::string> *container_child_field_names,
-      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
-
- private:
-  const BinaryOperation &op_;
-  std::unique_ptr<ParseExpression> left_operand_;
-  std::unique_ptr<ParseExpression> right_operand_;
-
-  DISALLOW_COPY_AND_ASSIGN(ParseBinaryExpression);
-};
-
-/**
  * @brief The parsed representation of '*' as a function argument.
  */
 class ParseStar : public ParseTreeNode {
@@ -346,6 +194,7 @@ class ParseStar : public ParseTreeNode {
   DISALLOW_COPY_AND_ASSIGN(ParseStar);
 };
 
+
 /**
  * @brief Parsed function call in the form of a name with a list of arguments in parentheses.
  */
@@ -495,144 +344,6 @@ class ParseFunctionCall : public ParseExpression {
   DISALLOW_COPY_AND_ASSIGN(ParseFunctionCall);
 };
 
-
-/**
- * @brief Parsed representation of EXTRACT(unit FROM date).
- */
-class ParseExtractFunction : public ParseExpression {
- public:
-  /**
-   * @brief Constructor.
-   *
-   * @param line_number The line number of the token "extract" in the statement.
-   * @param column_number The column number of the token "extract in the statement.
-   * @param extract_field The field to extract.
-   * @param source_expression The expression to extract a field from.
-   */
-  ParseExtractFunction(const int line_number,
-                       const int column_number,
-                       ParseString *extract_field,
-                       ParseExpression *date_expression)
-      : ParseExpression(line_number, column_number),
-        extract_field_(extract_field),
-        date_expression_(date_expression) {
-  }
-
-  ExpressionType getExpressionType() const override {
-    return kExtract;
-  }
-
-  std::string getName() const override {
-    return "Extract";
-  }
-
-  /**
-   * @return The field to extract.
-   */
-  const ParseString* extract_field() const {
-    return extract_field_.get();
-  }
-
-  /**
-   * @return The expression to extract a field from.
-   */
-  const ParseExpression* date_expression() const {
-    return date_expression_.get();
-  }
-
-  std::string generateName() const override;
-
- protected:
-  void getFieldStringItems(
-      std::vector<std::string> *inline_field_names,
-      std::vector<std::string> *inline_field_values,
-      std::vector<std::string> *non_container_child_field_names,
-      std::vector<const ParseTreeNode*> *non_container_child_fields,
-      std::vector<std::string> *container_child_field_names,
-      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
-
- private:
-  std::unique_ptr<ParseString> extract_field_;
-  std::unique_ptr<ParseExpression> date_expression_;
-
-  DISALLOW_COPY_AND_ASSIGN(ParseExtractFunction);
-};
-
-
-/**
- * @brief Parsed representation of the substring function.
- */
-class ParseSubstringFunction : public ParseExpression {
- public:
-  static constexpr std::size_t kDefaultLength = std::numeric_limits<std::size_t>::max();
-
-  /**
-   * @brief Constructor.
-   *
-   * @param line_number The line number of the first token of the function call.
-   * @param column_number The column number of the first token of the function call.
-   * @param operand The operand of the substring.
-   * @param start_position The 1-based starting position of the substring.
-   * @param length Optional substring length.
-   */
-  ParseSubstringFunction(const int line_number,
-                         const int column_number,
-                         ParseExpression *operand,
-                         const std::size_t start_position,
-                         const std::size_t length = kDefaultLength)
-      : ParseExpression(line_number, column_number),
-        operand_(operand),
-        start_position_(start_position),
-        length_(length) {}
-
-  ExpressionType getExpressionType() const override {
-    return kSubstring;
-  }
-
-  std::string getName() const override {
-    return "Substring";
-  }
-
-  /**
-   * @return The operand of the substring.
-   */
-  const ParseExpression* operand() const {
-    return operand_.get();
-  }
-
-  /**
-   * @return The 1-based starting position of the substring.
-   */
-  std::size_t start_position() const {
-    return start_position_;
-  }
-
-  /**
-   * @return Then substring length.
-   */
-  std::size_t length() const {
-    return length_;
-  }
-
-  std::string generateName() const override;
-
- protected:
-  void getFieldStringItems(
-      std::vector<std::string> *inline_field_names,
-      std::vector<std::string> *inline_field_values,
-      std::vector<std::string> *non_container_child_field_names,
-      std::vector<const ParseTreeNode*> *non_container_child_fields,
-      std::vector<std::string> *container_child_field_names,
-      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;
-
- private:
-  std::unique_ptr<ParseExpression> operand_;
-  const std::size_t start_position_;
-  const std::size_t length_;
-
-  DISALLOW_COPY_AND_ASSIGN(ParseSubstringFunction);
-};
-
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/ParseExpression.hpp
----------------------------------------------------------------------
diff --git a/parser/ParseExpression.hpp b/parser/ParseExpression.hpp
index 1b9ade4..94b4487 100644
--- a/parser/ParseExpression.hpp
+++ b/parser/ParseExpression.hpp
@@ -39,14 +39,11 @@ class ParseExpression : public ParseTreeNode {
   enum ExpressionType {
     kAttribute,
     kBinaryExpression,
-    kExtract,
     kFunctionCall,
     kScalarLiteral,
     kSearchedCaseExpression,
     kSimpleCaseExpression,
     kSubqueryExpression,
-    kSubstring,
-    kUnaryExpression,
   };
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/9b23a4d3/parser/SqlLexer.lpp
----------------------------------------------------------------------
diff --git a/parser/SqlLexer.lpp b/parser/SqlLexer.lpp
index d818d0b..92268e8 100644
--- a/parser/SqlLexer.lpp
+++ b/parser/SqlLexer.lpp
@@ -184,6 +184,7 @@ unsigned_numeric_literal {exact_numeric_literal}|{approximate_numeric_literal}
   "blocksample"      return TOKEN_BLOCKSAMPLE;
   "bloomfilter"      return TOKEN_BLOOM_FILTER;
   "case"             return TOKEN_CASE;
+  "cast"             return TOKEN_CAST;
   "csbtree"          return TOKEN_CSB_TREE;
   "by"               return TOKEN_BY;
   "char"             return TOKEN_CHARACTER;


[20/38] incubator-quickstep git commit: Some updates

Posted by ji...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/98a8e611/parser/preprocessed/SqlParser_gen.cpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.cpp b/parser/preprocessed/SqlParser_gen.cpp
index f3fedbc..569408e 100644
--- a/parser/preprocessed/SqlParser_gen.cpp
+++ b/parser/preprocessed/SqlParser_gen.cpp
@@ -235,88 +235,89 @@ extern int quickstep_yydebug;
     TOKEN_DESC = 308,
     TOKEN_DISTINCT = 309,
     TOKEN_DOUBLE = 310,
-    TOKEN_DROP = 311,
-    TOKEN_ELSE = 312,
-    TOKEN_END = 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_STDERR = 369,
-    TOKEN_STDOUT = 370,
-    TOKEN_SUBSTRING = 371,
-    TOKEN_TABLE = 372,
-    TOKEN_THEN = 373,
-    TOKEN_TIME = 374,
-    TOKEN_TIMESTAMP = 375,
-    TOKEN_TO = 376,
-    TOKEN_TRUE = 377,
-    TOKEN_TUPLESAMPLE = 378,
-    TOKEN_UNBOUNDED = 379,
-    TOKEN_UNIQUE = 380,
-    TOKEN_UPDATE = 381,
-    TOKEN_USING = 382,
-    TOKEN_VALUES = 383,
-    TOKEN_VARCHAR = 384,
-    TOKEN_WHEN = 385,
-    TOKEN_WHERE = 386,
-    TOKEN_WINDOW = 387,
-    TOKEN_WITH = 388,
-    TOKEN_YEAR = 389,
-    TOKEN_YEARMONTH = 390,
-    TOKEN_EOF = 391,
-    TOKEN_LEX_ERROR = 392
+    TOKEN_DOUBLECOLON = 311,
+    TOKEN_DROP = 312,
+    TOKEN_ELSE = 313,
+    TOKEN_END = 314,
+    TOKEN_EXISTS = 315,
+    TOKEN_EXTRACT = 316,
+    TOKEN_FALSE = 317,
+    TOKEN_FIRST = 318,
+    TOKEN_FLOAT = 319,
+    TOKEN_FOLLOWING = 320,
+    TOKEN_FOR = 321,
+    TOKEN_FOREIGN = 322,
+    TOKEN_FROM = 323,
+    TOKEN_FULL = 324,
+    TOKEN_GROUP = 325,
+    TOKEN_HASH = 326,
+    TOKEN_HAVING = 327,
+    TOKEN_HOUR = 328,
+    TOKEN_IN = 329,
+    TOKEN_INDEX = 330,
+    TOKEN_INNER = 331,
+    TOKEN_INSERT = 332,
+    TOKEN_INTEGER = 333,
+    TOKEN_INTERVAL = 334,
+    TOKEN_INTO = 335,
+    TOKEN_JOIN = 336,
+    TOKEN_KEY = 337,
+    TOKEN_LAST = 338,
+    TOKEN_LEFT = 339,
+    TOKEN_LIMIT = 340,
+    TOKEN_LONG = 341,
+    TOKEN_MINUTE = 342,
+    TOKEN_MONTH = 343,
+    TOKEN_NULL = 344,
+    TOKEN_NULLS = 345,
+    TOKEN_OFF = 346,
+    TOKEN_ON = 347,
+    TOKEN_ORDER = 348,
+    TOKEN_OUTER = 349,
+    TOKEN_OVER = 350,
+    TOKEN_PARTITION = 351,
+    TOKEN_PARTITIONS = 352,
+    TOKEN_PERCENT = 353,
+    TOKEN_PRECEDING = 354,
+    TOKEN_PRIMARY = 355,
+    TOKEN_PRIORITY = 356,
+    TOKEN_QUIT = 357,
+    TOKEN_RANGE = 358,
+    TOKEN_REAL = 359,
+    TOKEN_REFERENCES = 360,
+    TOKEN_RIGHT = 361,
+    TOKEN_ROW = 362,
+    TOKEN_ROW_DELIMITER = 363,
+    TOKEN_ROWS = 364,
+    TOKEN_SECOND = 365,
+    TOKEN_SELECT = 366,
+    TOKEN_SET = 367,
+    TOKEN_SMA = 368,
+    TOKEN_SMALLINT = 369,
+    TOKEN_STDERR = 370,
+    TOKEN_STDOUT = 371,
+    TOKEN_SUBSTRING = 372,
+    TOKEN_TABLE = 373,
+    TOKEN_THEN = 374,
+    TOKEN_TIME = 375,
+    TOKEN_TIMESTAMP = 376,
+    TOKEN_TO = 377,
+    TOKEN_TRUE = 378,
+    TOKEN_TUPLESAMPLE = 379,
+    TOKEN_UNBOUNDED = 380,
+    TOKEN_UNIQUE = 381,
+    TOKEN_UPDATE = 382,
+    TOKEN_USING = 383,
+    TOKEN_VALUES = 384,
+    TOKEN_VARCHAR = 385,
+    TOKEN_WHEN = 386,
+    TOKEN_WHERE = 387,
+    TOKEN_WINDOW = 388,
+    TOKEN_WITH = 389,
+    TOKEN_YEAR = 390,
+    TOKEN_YEARMONTH = 391,
+    TOKEN_EOF = 392,
+    TOKEN_LEX_ERROR = 393
   };
 #endif
 
@@ -426,7 +427,7 @@ union YYSTYPE
 
   quickstep::ParsePriority *opt_priority_clause_;
 
-#line 430 "SqlParser_gen.cpp" /* yacc.c:355  */
+#line 431 "SqlParser_gen.cpp" /* yacc.c:355  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -461,7 +462,7 @@ int quickstep_yyparse (yyscan_t yyscanner, quickstep::ParseStatement **parsedSta
 #include "SqlLexer_gen.hpp"
 void NotSupported(const YYLTYPE *location, yyscan_t yyscanner, const std::string &feature);
 
-#line 465 "SqlParser_gen.cpp" /* yacc.c:358  */
+#line 466 "SqlParser_gen.cpp" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -705,21 +706,21 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  50
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1389
+#define YYLAST   1282
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  149
+#define YYNTOKENS  150
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  111
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  301
+#define YYNRULES  303
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  559
+#define YYNSTATES  562
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   392
+#define YYMAXUTOK   393
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -729,11 +730,11 @@ union yyalloc
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     144,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     145,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,   148,     2,     2,
-     145,   146,    23,    21,   147,    22,    27,    24,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,   143,
+       2,     2,     2,     2,     2,     2,     2,   149,     2,     2,
+     146,   147,    23,    21,   148,    22,    27,    24,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,   144,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -767,44 +768,44 @@ static const yytype_uint8 yytranslate[] =
      110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
      120,   121,   122,   123,   124,   125,   126,   127,   128,   129,
      130,   131,   132,   133,   134,   135,   136,   137,   138,   139,
-     140,   141,   142
+     140,   141,   142,   143
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   634,   634,   638,   642,   646,   650,   653,   660,   663,
-     666,   669,   672,   675,   678,   681,   684,   687,   693,   699,
-     706,   712,   719,   728,   733,   742,   747,   752,   756,   762,
-     767,   770,   773,   778,   781,   784,   787,   790,   793,   796,
-     799,   802,   805,   817,   820,   823,   841,   861,   864,   867,
-     872,   877,   883,   889,   898,   902,   908,   911,   916,   921,
-     926,   933,   940,   944,   950,   953,   958,   961,   966,   969,
-     974,   977,   996,   999,  1004,  1008,  1014,  1017,  1020,  1023,
-    1028,  1031,  1034,  1041,  1046,  1057,  1062,  1067,  1071,  1075,
-    1081,  1084,  1090,  1098,  1101,  1104,  1110,  1115,  1120,  1124,
-    1130,  1134,  1137,  1142,  1145,  1150,  1155,  1160,  1164,  1170,
-    1179,  1182,  1187,  1190,  1209,  1214,  1218,  1224,  1230,  1239,
-    1244,  1252,  1258,  1264,  1267,  1270,  1275,  1278,  1283,  1287,
-    1293,  1296,  1299,  1304,  1309,  1314,  1317,  1320,  1325,  1328,
-    1331,  1334,  1337,  1340,  1343,  1346,  1351,  1354,  1359,  1363,
-    1367,  1370,  1374,  1377,  1382,  1385,  1390,  1393,  1398,  1402,
-    1408,  1411,  1416,  1419,  1424,  1427,  1432,  1435,  1454,  1457,
-    1462,  1466,  1472,  1478,  1483,  1486,  1491,  1494,  1499,  1502,
-    1507,  1510,  1515,  1516,  1519,  1524,  1525,  1528,  1533,  1537,
-    1543,  1550,  1553,  1556,  1561,  1564,  1567,  1573,  1576,  1581,
-    1586,  1595,  1600,  1609,  1614,  1617,  1622,  1625,  1630,  1636,
-    1642,  1645,  1648,  1651,  1654,  1657,  1663,  1672,  1678,  1683,
-    1689,  1694,  1699,  1704,  1707,  1710,  1713,  1717,  1721,  1724,
-    1727,  1730,  1733,  1736,  1741,  1745,  1749,  1752,  1757,  1771,
-    1782,  1793,  1801,  1812,  1815,  1820,  1824,  1830,  1835,  1839,
-    1845,  1850,  1853,  1858,  1862,  1868,  1871,  1874,  1877,  1889,
-    1893,  1912,  1925,  1940,  1943,  1946,  1949,  1952,  1955,  1960,
-    1964,  1970,  1973,  1978,  1982,  1989,  1992,  1995,  1998,  2001,
-    2004,  2007,  2010,  2013,  2016,  2021,  2032,  2035,  2040,  2043,
-    2046,  2052,  2056,  2062,  2065,  2073,  2076,  2079,  2082,  2088,
-    2093,  2098
+       0,   635,   635,   639,   643,   647,   651,   654,   661,   664,
+     667,   670,   673,   676,   679,   682,   685,   688,   694,   700,
+     707,   713,   720,   729,   734,   743,   748,   753,   757,   763,
+     768,   771,   774,   779,   782,   785,   788,   791,   794,   797,
+     800,   803,   806,   818,   821,   824,   842,   862,   865,   868,
+     873,   878,   884,   890,   899,   903,   909,   912,   917,   922,
+     927,   934,   941,   945,   951,   954,   959,   962,   967,   970,
+     975,   978,   997,  1000,  1005,  1009,  1015,  1018,  1021,  1024,
+    1029,  1032,  1035,  1042,  1047,  1058,  1063,  1068,  1072,  1076,
+    1082,  1085,  1091,  1099,  1102,  1105,  1111,  1116,  1121,  1125,
+    1131,  1135,  1138,  1143,  1146,  1151,  1156,  1161,  1165,  1171,
+    1180,  1183,  1188,  1191,  1210,  1215,  1219,  1225,  1231,  1240,
+    1245,  1253,  1259,  1265,  1268,  1271,  1276,  1279,  1284,  1288,
+    1294,  1297,  1300,  1305,  1310,  1315,  1318,  1321,  1326,  1329,
+    1332,  1335,  1338,  1341,  1344,  1347,  1352,  1355,  1360,  1364,
+    1368,  1371,  1375,  1378,  1383,  1386,  1391,  1394,  1399,  1403,
+    1409,  1412,  1417,  1420,  1425,  1428,  1433,  1436,  1455,  1458,
+    1463,  1467,  1473,  1479,  1484,  1487,  1492,  1495,  1500,  1503,
+    1508,  1511,  1516,  1517,  1520,  1525,  1526,  1529,  1534,  1538,
+    1544,  1551,  1554,  1557,  1562,  1565,  1568,  1574,  1577,  1582,
+    1587,  1596,  1601,  1610,  1615,  1618,  1623,  1626,  1631,  1637,
+    1643,  1646,  1649,  1652,  1655,  1658,  1664,  1673,  1679,  1684,
+    1690,  1695,  1700,  1705,  1708,  1711,  1714,  1718,  1722,  1725,
+    1728,  1731,  1734,  1737,  1742,  1746,  1750,  1753,  1758,  1772,
+    1781,  1795,  1806,  1817,  1825,  1836,  1839,  1844,  1848,  1854,
+    1859,  1863,  1869,  1874,  1877,  1882,  1886,  1892,  1895,  1898,
+    1901,  1913,  1917,  1936,  1949,  1964,  1967,  1970,  1973,  1976,
+    1979,  1984,  1988,  1994,  1997,  2002,  2006,  2013,  2016,  2019,
+    2022,  2025,  2028,  2031,  2034,  2037,  2040,  2045,  2056,  2059,
+    2064,  2067,  2070,  2076,  2080,  2086,  2089,  2097,  2100,  2103,
+    2106,  2112,  2117,  2122
 };
 #endif
 
@@ -827,15 +828,15 @@ static const char *const yytname[] =
   "TOKEN_CONSTRAINT", "TOKEN_COPY", "TOKEN_CREATE", "TOKEN_CURRENT",
   "TOKEN_DATE", "TOKEN_DATETIME", "TOKEN_DAY", "TOKEN_DECIMAL",
   "TOKEN_DEFAULT", "TOKEN_DELETE", "TOKEN_DESC", "TOKEN_DISTINCT",
-  "TOKEN_DOUBLE", "TOKEN_DROP", "TOKEN_ELSE", "TOKEN_END", "TOKEN_EXISTS",
-  "TOKEN_EXTRACT", "TOKEN_FALSE", "TOKEN_FIRST", "TOKEN_FLOAT",
-  "TOKEN_FOLLOWING", "TOKEN_FOR", "TOKEN_FOREIGN", "TOKEN_FROM",
-  "TOKEN_FULL", "TOKEN_GROUP", "TOKEN_HASH", "TOKEN_HAVING", "TOKEN_HOUR",
-  "TOKEN_IN", "TOKEN_INDEX", "TOKEN_INNER", "TOKEN_INSERT",
-  "TOKEN_INTEGER", "TOKEN_INTERVAL", "TOKEN_INTO", "TOKEN_JOIN",
-  "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT", "TOKEN_LIMIT", "TOKEN_LONG",
-  "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL", "TOKEN_NULLS", "TOKEN_OFF",
-  "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER", "TOKEN_OVER",
+  "TOKEN_DOUBLE", "TOKEN_DOUBLECOLON", "TOKEN_DROP", "TOKEN_ELSE",
+  "TOKEN_END", "TOKEN_EXISTS", "TOKEN_EXTRACT", "TOKEN_FALSE",
+  "TOKEN_FIRST", "TOKEN_FLOAT", "TOKEN_FOLLOWING", "TOKEN_FOR",
+  "TOKEN_FOREIGN", "TOKEN_FROM", "TOKEN_FULL", "TOKEN_GROUP", "TOKEN_HASH",
+  "TOKEN_HAVING", "TOKEN_HOUR", "TOKEN_IN", "TOKEN_INDEX", "TOKEN_INNER",
+  "TOKEN_INSERT", "TOKEN_INTEGER", "TOKEN_INTERVAL", "TOKEN_INTO",
+  "TOKEN_JOIN", "TOKEN_KEY", "TOKEN_LAST", "TOKEN_LEFT", "TOKEN_LIMIT",
+  "TOKEN_LONG", "TOKEN_MINUTE", "TOKEN_MONTH", "TOKEN_NULL", "TOKEN_NULLS",
+  "TOKEN_OFF", "TOKEN_ON", "TOKEN_ORDER", "TOKEN_OUTER", "TOKEN_OVER",
   "TOKEN_PARTITION", "TOKEN_PARTITIONS", "TOKEN_PERCENT",
   "TOKEN_PRECEDING", "TOKEN_PRIMARY", "TOKEN_PRIORITY", "TOKEN_QUIT",
   "TOKEN_RANGE", "TOKEN_REAL", "TOKEN_REFERENCES", "TOKEN_RIGHT",
@@ -906,14 +907,14 @@ static const yytype_uint16 yytoknum[] =
      360,   361,   362,   363,   364,   365,   366,   367,   368,   369,
      370,   371,   372,   373,   374,   375,   376,   377,   378,   379,
      380,   381,   382,   383,   384,   385,   386,   387,   388,   389,
-     390,   391,   392,    59,    10,    40,    41,    44,    37
+     390,   391,   392,   393,    59,    10,    40,    41,    44,    37
 };
 # endif
 
-#define YYPACT_NINF -286
+#define YYPACT_NINF -370
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-286)))
+  (!!((Yystate) == (-370)))
 
 #define YYTABLE_NINF -139
 
@@ -924,62 +925,63 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     254,  -286,  -286,   -65,    71,   -18,   133,   -19,    28,  -286,
-      40,   190,   190,  -286,   209,    79,  -286,  -286,  -286,  -286,
-    -286,  -286,  -286,  -286,  -286,  -286,   168,    45,   183,  -286,
-     150,   238,   190,  -286,  -286,    13,    77,   190,   190,   190,
-     190,   190,  -286,  -286,   704,   118,   105,  -286,   225,   120,
-    -286,  -286,  -286,   148,   186,    45,    40,   179,  -286,   148,
-    -286,  -286,  -286,   164,    18,   159,   285,   159,   204,   162,
-     174,  -286,   -37,  -286,  -286,   307,   312,  -286,  -286,  -286,
-     771,   178,   194,  -286,   258,  -286,  -286,   198,  -286,  -286,
-     344,  -286,  -286,  -286,  -286,   207,  -286,  -286,   211,   282,
-     865,   353,   300,   227,  -286,  -286,   349,    24,  -286,  -286,
-     276,  -286,  -286,  -286,  -286,  -286,  -286,  1026,   -13,   190,
-     190,   236,   190,    13,   190,  -286,   148,   347,  -286,   248,
-     270,  -286,  -286,  -286,   239,  -286,   159,  -286,   190,   190,
-     610,  -286,  -286,   246,   190,  -286,  -286,  -286,   610,    50,
-     -16,  -286,  1093,   379,  -286,   146,   146,  1093,   387,  -286,
-       0,    29,  -286,    20,   174,  1093,  -286,  -286,   190,  1093,
-    -286,  -286,  -286,  -286,  1093,    21,   312,  -286,   190,   406,
-     -81,  -286,   389,  -286,   148,  -286,   175,  -286,   159,   148,
-     183,  -286,   190,    -7,   190,   190,   190,  -286,   274,  -286,
-     215,  1249,   932,   236,   543,   408,   416,  -286,  -286,   315,
-     420,  1237,   217,    10,  1093,     1,  -286,  1093,  -286,   380,
-     226,   298,  -286,  -286,  -286,  -286,  -286,  -286,   374,  -286,
-      85,   301,  -286,  -286,    11,   220,   228,  -286,   306,   220,
-      56,   381,  -286,  -286,    24,  -286,   348,  -286,  -286,   308,
-    1093,  -286,   346,   231,   190,  -286,  1093,  -286,   190,  -286,
-    -286,  -286,   311,   371,   376,   318,  -286,  -286,  -286,   233,
-    -286,  -286,  -286,  -286,  -286,    15,   190,   328,    -7,   190,
-    -286,   152,  -286,  -286,     2,    72,   610,   610,   210,  -286,
-    -286,  -286,  -286,  -286,  -286,  -286,  -286,  1093,   319,  1093,
-      60,  -286,   241,   334,  1093,    58,  -286,   407,   346,  -286,
-    1153,  -286,  1093,   462,  -286,   163,   190,  -286,  -286,   375,
-    -286,   378,   382,   393,    20,  -286,   465,   472,   220,   439,
-     409,   440,   337,   390,  -286,   243,  -286,  1093,  -286,   346,
-    -286,   610,   339,   341,   190,  -286,   190,  -286,  -286,  -286,
-    -286,  -286,  -286,  -286,   190,  -286,  -286,  -286,   250,   463,
-     170,  -286,   345,   356,  -286,   398,   350,  1237,  -286,   411,
-     190,  -286,  -286,   152,  -286,  -286,   416,  -286,  -286,  -286,
-    1093,   355,    92,   865,  -286,   346,   405,  -286,  -286,  1237,
-     357,   346,  1093,  -286,   359,   360,    31,    51,  -286,  -286,
-    -286,  -286,  -286,    20,   228,   399,   401,  -286,  1093,   610,
-     410,  1093,  -286,   466,   126,  -286,   346,    22,   190,   190,
-     255,  -286,   257,  -286,   190,  -286,  -286,  -286,  -286,   364,
-      -7,   473,   412,  -286,   610,  -286,  -286,   365,  -286,   259,
-     865,  -286,  1093,   262,  -286,  -286,  1237,   346,  -286,  -286,
-    -286,   506,  -286,   419,  -286,  -286,   370,   408,   476,   430,
-     370,  1093,  -286,  -286,  -286,   501,  -286,   271,   275,  -286,
-    -286,  -286,   190,  -286,  -286,   377,   479,  -286,    30,   190,
-    1093,   277,   346,  -286,   284,   383,   610,  1093,   516,   388,
-     385,  -286,   325,    25,   417,  -286,   286,   190,    17,  -286,
-     391,   346,  -286,  -286,  -286,   408,   385,  -286,   190,  -286,
-     388,  -286,  1093,  -286,  -286,   434,   432,   422,   433,   529,
-     190,  -286,   288,  -286,  -286,   394,  -286,   508,  -286,  -286,
-      38,  -286,  -286,  -286,  -286,    49,   400,  -286,   190,   413,
-    -286,  -286,   474,   443,   475,  -286,   190,   290,   348,  -286,
-    -286,  -286,   292,   454,   414,  -286,   549,  -286,  -286
+     318,  -370,  -370,   -80,    69,   -19,    41,   -25,    43,  -370,
+      42,   242,   242,  -370,   137,   148,  -370,  -370,  -370,  -370,
+    -370,  -370,  -370,  -370,  -370,  -370,   173,    70,   114,  -370,
+     132,   215,   242,  -370,  -370,    11,     5,   242,   242,   242,
+     242,   242,  -370,  -370,   662,   111,    99,  -370,   233,   122,
+    -370,  -370,  -370,   186,   221,    70,    42,   206,  -370,   186,
+    -370,  -370,  -370,    74,    67,   175,   321,   175,   231,   195,
+     205,  -370,   -34,  -370,  -370,   337,   342,  -370,  -370,  -370,
+     730,   208,   228,  -370,   268,  -370,  -370,   244,  -370,  -370,
+     353,  -370,  -370,  -370,  -370,   246,  -370,  -370,   247,   299,
+     825,   386,   322,   255,  -370,  -370,   314,    27,  -370,   333,
+     304,  -370,  -370,  -370,  -370,  -370,  -370,   988,    -5,   242,
+     242,   259,   242,    11,   242,  -370,   186,   399,  -370,   155,
+     236,  -370,  -370,  -370,   261,  -370,   175,  -370,   242,   242,
+     567,  -370,  -370,   265,   242,  -370,  -370,  -370,   567,    25,
+     -15,  -370,  1056,   405,  -370,   146,   146,  1056,   409,  -370,
+       3,    32,  -370,    19,   205,  1056,  -370,  -370,   242,  1056,
+    -370,  -370,  -370,  -370,  1056,   635,    23,   342,   333,   242,
+     392,    60,  -370,   408,  -370,   186,  -370,   -68,  -370,   175,
+     186,   114,  -370,   242,   165,   242,   242,   242,  -370,   274,
+    -370,   112,   798,   893,   259,   499,   413,   415,  -370,  -370,
+    1201,   402,  1141,   150,    33,  1056,   149,  -370,  1056,  -370,
+     362,   220,   283,  -370,  -370,  -370,  -370,  -370,  -370,   358,
+    -370,    46,   285,  -370,  -370,     7,   190,   248,  -370,   290,
+     190,    38,   364,  -370,  -370,    27,  -370,  -370,  -370,  -370,
+     332,  -370,  -370,   293,  1056,  -370,   279,   163,   242,  -370,
+    1056,  -370,   242,  -370,  -370,  -370,   295,   355,   356,   300,
+    -370,  -370,  -370,   169,  -370,  -370,  -370,  -370,  -370,    14,
+     242,   316,   165,   242,   194,  -370,  -370,     4,    73,   567,
+     567,   245,  -370,  -370,  -370,  -370,  -370,  -370,  -370,  -370,
+    1056,   307,  1056,    53,  -370,   183,   320,  1056,    75,  -370,
+     395,   279,  -370,   635,  -370,  1056,   449,  -370,   124,   242,
+    -370,  -370,   363,  -370,   365,   366,   377,    19,  -370,   459,
+     460,   190,   426,   393,   427,   325,   375,  -370,   185,  -370,
+    1056,  -370,   279,  -370,   567,   328,   331,   242,  -370,   242,
+    -370,  -370,  -370,  -370,  -370,  -370,  -370,   242,  -370,  -370,
+    -370,   191,   452,   189,  -370,   334,   345,  -370,   387,   339,
+    1141,  -370,   400,   242,  -370,  -370,   194,  -370,  -370,   415,
+    -370,  -370,  -370,  1056,   343,   212,   825,  -370,   279,   394,
+    -370,  -370,  1141,   344,   279,  1056,  -370,   346,   347,    34,
+     -22,  -370,  -370,  -370,  -370,  -370,    19,   248,   388,   389,
+    -370,  1056,   567,   397,  1056,  -370,   455,   135,  -370,   279,
+      16,   242,   242,   209,  -370,   214,  -370,   242,  -370,  -370,
+    -370,  -370,   352,   165,   461,   401,  -370,   567,  -370,  -370,
+     354,  -370,   235,   825,  -370,  1056,   216,  -370,  -370,  1141,
+     279,  -370,  -370,  -370,   501,  -370,   416,  -370,  -370,   367,
+     413,   468,   422,   367,  1056,  -370,  -370,  -370,   497,  -370,
+     218,   223,  -370,  -370,  -370,   242,  -370,  -370,   376,   481,
+    -370,    31,   242,  1056,   225,   279,  -370,   230,   378,   567,
+    1056,   517,   390,   381,  -370,   193,     9,   420,  -370,   234,
+     242,     0,  -370,   379,   279,  -370,  -370,  -370,   413,   381,
+    -370,   242,  -370,   390,  -370,  1056,  -370,  -370,   436,   428,
+     424,   437,   531,   242,  -370,   237,  -370,  -370,   403,  -370,
+     513,  -370,  -370,    39,  -370,  -370,  -370,  -370,    52,   404,
+    -370,   242,   407,  -370,  -370,   477,   443,   478,  -370,   242,
+     239,   332,  -370,  -370,  -370,   241,   454,   410,  -370,   551,
+    -370,  -370
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -987,95 +989,96 @@ static const yytype_int16 yypact[] =
      means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
-       0,     6,   301,     0,     0,     0,     0,     0,     0,    18,
+       0,     6,   303,     0,     0,     0,     0,     0,     0,    18,
      123,     0,     0,     7,     0,     0,    15,     8,    10,    11,
       13,    14,     9,    17,    12,    16,     0,   112,   119,   121,
-       0,   299,     0,   293,   294,     0,     0,     0,     0,     0,
+       0,   301,     0,   295,   296,     0,     0,     0,     0,     0,
        0,     0,   124,   125,     0,     0,   114,   115,     0,   156,
        1,     3,     2,     0,     0,   112,   123,     0,   110,     0,
-       5,     4,   300,     0,     0,   103,     0,   103,     0,     0,
-     197,    25,     0,   259,   256,     0,   285,   126,    40,    29,
+       5,     4,   302,     0,     0,   103,     0,   103,     0,     0,
+     197,    25,     0,   261,   258,     0,   287,   126,    40,    29,
        0,     0,     0,    30,    31,    34,    36,     0,    37,    39,
-       0,    41,   255,    35,    38,     0,    32,    33,     0,     0,
+       0,    41,   257,    35,    38,     0,    32,    33,     0,     0,
        0,     0,     0,   127,   128,   233,   132,   218,   220,   222,
-     225,   228,   229,   230,   231,   224,   223,     0,   271,     0,
+     225,   228,   229,   230,   231,   224,   223,     0,   273,     0,
        0,     0,     0,     0,     0,   111,     0,     0,   120,     0,
        0,   100,   102,   101,     0,    98,   103,    97,     0,     0,
-       0,   106,   198,     0,     0,    94,   257,   258,     0,     0,
-     251,   248,     0,     0,    43,     0,   260,     0,     0,    44,
-       0,     0,   262,     0,   197,     0,   286,   287,     0,     0,
-     131,   289,   290,   288,     0,     0,     0,   221,     0,     0,
-     197,   108,     0,   116,     0,   117,     0,   291,   103,     0,
-     118,   113,     0,     0,     0,     0,     0,    96,    66,    27,
-       0,     0,     0,     0,     0,   199,   201,   203,   205,     0,
-     223,     0,     0,     0,     0,   251,   245,     0,   249,     0,
-       0,     0,   265,   266,   267,   264,   268,   263,     0,   261,
-       0,     0,   134,   232,     0,     0,   158,   147,   133,   152,
-     135,   160,   129,   130,   217,   219,   174,   226,   272,     0,
-       0,   234,   253,     0,     0,   105,     0,   157,     0,    99,
-      95,    19,     0,     0,     0,     0,    20,    21,    22,     0,
-      74,    76,    77,    78,    79,     0,     0,     0,    64,     0,
-      42,    56,   204,   212,     0,     0,     0,     0,     0,   275,
-     277,   278,   279,   280,   276,   281,   283,     0,     0,     0,
-       0,   269,     0,     0,     0,     0,   246,     0,   252,   244,
-       0,    45,     0,     0,    46,   138,     0,   148,   154,   144,
-     139,   140,   142,     0,     0,   151,     0,     0,   150,     0,
-     162,     0,     0,   176,   235,     0,   236,     0,   107,   109,
-     292,     0,     0,     0,     0,   104,     0,    81,    84,    82,
-     297,   298,   296,   295,     0,    80,    85,   273,     0,   271,
-       0,    63,    65,    68,    28,     0,     0,     0,    47,     0,
-       0,    49,    55,    57,    26,   211,   200,   202,   282,   284,
-       0,     0,     0,     0,   213,   210,     0,   209,    93,     0,
-       0,   250,     0,   243,     0,     0,     0,     0,   153,   155,
-     145,   141,   143,     0,   159,     0,     0,   149,     0,     0,
-     164,     0,   227,     0,   178,   237,   254,     0,     0,     0,
-       0,    75,     0,    67,     0,    86,    87,    88,    89,    90,
-       0,     0,    70,    48,     0,    51,    50,     0,    54,     0,
-       0,   215,     0,     0,   208,   270,     0,   247,   238,   239,
-     240,     0,   241,     0,   136,   137,   161,   163,     0,   166,
-     175,     0,   181,   180,   173,     0,    61,     0,     0,    58,
-      83,   274,     0,    24,    62,     0,     0,    23,     0,     0,
-       0,     0,   206,   214,     0,     0,     0,     0,     0,   168,
-     177,   188,   191,     0,     0,    59,     0,     0,     0,    52,
-       0,   207,   216,    92,   242,   146,   165,   167,     0,   122,
-     169,   170,     0,   192,   193,   194,     0,     0,     0,     0,
-       0,    91,     0,    72,    73,     0,    53,     0,   171,   189,
-       0,   190,   182,   184,   183,     0,     0,    69,     0,     0,
-     195,   196,     0,     0,     0,   179,     0,     0,   174,   185,
-     187,   186,     0,     0,     0,    60,     0,   172,    71
+       0,   106,   198,     0,     0,    94,   259,   260,     0,     0,
+     253,   250,     0,     0,    43,     0,   262,     0,     0,    44,
+       0,     0,   264,     0,   197,     0,   288,   289,     0,     0,
+     131,   291,   292,   290,     0,     0,     0,     0,   221,     0,
+       0,   197,   108,     0,   116,     0,   117,     0,   293,   103,
+       0,   118,   113,     0,     0,     0,     0,     0,    96,    66,
+      27,     0,     0,     0,     0,     0,   199,   201,   203,   205,
+       0,   223,     0,     0,     0,     0,   253,   247,     0,   251,
+       0,     0,     0,   267,   268,   269,   266,   270,   265,     0,
+     263,     0,     0,   134,   232,     0,     0,   158,   147,   133,
+     152,   135,   160,   129,   130,   217,   219,    42,   240,   241,
+     174,   226,   274,     0,     0,   234,   255,     0,     0,   105,
+       0,   157,     0,    99,    95,    19,     0,     0,     0,     0,
+      20,    21,    22,     0,    74,    76,    77,    78,    79,     0,
+       0,     0,    64,     0,    56,   204,   212,     0,     0,     0,
+       0,     0,   277,   279,   280,   281,   282,   278,   283,   285,
+       0,     0,     0,     0,   271,     0,     0,     0,     0,   248,
+       0,   254,   246,     0,    45,     0,     0,    46,   138,     0,
+     148,   154,   144,   139,   140,   142,     0,     0,   151,     0,
+       0,   150,     0,   162,     0,     0,   176,   235,     0,   236,
+       0,   107,   109,   294,     0,     0,     0,     0,   104,     0,
+      81,    84,    82,   299,   300,   298,   297,     0,    80,    85,
+     275,     0,   273,     0,    63,    65,    68,    28,     0,     0,
+       0,    47,     0,     0,    49,    55,    57,    26,   211,   200,
+     202,   284,   286,     0,     0,     0,     0,   213,   210,     0,
+     209,    93,     0,     0,   252,     0,   245,     0,     0,     0,
+       0,   153,   155,   145,   141,   143,     0,   159,     0,     0,
+     149,     0,     0,   164,     0,   227,     0,   178,   237,   256,
+       0,     0,     0,     0,    75,     0,    67,     0,    86,    87,
+      88,    89,    90,     0,     0,    70,    48,     0,    51,    50,
+       0,    54,     0,     0,   215,     0,     0,   208,   272,     0,
+     249,   238,   239,   242,     0,   243,     0,   136,   137,   161,
+     163,     0,   166,   175,     0,   181,   180,   173,     0,    61,
+       0,     0,    58,    83,   276,     0,    24,    62,     0,     0,
+      23,     0,     0,     0,     0,   206,   214,     0,     0,     0,
+       0,     0,   168,   177,   188,   191,     0,     0,    59,     0,
+       0,     0,    52,     0,   207,   216,    92,   244,   146,   165,
+     167,     0,   122,   169,   170,     0,   192,   193,   194,     0,
+       0,     0,     0,     0,    91,     0,    72,    73,     0,    53,
+       0,   171,   189,     0,   190,   182,   184,   183,     0,     0,
+      69,     0,     0,   195,   196,     0,     0,     0,   179,     0,
+       0,   174,   185,   187,   186,     0,     0,     0,    60,     0,
+     172,    71
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -286,  -286,  -286,  -286,  -286,  -286,  -286,  -286,  -132,  -286,
-    -152,   184,  -286,  -286,  -275,  -286,  -286,  -286,  -286,  -286,
-    -286,  -285,   213,  -286,  -286,  -286,  -286,  -286,  -286,  -286,
-    -286,     4,    -8,  -286,  -286,  -286,   309,  -286,   507,  -286,
-    -286,   441,   240,   442,   -28,   510,  -286,  -286,   402,  -286,
-    -105,  -286,  -286,  -193,   166,  -185,   -11,  -286,  -286,  -286,
-    -286,  -286,  -286,  -286,    61,    26,  -286,  -286,  -286,  -286,
-    -286,  -286,    83,    63,  -286,  -286,    52,  -286,  -142,   287,
-     289,   392,   -35,   403,   415,   460,  -161,  -286,  -286,  -286,
-    -286,  -286,   366,  -286,   435,   367,  -238,  -200,   424,   137,
-    -135,  -286,  -286,  -286,  -286,  -286,  -140,    -4,  -286,  -286,
-    -286
+    -370,  -370,  -370,  -370,  -370,  -370,  -370,  -370,  -135,  -370,
+    -145,   184,  -370,  -370,  -279,  -370,  -370,  -370,  -370,  -370,
+    -370,  -369,   213,  -370,  -370,  -370,  -370,  -370,  -370,  -370,
+    -370,   -10,    -3,  -370,  -370,  -370,   303,  -370,   508,  -370,
+    -370,   446,   287,   441,   -28,   514,  -370,  -370,   411,  -370,
+    -111,  -370,  -370,  -169,   172,  -202,   -11,  -370,  -370,  -370,
+    -370,  -370,  -370,  -370,    56,    24,  -370,  -370,  -370,  -370,
+    -370,  -370,    89,    65,  -370,  -370,   -38,  -370,  -143,   292,
+     294,   382,   -35,   417,   418,   470,  -161,  -370,  -370,  -370,
+    -370,  -370,   380,  -370,   444,   383,  -237,  -197,   435,   151,
+    -134,  -370,  -370,  -370,  -370,  -370,  -140,    -4,  -370,  -370,
+    -370
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,    14,    15,    16,    17,    18,    19,    20,   199,   200,
-     101,   372,   373,   374,   266,   362,   363,   277,   432,   477,
-     525,   269,   270,   271,   272,   273,   274,   429,   473,    21,
-      22,    65,   135,    23,    24,   180,   181,    25,    58,    26,
+      -1,    14,    15,    16,    17,    18,    19,    20,   200,   201,
+     101,   375,   376,   377,   270,   365,   366,   281,   435,   480,
+     528,   273,   274,   275,   276,   277,   278,   432,   476,    21,
+      22,    65,   135,    23,    24,   181,   182,    25,    58,    26,
       46,    47,   160,    28,    29,    44,   102,   103,   104,   164,
-     105,   328,   323,   236,   237,   317,   318,   238,   330,   410,
-     459,   489,   509,   510,   511,   332,   333,   414,   464,   465,
-     519,   545,   490,   491,   515,   531,   141,   142,   205,   206,
-     207,   208,   209,   107,   108,   109,   110,   111,   112,   113,
-     114,   215,   216,   150,   151,   219,   253,   115,   228,   302,
-     116,   358,   299,   117,   169,   174,   186,   118,   356,    30,
+     105,   331,   326,   237,   238,   320,   321,   239,   333,   413,
+     462,   492,   512,   513,   514,   335,   336,   417,   467,   468,
+     522,   548,   493,   494,   518,   534,   141,   142,   206,   207,
+     208,   209,   210,   107,   108,   109,   110,   111,   112,   113,
+     114,   216,   217,   150,   151,   220,   257,   115,   229,   305,
+     116,   361,   302,   117,   169,   174,   187,   118,   359,    30,
       31
 };
 
@@ -1084,386 +1087,367 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      36,    48,   239,   361,   212,   210,   213,    45,    49,   106,
-     286,   301,   335,   210,   178,    33,   185,    34,   286,    33,
-     347,    34,   348,   131,    33,    33,    34,    34,    63,    56,
-     286,   128,   516,    68,    69,    70,    71,    72,   286,   262,
-      67,   315,    56,   349,   145,   149,   217,   171,   172,   281,
-     166,   167,   166,   167,   325,   140,   542,    32,   235,   137,
-     261,    37,   284,   217,   263,   161,   254,   210,    42,   210,
-     386,   166,   167,   239,    56,    33,   517,    34,    10,   166,
-     167,   350,   288,   289,   290,   291,   292,   293,   294,   295,
-     296,   297,   523,   166,   167,   326,   143,   264,   283,    43,
-     543,   442,   170,    40,    38,   540,   166,   167,   144,    48,
-     351,   352,    41,   166,   167,   182,    49,   220,   187,   148,
-     189,   451,   230,   265,   524,   541,    10,   188,   197,   235,
-     106,   404,   179,   304,   198,   201,   214,   132,   133,    64,
-     187,   357,   353,   407,   252,   443,   232,   364,   375,    66,
-     298,   210,   210,   387,   518,   474,   234,   313,   394,   240,
-     354,   260,   365,   239,   243,   234,   246,   435,   466,   285,
-     456,   247,   173,   460,   248,   233,   499,   450,   544,   305,
-     259,   392,   308,    57,   327,   214,    10,   496,   201,   445,
-     267,   268,   275,   384,    33,   129,    34,   452,   366,   417,
-     222,   179,   481,    64,   420,    39,   210,   425,   367,    50,
-     426,   427,   522,    59,   422,   252,   241,    53,   233,   235,
-      51,   339,    52,   223,    33,   130,    34,   378,   379,   380,
-     240,    49,   255,   462,   119,    49,   319,   224,   225,   463,
-      27,    62,   239,   320,    35,   368,   301,   166,   167,    54,
-     182,   321,   120,   316,   340,     1,   369,     2,   121,   310,
-     226,   370,   382,    10,   385,   122,    55,   457,   480,   391,
-     124,   355,   359,   322,   210,   201,   441,   396,   467,   468,
-     166,   167,   371,    10,   127,   227,     3,   428,   381,   471,
-     136,    60,   478,   123,    61,   192,   193,   134,   235,   210,
-     138,   319,   416,     4,     5,   399,   395,   139,   320,   398,
-     140,     6,    49,  -138,   146,     7,   321,   194,   195,   147,
-     240,   257,   258,   152,    49,   288,   289,   290,   291,   292,
-     293,   294,   295,   296,   297,     8,   166,   167,   322,   153,
-     187,   154,   275,   155,   505,   439,   166,   167,   252,   156,
-     187,   210,   157,    33,   191,    34,   158,   447,   162,   513,
-       9,   278,   279,   303,   258,   159,   437,   166,   167,    10,
-     166,   167,   163,   252,   165,   175,   252,   336,   337,   345,
-     346,   184,   168,   514,   196,    11,   221,   388,   389,   415,
-     337,   211,    12,   298,   231,    13,   423,   424,   547,   240,
-     256,   469,   258,   470,   258,   252,   552,   482,   483,   337,
-      33,    73,    34,    74,   187,   187,   286,   494,   258,   276,
-     359,   495,   258,   502,   337,   287,   492,    75,    76,   249,
-     503,   389,   521,   346,   537,   346,   553,   258,   555,   258,
-     300,    78,    79,   309,   311,   501,   312,   314,   331,    80,
-      81,    82,   492,   324,   334,   329,   341,   342,    83,    84,
-     360,    85,   343,   344,   383,   250,    86,   390,   275,   397,
-     393,    87,   405,   400,    88,   500,   401,   492,   403,   406,
-     402,   408,   411,   412,   418,   409,   419,   413,    89,    90,
-     178,   433,   430,   275,   431,   434,    91,   436,   444,    92,
-     440,   454,   446,   455,   527,   448,   449,   458,   461,   472,
-     479,   475,   476,   485,    93,   486,   536,   337,   487,   488,
-     493,   498,   497,   507,    94,   508,   520,    95,   530,   504,
-      96,    97,   512,   533,   187,   532,   534,   526,   535,   538,
-      98,   539,   187,   549,   551,   546,    99,    33,    73,    34,
-      74,   100,   251,   202,   550,   556,   558,   438,   548,   421,
-     557,   183,   125,   338,    75,    76,   126,   242,   190,   453,
-     506,   528,   244,   376,   554,   529,   377,   177,    78,    79,
-     229,   306,   307,   484,     0,   218,    80,    81,    82,   245,
-       0,     0,     0,     0,   282,    83,    84,     0,    85,     0,
-       0,     0,     0,    86,     0,     0,     0,   203,    87,     0,
+      36,    48,   240,   364,   213,   214,   211,    45,    49,   106,
+     186,    33,   289,    34,   211,   304,   519,   338,    33,   350,
+      34,   351,   179,    33,   289,    34,    67,    33,    63,    34,
+     248,   128,    56,    68,    69,    70,    71,    72,   328,   289,
+      56,   289,   352,    32,   145,   149,   166,   167,   218,   454,
+     171,   172,   236,   166,   167,   166,   167,   284,   265,   545,
+     520,    37,   287,   389,   137,   161,   318,   166,   167,   211,
+      42,   211,   131,    33,   240,    34,   526,   329,    66,   261,
+     262,   353,    10,   291,   292,   293,   294,   295,   296,   297,
+     298,   299,   300,   286,   166,   167,   166,   167,    40,    56,
+     143,    43,   170,   546,    38,   129,   499,   543,   527,    48,
+     354,   355,   144,   189,    39,   183,    49,   221,   188,   316,
+     190,   148,   231,    10,   236,   455,   242,   544,    41,   410,
+     106,   525,    64,   198,   199,   202,   130,    50,    64,   521,
+     188,   180,   356,   259,    59,   256,   360,   390,   367,   446,
+     233,   378,   301,   235,   477,   211,   211,   307,   407,   241,
+     357,   215,   264,   469,   244,   235,   240,   330,   397,   250,
+     288,   249,   251,   438,   459,   252,   173,   463,   502,   234,
+     308,   453,   547,   311,   180,    10,   263,   132,   133,   202,
+     387,   271,   272,   279,    33,   448,    34,   140,   322,   395,
+     223,   420,   193,   194,   368,   323,   484,   423,   258,    57,
+     211,   266,   218,   324,   166,   167,   236,   425,    62,   256,
+     234,   445,    53,   319,   224,   342,   428,   516,   119,   429,
+     430,   241,    49,   166,   167,   325,    49,   267,   225,   226,
+     369,   166,   167,   465,   483,   240,    33,   120,    34,   466,
+     370,   517,   304,   313,   183,    54,   166,   167,   343,   282,
+     283,   227,   381,   382,   383,   385,   121,   388,   122,   460,
+     268,   401,   394,   444,    60,   358,   362,    61,   211,   202,
+     399,   470,   471,   195,   196,   215,   228,    27,   371,    10,
+      51,    35,    52,   474,   481,   236,   269,   306,   262,   372,
+     166,   167,    10,   211,   373,   419,   124,   431,   402,   398,
+     339,   340,   127,    55,   134,    49,   348,   349,    33,     1,
+      34,     2,   322,   241,   384,   374,   136,    49,   138,   323,
+     391,   392,   418,   340,  -138,   166,   167,   324,   426,   427,
+     123,   139,   140,   188,   146,   279,   508,   168,   442,   147,
+       3,   256,   154,   188,   152,   211,   472,   262,   156,   325,
+     450,   473,   262,   486,   340,   497,   262,     4,     5,   440,
+     498,   262,   505,   340,   153,     6,   256,   506,   392,   256,
+       7,   524,   349,   159,   540,   349,   556,   262,   558,   262,
+     155,   162,   157,   158,   175,   163,    33,    73,    34,    74,
+       8,   550,   241,   165,   176,   185,   192,   197,   256,   555,
+     485,   212,   222,    75,    76,   253,   232,   188,   188,   260,
+     280,   289,   303,   362,   290,     9,   312,    78,    79,   495,
+     314,   315,   317,   334,    10,    80,    81,    82,   327,   332,
+     337,   344,   345,   346,    83,    84,   347,    85,   504,   363,
+      11,   254,    86,   386,   393,   495,   400,    12,    87,   396,
+      13,    88,   403,   406,   404,   405,   408,   409,   411,   414,
+     412,   279,   415,   416,   421,    89,    90,   422,   503,   179,
+     495,   436,   433,    91,   434,   437,    92,   439,   447,   443,
+     449,   457,   458,   451,   452,   461,   279,   464,   475,   478,
+     482,    93,   479,    33,    73,    34,    74,   530,   488,   203,
+     490,    94,   491,   489,    95,   340,   496,    96,    97,   539,
+      75,    76,   500,   501,   510,   507,   529,    98,   511,   515,
+     523,   533,   535,    99,    78,    79,   536,   188,   100,   255,
+     538,   537,    80,    81,    82,   188,   542,   552,   554,   541,
+     549,    83,    84,   551,    85,   553,   559,   560,   561,    86,
+     441,   341,   424,   125,   204,    87,   184,   191,    88,   531,
+     126,    33,    73,    34,    74,   557,   243,   203,   456,   509,
+     532,   379,    89,    90,   380,   285,   245,   178,    75,    76,
+      91,   230,   246,    92,   219,     0,   309,     0,     0,   310,
+     487,     0,    78,    79,     0,     0,     0,     0,    93,     0,
+      80,    81,    82,     0,     0,    10,     0,     0,    94,    83,
+      84,    95,    85,     0,    96,    97,     0,    86,     0,     0,
+       0,     0,   204,    87,    98,     0,    88,     0,     0,    33,
+      99,    34,     0,     0,     0,   205,     0,     0,     0,     0,
+      89,    90,     0,     0,     0,     0,     0,     0,    91,     0,
+       0,    92,     0,     0,     0,     0,    33,    73,    34,    74,
+      78,    79,     0,     0,     0,     0,    93,     0,     0,     0,
+      82,     0,     0,    75,    76,    77,    94,    83,    84,    95,
+      85,     0,    96,    97,     0,    86,     0,    78,    79,     0,
+       0,     0,    98,     0,    88,    80,    81,    82,    99,     0,
+       0,     0,     0,   205,    83,    84,     0,    85,    89,   247,
+       0,     0,    86,     0,     0,     0,    91,     0,    87,     0,
        0,    88,     0,     0,    33,    73,    34,    74,     0,     0,
-     202,     0,     0,     0,     0,    89,    90,     0,     0,     0,
-       0,    75,    76,    91,     0,     0,    92,     0,     0,     0,
-       0,     0,     0,     0,     0,    78,    79,     0,     0,     0,
-       0,    93,     0,    80,    81,    82,     0,     0,    10,     0,
+       0,     0,     0,     0,    93,    89,    90,     0,     0,     0,
+       0,    75,    76,    91,    94,     0,    92,     0,     0,     0,
+      96,    97,     0,     0,     0,    78,    79,     0,     0,     0,
+      98,    93,     0,    80,    81,    82,    99,     0,     0,     0,
        0,    94,    83,    84,    95,    85,     0,    96,    97,     0,
-      86,     0,     0,     0,   203,    87,     0,    98,    88,     0,
-       0,     0,     0,    99,     0,     0,     0,     0,   204,     0,
-       0,     0,    89,    90,     0,     0,     0,     0,     0,     0,
-      91,     0,     0,    92,     0,     0,     0,     0,    33,    73,
-      34,    74,     0,     0,     0,     0,     0,     0,    93,     0,
-       0,     0,     0,     0,     0,    75,    76,    77,    94,     0,
-       0,    95,     0,     0,    96,    97,     0,     0,     0,    78,
-      79,     0,     0,     0,    98,     0,     0,    80,    81,    82,
-      99,     0,     0,     0,     0,   204,    83,    84,     0,    85,
-       0,     0,     0,     0,    86,     0,     0,     0,     0,    87,
-       0,     0,    88,     0,     0,    33,    73,    34,    74,     0,
-       0,     0,     0,     0,     0,     0,    89,    90,     0,     0,
-       0,     0,    75,    76,    91,     0,     0,    92,     0,     0,
-       0,     0,     0,     0,     0,     0,    78,    79,     0,     0,
-       0,     0,    93,     0,    80,    81,    82,     0,     0,     0,
-       0,     0,    94,    83,    84,    95,    85,     0,    96,    97,
-       0,    86,     0,     0,     0,     0,    87,     0,    98,    88,
-       0,     0,     0,     0,    99,     0,     0,     0,     0,   100,
+      86,     0,     0,     0,     0,     0,    87,    98,     0,    88,
+       0,     0,     0,    99,     0,     0,     0,     0,   100,     0,
        0,     0,     0,    89,    90,     0,     0,     0,     0,     0,
        0,    91,     0,     0,    92,     0,     0,     0,     0,    33,
-      73,    34,    74,     0,     0,     0,     0,     0,     0,    93,
-       0,     0,     0,     0,     0,     0,    75,    76,     0,    94,
-       0,     0,    95,     0,     0,    96,    97,     0,     0,     0,
-      78,    79,     0,     0,     0,    98,   148,     0,    80,    81,
+      73,    34,    74,    78,    79,     0,     0,     0,     0,    93,
+       0,     0,     0,    82,     0,     0,    75,    76,     0,    94,
+      83,    84,    95,    85,     0,    96,    97,     0,    86,     0,
+      78,    79,     0,     0,     0,    98,   148,    88,    80,    81,
       82,    99,     0,     0,     0,     0,   100,    83,    84,     0,
-      85,     0,     0,     0,     0,    86,     0,     0,     0,     0,
-      87,     0,     0,    88,     0,     0,    33,    73,    34,    74,
-       0,     0,     0,     0,     0,     0,     0,    89,    90,     0,
-       0,     0,     0,    75,    76,    91,     0,     0,    92,     0,
-       0,     0,     0,     0,     0,     0,     0,    78,    79,     0,
-       0,     0,     0,    93,     0,    80,    81,    82,     0,     0,
-      10,     0,     0,    94,    83,    84,    95,    85,     0,    96,
-      97,     0,    86,     0,     0,     0,   203,    87,     0,    98,
-      88,     0,     0,     0,     0,    99,     0,     0,     0,     0,
-     100,     0,     0,     0,    89,    90,     0,     0,     0,     0,
-       0,     0,    91,     0,     0,    92,     0,     0,     0,     0,
-      33,    73,    34,    74,     0,     0,     0,     0,     0,     0,
-      93,     0,     0,     0,     0,     0,     0,    75,   176,     0,
-      94,     0,     0,    95,     0,     0,    96,    97,     0,     0,
-       0,    78,    79,     0,     0,     0,    98,     0,     0,    80,
-      81,    82,    99,     0,     0,     0,     0,   204,    83,    84,
-       0,    85,     0,     0,     0,     0,    86,     0,     0,     0,
+      85,    89,   247,     0,     0,    86,     0,     0,     0,    91,
        0,    87,     0,     0,    88,     0,     0,    33,    73,    34,
-      74,     0,     0,     0,     0,     0,     0,     0,    89,    90,
-       0,     0,     0,     0,    75,    76,    91,     0,     0,    92,
-       0,     0,     0,     0,     0,     0,     0,     0,    78,    79,
-       0,     0,     0,     0,    93,     0,    80,    81,    82,     0,
-       0,     0,     0,     0,    94,    83,    84,    95,    85,     0,
-      96,    97,     0,    86,     0,     0,     0,    33,    87,    34,
-      98,    88,     0,     0,     0,     0,    99,     0,     0,     0,
-       0,   100,     0,     0,     0,    89,    90,     0,     0,     0,
-       0,     0,     0,    91,     0,     0,    92,     0,    78,    79,
-       0,     0,     0,     0,     0,     0,     0,     0,    82,     0,
-       0,    93,     0,     0,     0,    83,    84,     0,    85,     0,
-       0,    94,     0,    86,    95,     0,     0,    96,    97,     0,
-       0,    88,     0,     0,     0,     0,     0,    98,     0,     0,
-       0,     0,     0,    99,     0,    89,   280,     0,   100,     0,
-       0,     0,    73,    91,    74,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    75,   176,
-       0,    93,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    94,    78,    79,     0,     0,     0,    96,    97,     0,
-       0,     0,    82,     0,    78,    79,     0,    98,     0,    83,
-      84,     0,    85,    99,    82,     0,     0,    86,     0,     0,
-       0,    83,    84,     0,    85,    88,     0,     0,     0,    86,
-       0,     0,     0,     0,     0,     0,     0,    88,     0,    89,
-      90,     0,     0,     0,     0,     0,     0,    91,     0,     0,
-      92,    89,   280,     0,     0,     0,     0,     0,     0,    91,
-       0,     0,     0,     0,     0,    93,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    94,     0,    93,     0,     0,
-       0,    96,    97,     0,     0,     0,     0,    94,     0,     0,
-       0,    98,     0,    96,    97,     0,     0,    99,     0,     0,
-       0,     0,     0,    98,     0,     0,     0,     0,     0,    99
+      74,     0,     0,     0,     0,     0,     0,    93,    89,    90,
+       0,     0,     0,     0,    75,    76,    91,    94,     0,    92,
+       0,     0,     0,    96,    97,     0,     0,     0,    78,    79,
+       0,     0,     0,    98,    93,     0,    80,    81,    82,    99,
+       0,    10,     0,     0,    94,    83,    84,    95,    85,     0,
+      96,    97,     0,    86,     0,     0,     0,     0,   204,    87,
+      98,     0,    88,     0,     0,     0,    99,     0,     0,     0,
+       0,   100,     0,     0,     0,     0,    89,    90,     0,     0,
+       0,     0,     0,     0,    91,     0,     0,    92,     0,     0,
+       0,     0,    33,    73,    34,    74,     0,     0,     0,     0,
+       0,     0,    93,     0,     0,     0,     0,     0,     0,    75,
+     177,     0,    94,     0,     0,    95,     0,     0,    96,    97,
+       0,     0,     0,    78,    79,     0,     0,     0,    98,     0,
+       0,    80,    81,    82,    99,     0,     0,     0,     0,   205,
+      83,    84,     0,    85,     0,     0,     0,     0,    86,     0,
+       0,     0,     0,     0,    87,     0,     0,    88,     0,     0,
+      33,    73,    34,    74,     0,     0,     0,     0,     0,     0,
+       0,    89,    90,     0,     0,     0,     0,    75,    76,    91,
+       0,     0,    92,     0,     0,     0,     0,     0,     0,     0,
+       0,    78,    79,     0,     0,     0,     0,    93,     0,    80,
+      81,    82,     0,     0,     0,     0,     0,    94,    83,    84,
+      95,    85,     0,    96,    97,     0,    86,     0,     0,     0,
+       0,     0,    87,    98,     0,    88,     0,     0,     0,    99,
+       0,     0,     0,     0,   100,     0,     0,     0,     0,    89,
+      90,     0,     0,     0,     0,     0,    73,    91,    74,     0,
+      92,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    75,   177,     0,    93,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    94,    78,    79,    95,     0,
+       0,    96,    97,     0,     0,     0,    82,     0,     0,     0,
+       0,    98,     0,    83,    84,     0,    85,    99,     0,     0,
+       0,    86,   100,     0,     0,     0,     0,     0,     0,     0,
+      88,   291,   292,   293,   294,   295,   296,   297,   298,   299,
+     300,     0,   166,   167,    89,    90,     0,     0,     0,     0,
+       0,     0,    91,     0,     0,    92,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      93,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      94,     0,     0,     0,     0,     0,    96,    97,     0,     0,
+       0,     0,     0,     0,     0,     0,    98,     0,     0,     0,
+     301,     0,    99
 };
 
 static const yytype_int16 yycheck[] =
 {
-       4,    12,   163,   278,   144,   140,   148,    11,    12,    44,
-       8,   211,   250,   148,    27,     4,   121,     6,     8,     4,
-       5,     6,     7,     5,     4,     4,     6,     6,    32,    29,
-       8,    59,     7,    37,    38,    39,    40,    41,     8,    46,
-      36,   234,    29,    28,    72,    80,    62,    23,    24,   201,
-      21,    22,    21,    22,   239,   136,     7,   122,   163,    67,
-     192,    79,   204,    62,    71,   100,   147,   202,    28,   204,
-      10,    21,    22,   234,    29,     4,    51,     6,   115,    21,
-      22,    66,    10,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,    75,    21,    22,    39,   133,   104,   203,    59,
-      51,     9,   106,   122,   122,    67,    21,    22,   145,   120,
-      95,    96,    84,    21,    22,   119,   120,   152,   122,   135,
-     124,    70,   157,   130,   107,    87,   115,   123,   136,   234,
-     165,   324,   145,   123,   138,   139,   135,   119,   120,   126,
-     144,   276,   127,   328,   179,   383,   146,   279,   146,    72,
-      78,   286,   287,    93,   129,   430,   145,    72,   310,   163,
-     145,   189,    10,   324,   168,   145,   145,   367,   146,   204,
-     408,   175,   148,   411,   178,   146,   146,   146,   129,   214,
-     188,   123,   217,   138,   128,   135,   115,   472,   192,   389,
-     194,   195,   196,   298,     4,    31,     6,   146,    46,   341,
-      54,   145,   440,   126,   344,    72,   341,    37,    56,     0,
-      40,    41,   497,    30,   354,   250,   164,    49,   146,   324,
-     141,   256,   143,    77,     4,    61,     6,    17,    18,    19,
-     234,   235,   180,   107,   116,   239,    73,    91,    92,   113,
-       0,     3,   403,    80,     4,    93,   446,    21,    22,    81,
-     254,    88,   147,    33,   258,     1,   104,     3,    33,    33,
-     114,   109,   297,   115,   299,   145,    26,   409,     9,   304,
-      84,   275,   276,   110,   409,   279,   381,   312,   418,   419,
-      21,    22,   130,   115,   105,   139,    32,   117,    78,   424,
-       5,   141,   434,    53,   144,    47,    48,   138,   403,   434,
-      96,    73,   337,    49,    50,   316,   310,   145,    80,   146,
-     136,    57,   316,    85,     7,    61,    88,    47,    48,     7,
-     324,   146,   147,   145,   328,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    81,    21,    22,   110,   145,
-     344,    83,   346,   145,   486,   380,    21,    22,   383,     5,
-     354,   486,   145,     4,     7,     6,   145,   392,     5,    34,
-     106,   146,   147,   146,   147,    83,   370,    21,    22,   115,
-      21,    22,    72,   408,   147,    99,   411,   146,   147,   146,
-     147,   145,    33,    58,   145,   131,     7,   146,   147,   146,
-     147,   145,   138,    78,     7,   141,   146,   147,   538,   403,
-      11,   146,   147,   146,   147,   440,   546,   442,   146,   147,
-       4,     5,     6,     7,   418,   419,     8,   146,   147,   145,
-     424,   146,   147,   146,   147,     9,   461,    21,    22,    23,
-     146,   147,   146,   147,   146,   147,   146,   147,   146,   147,
-      20,    35,    36,    63,   146,   480,    72,   146,   100,    43,
-      44,    45,   487,   147,   146,    74,   145,    86,    52,    53,
-     132,    55,    86,   145,   145,    59,    60,   133,   472,     7,
-      63,    65,     7,    98,    68,   479,    98,   512,    85,     7,
-      98,    42,    42,   146,   145,    76,   145,    97,    82,    83,
-      27,    93,   147,   497,   138,   145,    90,    86,    93,    93,
-     145,   102,   145,   102,   508,   146,   146,    97,    42,   145,
-     145,    38,   100,     7,   108,    96,   520,   147,    42,    89,
-      19,    42,   145,     7,   118,   137,   109,   121,    94,   146,
-     124,   125,   147,   111,   538,   103,   103,   146,     9,   145,
-     134,    33,   546,    69,    69,   145,   140,     4,     5,     6,
-       7,   145,   146,    10,   111,   101,     7,   373,   145,   346,
-     146,   120,    55,   254,    21,    22,    56,   165,   126,   403,
-     487,   510,   169,   286,   548,   512,   287,   117,    35,    36,
-     156,   215,   215,   446,    -1,   150,    43,    44,    45,   174,
-      -1,    -1,    -1,    -1,   202,    52,    53,    -1,    55,    -1,
-      -1,    -1,    -1,    60,    -1,    -1,    -1,    64,    65,    -1,
-      -1,    68,    -1,    -1,     4,     5,     6,     7,    -1,    -1,
-      10,    -1,    -1,    -1,    -1,    82,    83,    -1,    -1,    -1,
-      -1,    21,    22,    90,    -1,    -1,    93,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    35,    36,    -1,    -1,    -1,
-      -1,   108,    -1,    43,    44,    45,    -1,    -1,   115,    -1,
-      -1,   118,    52,    53,   121,    55,    -1,   124,   125,    -1,
-      60,    -1,    -1,    -1,    64,    65,    -1,   134,    68,    -1,
-      -1,    -1,    -1,   140,    -1,    -1,    -1,    -1,   145,    -1,
-      -1,    -1,    82,    83,    -1,    -1,    -1,    -1,    -1,    -1,
-      90,    -1,    -1,    93,    -1,    -1,    -1,    -1,     4,     5,
-       6,     7,    -1,    -1,    -1,    -1,    -1,    -1,   108,    -1,
-      -1,    -1,    -1,    -1,    -1,    21,    22,    23,   118,    -1,
-      -1,   121,    -1,    -1,   124,   125,    -1,    -1,    -1,    35,
-      36,    -1,    -1,    -1,   134,    -1,    -1,    43,    44,    45,
-     140,    -1,    -1,    -1,    -1,   145,    52,    53,    -1,    55,
-      -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,    65,
-      -1,    -1,    68,    -1,    -1,     4,     5,     6,     7,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    82,    83,    -1,    -1,
-      -1,    -1,    21,    22,    90,    -1,    -1,    93,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    35,    36,    -1,    -1,
-      -1,    -1,   108,    -1,    43,    44,    45,    -1,    -1,    -1,
-      -1,    -1,   118,    52,    53,   121,    55,    -1,   124,   125,
-      -1,    60,    -1,    -1,    -1,    -1,    65,    -1,   134,    68,
-      -1,    -1,    -1,    -1,   140,    -1,    -1,    -1,    -1,   145,
-      -1,    -1,    -1,    82,    83,    -1,    -1,    -1,    -1,    -1,
-      -1,    90,    -1,    -1,    93,    -1,    -1,    -1,    -1,     4,
-       5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,   108,
-      -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    -1,   118,
-      -1,    -1,   121,    -1,    -1,   124,   125,    -1,    -1,    -1,
-      35,    36,    -1,    -1,    -1,   134,   135,    -1,    43,    44,
-      45,   140,    -1,    -1,    -1,    -1,   145,    52,    53,    -1,
-      55,    -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,
-      65,    -1,    -1,    68,    -1,    -1,     4,     5,     6,     7,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    82,    83,    -1,
-      -1,    -1,    -1,    21,    22,    90,    -1,    -1,    93,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    35,    36,    -1,
-      -1,    -1,    -1,   108,    -1,    43,    44,    45,    -1,    -1,
-     115,    -1,    -1,   118,    52,    53,   121,    55,    -1,   124,
-     125,    -1,    60,    -1,    -1,    -1,    64,    65,    -1,   134,
-      68,    -1,    -1,    -1,    -1,   140,    -1,    -1,    -1,    -1,
-     145,    -1,    -1,    -1,    82,    83,    -1,    -1,    -1,    -1,
-      -1,    -1,    90,    -1,    -1,    93,    -1,    -1,    -1,    -1,
+       4,    12,   163,   282,   144,   148,   140,    11,    12,    44,
+     121,     4,     8,     6,   148,   212,     7,   254,     4,     5,
+       6,     7,    27,     4,     8,     6,    36,     4,    32,     6,
+     175,    59,    29,    37,    38,    39,    40,    41,   240,     8,
+      29,     8,    28,   123,    72,    80,    21,    22,    63,    71,
+      23,    24,   163,    21,    22,    21,    22,   202,   193,     7,
+      51,    80,   205,    10,    67,   100,   235,    21,    22,   203,
+      28,   205,     5,     4,   235,     6,    76,    39,    73,   147,
+     148,    67,   116,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,   204,    21,    22,    21,    22,   123,    29,
+     134,    59,   106,    51,   123,    31,   475,    68,   108,   120,
+      96,    97,   146,   123,    73,   119,   120,   152,   122,    73,
+     124,   136,   157,   116,   235,   147,   164,    88,    85,   331,
+     165,   500,   127,   136,   138,   139,    62,     0,   127,   130,
+     144,   146,   128,   181,    30,   180,   280,    94,   283,   386,
+     147,   147,    79,   146,   433,   289,   290,   124,   327,   163,
+     146,   136,   190,   147,   168,   146,   327,   129,   313,   146,
+     205,   175,   176,   370,   411,   179,   149,   414,   147,   147,
+     215,   147,   130,   218,   146,   116,   189,   120,   121,   193,
+     301,   195,   196,   197,     4,   392,     6,   137,    74,   124,
+      54,   344,    47,    48,    10,    81,   443,   347,   148,   139,
+     344,    46,    63,    89,    21,    22,   327,   357,     3,   254,
+     147,     9,    49,    33,    78,   260,    37,    34,   117,    40,
+      41,   235,   236,    21,    22,   111,   240,    72,    92,    93,
+      46,    21,    22,   108,     9,   406,     4,   148,     6,   114,
+      56,    58,   449,    33,   258,    82,    21,    22,   262,   147,
+     148,   115,    17,    18,    19,   300,    33,   302,   146,   412,
+     105,   147,   307,   384,   142,   279,   280,   145,   412,   283,
+     315,   421,   422,    47,    48,   136,   140,     0,    94,   116,
+     142,     4,   144,   427,   437,   406,   131,   147,   148,   105,
+      21,    22,   116,   437,   110,   340,    85,   118,   319,   313,
+     147,   148,   106,    26,   139,   319,   147,   148,     4,     1,
+       6,     3,    74,   327,    79,   131,     5,   331,    97,    81,
+     147,   148,   147,   148,    86,    21,    22,    89,   147,   148,
+      53,   146,   137,   347,     7,   349,   489,    33,   383,     7,
+      32,   386,    84,   357,   146,   489,   147,   148,     5,   111,
+     395,   147,   148,   147,   148,   147,   148,    49,    50,   373,
+     147,   148,   147,   148,   146,    57,   411,   147,   148,   414,
+      62,   147,   148,    84,   147,   148,   147,   148,   147,   148,
+     146,     5,   146,   146,    61,    73,     4,     5,     6,     7,
+      82,   541,   406,   148,   100,   146,     7,   146,   443,   549,
+     445,   146,     7,    21,    22,    23,     7,   421,   422,    11,
+     146,     8,    20,   427,     9,   107,    64,    35,    36,   464,
+     147,    73,   147,   101,   116,    43,    44,    45,   148,    75,
+     147,   146,    87,    87,    52,    53,   146,    55,   483,   133,
+     132,    59,    60,   146,   134,   490,     7,   139,    66,    64,
+     142,    69,    99,    86,    99,    99,     7,     7,    42,    42,
+      77,   475,   147,    98,   146,    83,    84,   146,   482,    27,
+     515,    94,   148,    91,   139,   146,    94,    87,    94,   146,
+     146,   103,   103,   147,   147,    98,   500,    42,   146,    38,
+     146,   109,   101,     4,     5,     6,     7,   511,     7,    10,
+      42,   119,    90,    97,   122,   148,    19,   125,   126,   523,
+      21,    22,   146,    42,     7,   147,   147,   135,   138,   148,
+     110,    95,   104,   141,    35,    36,   112,   541,   146,   147,
+       9,   104,    43,    44,    45,   549,    33,    70,    70,   146,
+     146,    52,    53,   146,    55,   112,   102,   147,     7,    60,
+     376,   258,   349,    55,    65,    66,   120,   126,    69,   513,
+      56,     4,     5,     6,     7,   551,   165,    10,   406,   490,
+     515,   289,    83,    84,   290,   203,   169,   117,    21,    22,
+      91,   156,   174,    94,   150,    -1,   216,    -1,    -1,   216,
+     449,    -1,    35,    36,    -1,    -1,    -1,    -1,   109,    -1,
+      43,    44,    45,    -1,    -1,   116,    -1,    -1,   119,    52,
+      53,   122,    55,    -1,   125,   126,    -1,    60,    -1,    -1,
+      -1,    -1,    65,    66,   135,    -1,    69,    -1,    -1,     4,
+     141,     6,    -1,    -1,    -1,   146,    -1,    -1,    -1,    -1,
+      83,    84,    -1,    -1,    -1,    -1,    -1,    -1,    91,    -1,
+      -1,    94,    -1,    -1,    -1,    -1,     4,     5,     6,     7,
+      35,    36,    -1,    -1,    -1,    -1,   109,    -1,    -1,    -1,
+      45,    -1,    -1,    21,    22,    23,   119,    52,    53,   122,
+      55,    -1,   125,   126,    -1,    60,    -1,    35,    36,    -1,
+      -1,    -1,   135,    -1,    69,    43,    44,    45,   141,    -1,
+      -1,    -1,    -1,   146,    52,    53,    -1,    55,    83,    84,
+      -1,    -1,    60,    -1,    -1,    -1,    91,    -1,    66,    -1,
+      -1,    69,    -1,    -1,     4,     5,     6,     7,    -1,    -1,
+      -1,    -1,    -1,    -1,   109,    83,    84,    -1,    -1,    -1,
+      -1,    21,    22,    91,   119,    -1,    94,    -1,    -1,    -1,
+     125,   126,    -1,    -1,    -1,    35,    36,    -1,    -1,    -1,
+     135,   109,    -1,    43,    44,    45,   141,    -1,    -1,    -1,
+      -1,   119,    52,    53,   122,    55,    -1,   125,   126,    -1,
+      60,    -1,    -1,    -1,    -1,    -1,    66,   135,    -1,    69,
+      -1,    -1,    -1,   141,    -1,    -1,    -1,    -1,   146,    -1,
+      -1,    -1,    -1,    83,    84,    -1,    -1,    -1,    -1,    -1,
+      -1,    91,    -1,    -1,    94,    -1,    -1,    -1,    -1,     4,
+       5,     6,     7,    35,    36,    -1,    -1,    -1,    -1,   109,
+      -1,    -1,    -1,    45,    -1,    -1,    21,    22,    -1,   119,
+      52,    53,   122,    55,    -1,   125,   126,    -1,    60,    -1,
+      35,    36,    -1,    -1,    -1,   135,   136,    69,    43,    44,
+      45,   141,    -1,    -1,    -1,    -1,   146,    52,    53,    -1,
+      55,    83,    84,    -1,    -1,    60,    -1,    -1,    -1,    91,
+      -1,    66,    -1,    -1,    69,    -1,    -1,     4,     5,     6,
+       7,    -1,    -1,    -1,    -1,    -1,    -1,   109,    83,    84,
+      -1,    -1,    -1,    -1,    21,    22,    91,   119,    -1,    94,
+      -1,    -1,    -1,   125,   126,    -1,    -1,    -1,    35,    36,
+      -1,    -1,    -1,   135,   109,    -1,    43,    44,    45,   141,
+      -1,   116,    -1,    -1,   119,    52,    53,   122,    55,    -1,
+     125,   126,    -1,    60,    -1,    -1,    -1,    -1,    65,    66,
+     135,    -1,    69,    -1,    -1,    -1,   141,    -1,    -1,    -1,
+      -1,   146,    -1,    -1,    -1,    -1,    83,    84,    -1,    -1,
+      -1,    -1,    -1,    -1,    91,    -1,    -1,    94,    -1,    -1,
+      -1,    -1,     4,     5,     6,     7,    -1,    -1,    -1,    -1,
+      -1,    -1,   109,    -1,    -1,    -1,    -1,    -1,    -1,    21,
+      22,    -1,   119,    -1,    -1,   122,    -1,    -1,   125,   126,
+      -1,    -1,    -1,    35,    36,    -1,    -1,    -1,   135,    -1,
+      -1,    43,    44,    45,   141,    -1,    -1,    -1,    -1,   146,
+      52,    53,    -1,    55,    -1,    -1,    -1,    -1,    60,    -1,
+      -1,    -1,    -1,    -1,    66,    -1,    -1,    69,    -1,    -1,
        4,     5,     6,     7,    -1,    -1,    -1,    -1,    -1,    -1,
-     108,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,    -1,
-     118,    -1,    -1,   121,    -1,    -1,   124,   125,    -1,    -1,
-      -1,    35,    36,    -1,    -1,    -1,   134,    -1,    -1,    43,
-      44,    45,   140,    -1,    -1,    -1,    -1,   145,    52,    53,
-      -1,    55,    -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,
-      -1,    65,    -1,    -1,    68,    -1,    -1,     4,     5,     6,
-       7,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    82,    83,
-      -1,    -1,    -1,    -1,    21,    22,    90,    -1,    -1,    93,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    35,    36,
-      -1,    -1,    -1,    -1,   108,    -1,    43,    44,    45,    -1,
-      -1,    -1,    -1,    -1,   118,    52,    53,   121,    55,    -1,
-     124,   125,    -1,    60,    -1,    -1,    -1,     4,    65,     6,
-     134,    68,    -1,    -1,    -1,    -1,   140,    -1,    -1,    -1,
-      -1,   145,    -1,    -1,    -1,    82,    83,    -1,    -1,    -1,
-      -1,    -1,    -1,    90,    -1,    -1,    93,    -1,    35,    36,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    45,    -1,
-      -1,   108,    -1,    -1,    -1,    52,    53,    -1,    55,    -1,
-      -1,   118,    -1,    60,   121,    -1,    -1,   124,   125,    -1,
-      -1,    68,    -1,    -1,    -1,    -1,    -1,   134,    -1,    -1,
-      -1,    -1,    -1,   140,    -1,    82,    83,    -1,   145,    -1,
-      -1,    -1,     5,    90,     7,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    21,    22,
-      -1,   108,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   118,    35,    36,    -1,    -1,    -1,   124,   125,    -1,
-      -1,    -1,    45,    -1,    35,    36,    -1,   134,    -1,    52,
-      53,    -1,    55,   140,    45,    -1,    -1,    60,    -1,    -1,
-      -1,    52,    53,    -1,    55,    68,    -1,    -1,    -1,    60,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    68,    -1,    82,
-      83,    -1,    -1,    -1,    -1,    -1,    -1,    90,    -1,    -1,
-      93,    82,    83,    -1,    -1,    -1,    -1,    -1,    -1,    90,
-      -1,    -1,    -1,    -1,    -1,   108,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,   118,    -1,   108,    -1,    -1,
-      -1,   124,   125,    -1,    -1,    -1,    -1,   118,    -1,    -1,
-      -1,   134,    -1,   124,   125,    -1,    -1,   140,    -1,    -1,
-      -1,    -1,    -1,   134,    -1,    -1,    -1,    -1,    -1,   140
+      -1,    83,    84,    -1,    -1,    -1,    -1,    21,    22,    91,
+      -1,    -1,    94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    35,    36,    -1,    -1,    -1,    -1,   109,    -1,    43,
+      44,    45,    -1,    -1,    -1,    -1,    -1,   119,    52,    53,
+     122,    55,    -1,   125,   126,    -1,    60,    -1,    -1,    -1,
+      -1,    -1,    66,   135,    -1,    69,    -1,    -1,    -1,   141,
+      -1,    -1,    -1,    -1,   146,    -1,    -1,    -1,    -1,    83,
+      84,    -1,    -1,    -1,    -1,    -1,     5,    91,     7,    -1,
+      94,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    21,    22,    -1,   109,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,   119,    35,    36,   122,    -1,
+      -1,   125,   126,    -1,    -1,    -1,    45,    -1,    -1,    -1,
+      -1,   135,    -1,    52,    53,    -1,    55,   141,    -1,    -1,
+      -1,    60,   146,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      69,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    -1,    21,    22,    83,    84,    -1,    -1,    -1,    -1,
+      -1,    -1,    91,    -1,    -1,    94,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     109,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     119,    -1,    -1,    -1,    -1,    -1,   125,   126,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   135,    -1,    -1,    -1,
+      79,    -1,   141
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint16 yystos[] =
 {
-       0,     1,     3,    32,    49,    50,    57,    61,    81,   106,
-     115,   131,   138,   141,   150,   151,   152,   153,   154,   155,
-     156,   178,   179,   182,   183,   186,   188,   191,   192,   193,
-     258,   259,   122,     4,     6,   191,   256,    79,   122,    72,
-     122,    84,    28,    59,   194,   256,   189,   190,   205,   256,
-       0,   141,   143,    49,    81,   191,    29,   138,   187,    30,
-     141,   144,     3,   256,   126,   180,    72,   180,   256,   256,
-     256,   256,   256,     5,     7,    21,    22,    23,    35,    36,
-      43,    44,    45,    52,    53,    55,    60,    65,    68,    82,
-      83,    90,    93,   108,   118,   121,   124,   125,   134,   140,
-     145,   159,   195,   196,   197,   199,   231,   232,   233,   234,
-     235,   236,   237,   238,   239,   246,   249,   252,   256,   116,
-     147,    33,   145,   191,    84,   187,   194,   105,   193,    31,
-      61,     5,   119,   120,   138,   181,     5,   181,    96,   145,
-     136,   225,   226,   133,   145,   193,     7,     7,   135,   231,
-     242,   243,   145,   145,    83,   145,     5,   145,   145,    83,
-     191,   231,     5,    72,   198,   147,    21,    22,    33,   253,
-     256,    23,    24,   148,   254,    99,    22,   234,    27,   145,
-     184,   185,   256,   190,   145,   199,   255,   256,   180,   256,
-     192,     7,    47,    48,    47,    48,   145,   181,   256,   157,
-     158,   256,    10,    64,   145,   227,   228,   229,   230,   231,
-     249,   145,   255,   227,   135,   240,   241,    62,   243,   244,
-     231,     7,    54,    77,    91,    92,   114,   139,   247,   247,
-     231,     7,   146,   146,   145,   199,   202,   203,   206,   235,
-     256,   225,   197,   256,   232,   233,   145,   256,   256,    23,
-      59,   146,   231,   245,   147,   225,    11,   146,   147,   181,
-     193,   157,    46,    71,   104,   130,   163,   256,   256,   170,
-     171,   172,   173,   174,   175,   256,   145,   166,   146,   147,
-      83,   159,   230,   199,   227,   231,     8,     9,    10,    11,
-      12,    13,    14,    15,    16,    17,    18,    19,    78,   251,
-      20,   246,   248,   146,   123,   231,   241,   244,   231,    63,
-      33,   146,    72,    72,   146,   202,    33,   204,   205,    73,
-      80,    88,   110,   201,   147,   204,    39,   128,   200,    74,
-     207,   100,   214,   215,   146,   245,   146,   147,   185,   231,
-     256,   145,    86,    86,   145,   146,   147,     5,     7,    28,
-      66,    95,    96,   127,   145,   256,   257,   249,   250,   256,
-     132,   163,   164,   165,   157,    10,    46,    56,    93,   104,
-     109,   130,   160,   161,   162,   146,   228,   229,    17,    18,
-      19,    78,   231,   145,   199,   231,    10,    93,   146,   147,
-     133,   231,   123,    63,   159,   256,   231,     7,   146,   205,
-      98,    98,    98,    85,   202,     7,     7,   204,    42,    76,
-     208,    42,   146,    97,   216,   146,   231,   227,   145,   145,
-     255,   171,   255,   146,   147,    37,    40,    41,   117,   176,
-     147,   138,   167,    93,   145,   246,    86,   256,   160,   231,
-     145,   199,     9,   245,    93,   246,   145,   231,   146,   146,
-     146,    70,   146,   203,   102,   102,   245,   227,    97,   209,
-     245,    42,   107,   113,   217,   218,   146,   255,   255,   146,
-     146,   249,   145,   177,   163,    38,   100,   168,   227,   145,
-       9,   245,   231,   146,   248,     7,    96,    42,    89,   210,
-     221,   222,   231,    19,   146,   146,   170,   145,    42,   146,
-     256,   231,   146,   146,   146,   227,   221,     7,   137,   211,
-     212,   213,   147,    34,    58,   223,     7,    51,   129,   219,
-     109,   146,   170,    75,   107,   169,   146,   256,   213,   222,
-      94,   224,   103,   111,   103,     9,   256,   146,   145,    33,
-      67,    87,     7,    51,   129,   220,   145,   255,   145,    69,
-     111,    69,   255,   146,   214,   146,   101,   146,     7
+       0,     1,     3,    32,    49,    50,    57,    62,    82,   107,
+     116,   132,   139,   142,   151,   152,   153,   154,   155,   156,
+     157,   179,   180,   183,   184,   187,   189,   192,   193,   194,
+     259,   260,   123,     4,     6,   192,   257,    80,   123,    73,
+     123,    85,    28,    59,   195,   257,   190,   191,   206,   257,
+       0,   142,   144,    49,    82,   192,    29,   139,   188,    30,
+     142,   145,     3,   257,   127,   181,    73,   181,   257,   257,
+     257,   257,   257,     5,     7,    21,    22,    23,    35,    36,
+      43,    44,    45,    52,    53,    55,    60,    66,    69,    83,
+      84,    91,    94,   109,   119,   122,   125,   126,   135,   141,
+     146,   160,   196,   197,   198,   200,   232,   233,   234,   235,
+     236,   237,   238,   239,   240,   247,   250,   253,   257,   117,
+     148,    33,   146,   192,    85,   188,   195,   106,   194,    31,
+      62,     5,   120,   121,   139,   182,     5,   182,    97,   146,
+     137,   226,   227,   134,   146,   194,     7,     7,   136,   232,
+     243,   244,   146,   146,    84,   146,     5,   146,   146,    84,
+     192,   232,     5,    73,   199,   148,    21,    22,    33,   254,
+     257,    23,    24,   149,   255,    61,   100,    22,   235,    27,
+     146,   185,   186,   257,   191,   146,   200,   256,   257,   181,
+     257,   193,     7,    47,    48,    47,    48,   146,   182,   257,
+     158,   159,   257,    10,    65,   146,   228,   229,   230,   231,
+     232,   250,   146,   256,   228,   136,   241,   242,    63,   244,
+     245,   232,     7,    54,    78,    92,    93,   115,   140,   248,
+     248,   232,     7,   147,   147,   146,   200,   203,   204,   207,
+     236,   257,   226,   198,   257,   233,   234,    84,   160,   257,
+     146,   257,   257,    23,    59,   147,   232,   246,   148,   226,
+      11,   147,   148,   182,   194,   158,    46,    72,   105,   131,
+     164,   257,   257,   171,   172,   173,   174,   175,   176,   257,
+     146,   167,   147,   148,   160,   231,   200,   228,   232,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    79,   252,    20,   247,   249,   147,   124,   232,   242,
+     245,   232,    64,    33,   147,    73,    73,   147,   203,    33,
+     205,   206,    74,    81,    89,   111,   202,   148,   205,    39,
+     129,   201,    75,   208,   101,   215,   216,   147,   246,   147,
+     148,   186,   232,   257,   146,    87,    87,   146,   147,   148,
+       5,     7,    28,    67,    96,    97,   128,   146,   257,   258,
+     250,   251,   257,   133,   164,   165,   166,   158,    10,    46,
+      56,    94,   105,   110,   131,   161,   162,   163,   147,   229,
+     230,    17,    18,    19,    79,   232,   146,   200,   232,    10,
+      94,   147,   148,   134,   232,   124,    64,   160,   257,   232,
+       7,   147,   206,    99,    99,    99,    86,   203,     7,     7,
+     205,    42,    77,   209,    42,   147,    98,   217,   147,   232,
+     228,   146,   146,   256,   172,   256,   147,   148,    37,    40,
+      41,   118,   177,   148,   139,   168,    94,   146,   247,    87,
+     257,   161,   232,   146,   200,     9,   246,    94,   247,   146,
+     232,   147,   147,   147,    71,   147,   204,   103,   103,   246,
+     228,    98,   210,   246,    42,   108,   114,   218,   219,   147,
+     256,   256,   147,   147,   250,   146,   178,   164,    38,   101,
+     169,   228,   146,     9,   246,   232,   147,   249,     7,    97,
+      42,    90,   211,   222,   223,   232,    19,   147,   147,   171,
+     146,    42,   147,   257,   232,   147,   147,   147,   228,   222,
+       7,   138,   212,   213,   214,   148,    34,    58,   224,     7,
+      51,   130,   220,   110,   147,   171,    76,   108,   170,   147,
+     257,   214,   223,    95,   225,   104,   112,   104,     9,   257,
+     147,   146,    33,    68,    88,     7,    51,   130,   221,   146,
+     256,   146,    70,   112,    70,   256,   147,   215,   147,   102,
+     147,     7
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint16 yyr1[] =
 {
-       0,   149,   150,   150,   150,   150,   150,   150,   151,   151,
-     151,   151,   151,   151,   151,   151,   151,   151,   152,   153,
-     153,   153,   153,   154,   155,   156,   157,   158,   158,   159,
-     159,   159,   159,   159,   159,   159,   159,   159,   159,   159,
-     159,   159,   159,   159,   159,   159,   159,   160,   160,   160,
-     160,   160,   160,   160,   161,   161,   162,   162,   163,   163,
-     163,   163,   164,   164,   165,   165,   166,   166,   167,   167,
-     168,   168,   169,   169,   170,   170,   171,   171,   171,   171,
-     172,   172,   172,   173,   174,   175,   176,   176,   176,   176,
-     177,   177,   178,   178,   178,   178,   179,   179,   179,   179,
-     180,   180,   180,   181,   181,   182,   183,   184,   184,   185,
-     186,   186,   187,   187,   188,   189,   189,   190,   191,   191,
-     192,   192,   193,   194,   194,   194,   195,   195,   196,   196,
-     197,   197,   197,   198,   199,   200,   200,   200,   201,   201,
-     201,   201,   201,   201,   201,   201,   202,   202,   203,   203,
-     203,   203,   203,   203,   204,   204,   205,   205,   206,   206,
-     207,   207,   208,   208,   209,   209,   210,   210,   211,   211,
-     212,   212,   213,   214,   215,   215,   216,   216,   217,   217,
-     218,   218,   219,   219,   219,   220,   220,   220,   221,   221,
-     222,   223,   223,   223,   224,   224,   224,   225,   225,   226,
-     227,   227,   228,   228,   229,   229,   230,   230,   230,   230,
-     230,   230,   230,   230,   230,   230,   230,   231,   231,   232,
-     232,   233,   233,   234,   234,   234,   234,   234,   234,   234,
-     234,   234,   234,   234,   235,   235,   235,   235,   236,   236,
-     237,   238,   238,   239,   239,   240,   240,   241,   242,   242,
-     243,   244,   244,   245,   245,   246,   246,   246,   246,   246,
-     246,   246,   246,   247,   247,   247,   247,   247,   247,   248,
-     248,   249,   249,   250,   250,   251,   251,   251,   251,   251,
-     251,   251,   251,   251,   251,   252,   253,   253,   254,   254,
-     254,   255,   255,   256,   256,   257,   257,   257,   257,   258,
-     259,   259
+       0,   150,   151,   151,   151,   151,   151,   151,   152,   152,
+     152,   152,   152,   152,   152,   152,   152,   152,   153,   154,
+     154,   154,   154,   155,   156,   157,   158,   159,   159,   160,
+     160,   160,   160,   160,   160,   160,   160,   160,   160,   160,
+     160,   160,   160,   160,   160,   160,   160,   161,   161,   161,
+     161,   161,   161,   161,   162,   162,   163,   163,   164,   164,
+     164,   164,   165,   165,   166,   166,   167,   167,   168,   168,
+     169,   169,   170,   170,   171,   171,   172,   172,   172,   172,
+     173,   173,   173,   174,   175,   176,   177,   177,   177,   177,
+     178,   178,   179,   179,   179,   179,   180,   180,   180,   180,
+     181,   181,   181,   182,   182,   183,   184,   185,   185,   186,
+     187,   187,   188,   188,   189,   190,   190,   191,   192,   192,
+     193,   193,   194,   195,   195,   195,   196,   196,   197,   197,
+     198,   198,   198,   199,   200,   201,   201,   201,   202,   202,
+     202,   202,   202,   202,   202,   202,   203,   203,   204,   204,
+     204,   204,   204,   204,   205,   205,   206,   206,   207,   207,
+     208,   208,   209,   209,   210,   210,   211,   211,   212,   212,
+     213,   213,   214,   215,   216,   216,   217,   217,   218,   218,
+     219,   219,   220,   220,   220,   221,   221,   221,   222,   222,
+     223,   224,   224,   224,   225,   225,   225,   226,   226,   227,
+     228,   228,   229,   229,   230,   230,   231,   231,   231,   231,
+     231,   231,   231,   231,   231,   231,   231,   232,   232,   233,
+     233,   234,   234,   235,   235,   235,   235,   235,   235,   235,
+     235,   235,   235,   235,   236,   236,   236,   236,   237,   237,
+     237,   237,   238,   239,   239,   240,   240,   241,   241,   242,
+     243,   243,   244,   245,   245,   246,   246,   247,   247,   247,
+     247,   247,   247,   247,   247,   248,   248,   248,   248,   248,
+     248,   249,   249,   250,   250,   251,   251,   252,   252,   252,
+     252,   252,   252,   252,   252,   252,   252,   253,   254,   254,
+     255,   255,   255,   256,   256,   257,   257,   258,   258,   258,
+     258,   259,   260,   260
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
@@ -1493,13 +1477,13 @@ static const yytype_uint8 yyr2[] =
        3,     3,     2,     3,     5,     4,     6,     3,     1,     3,
        1,     2,     1,     1,     1,     1,     3,     5,     1,     1,
        1,     1,     3,     1,     3,     4,     4,     5,     6,     6,
-       6,     6,     8,     5,     4,     1,     2,     4,     1,     2,
-       4,     0,     2,     1,     3,     1,     1,     2,     2,     1,
-       2,     3,     2,     1,     1,     1,     1,     1,     1,     1,
-       3,     1,     3,     1,     3,     1,     1,     1,     1,     1,
-       1,     1,     2,     1,     2,     1,     1,     1,     1,     1,
-       1,     1,     3,     1,     1,     1,     1,     1,     1,     2,
-       2,     0
+       3,     3,     6,     6,     8,     5,     4,     1,     2,     4,
+       1,     2,     4,     0,     2,     1,     3,     1,     1,     2,
+       2,     1,     2,     3,     2,     1,     1,     1,     1,     1,
+       1,     1,     3,     1,     3,     1,     3,     1,     1,     1,
+       1,     1,     1,     1,     2,     1,     2,     1,     1,     1,
+       1,     1,     1,     1,     3,     1,     1,     1,     1,     1,
+       1,     2,     2,     0
 };
 
 
@@ -1996,1093 +1980,1093 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocatio
   switch (yytype)
     {
           case 3: /* TOKEN_COMMAND  */
-#line 625 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 626 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2006 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 1990 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 4: /* TOKEN_NAME  */
-#line 625 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 626 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2016 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2000 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 5: /* TOKEN_STRING_SINGLE_QUOTED  */
-#line 625 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 626 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2026 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2010 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 6: /* TOKEN_STRING_DOUBLE_QUOTED  */
-#line 625 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 626 "../SqlParser.ypp" /* yacc.c:1257  */
       {
   if (((*yyvaluep).string_value_) != nullptr) {
     delete ((*yyvaluep).string_value_);
   }
 }
-#line 2036 "SqlParser_gen.cpp" /* yacc.c:1257  */
+#line 2020 "SqlParser_gen.cpp" /* yacc.c:1257  */
         break;
 
     case 7: /* TOKEN_UNSIGNED_NUMVAL  */
-#line 625 "../SqlParser.ypp" /* yacc.c:1257  */
+#line 626 "../SqlParser.ypp" /* yacc.c:1257  */
  

<TRUNCATED>