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/11 18:38:41 UTC

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

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/query_optimizer/resolver/Resolver.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/resolver/Resolver.cpp b/query_optimizer/resolver/Resolver.cpp
index 2991568..ca3a874 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;
 }
 
@@ -1024,14 +1021,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 "
@@ -1169,8 +1167,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 "
@@ -1588,11 +1587,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);
@@ -2444,109 +2444,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);
@@ -2571,57 +2468,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),
@@ -2635,75 +2481,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();
@@ -2797,13 +2574,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) {
@@ -2941,13 +2720,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) {
@@ -2963,6 +2744,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,
@@ -2983,8 +2843,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;
@@ -2992,7 +2851,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));
@@ -3011,6 +2870,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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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/cb564509/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_