quickstep-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hakanmemiso...@apache.org
Subject [1/3] incubator-quickstep git commit: New type for fixed precision number: Decimal. [Forced Update!]
Date Thu, 23 Jun 2016 19:59:42 GMT
Repository: incubator-quickstep
Updated Branches:
  refs/heads/decimal-type 21e912c93 -> 0dd7978bb (forced update)


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/parser/preprocessed/SqlParser_gen.hpp
----------------------------------------------------------------------
diff --git a/parser/preprocessed/SqlParser_gen.hpp b/parser/preprocessed/SqlParser_gen.hpp
index 71e4332..c60b0e3 100644
--- a/parser/preprocessed/SqlParser_gen.hpp
+++ b/parser/preprocessed/SqlParser_gen.hpp
@@ -175,7 +175,7 @@ extern int quickstep_yydebug;
 
 union YYSTYPE
 {
-#line 118 "../SqlParser.ypp" /* yacc.c:1915  */
+#line 118 "../SqlParser.ypp" /* yacc.c:1909  */
 
   quickstep::ParseString *string_value_;
 
@@ -267,7 +267,7 @@ union YYSTYPE
   quickstep::PtrVector<quickstep::ParseSubqueryTableReference> *with_list_;
   quickstep::ParseSubqueryTableReference *with_list_element_;
 
-#line 271 "SqlParser_gen.hpp" /* yacc.c:1915  */
+#line 271 "SqlParser_gen.hpp" /* yacc.c:1909  */
 };
 
 typedef union YYSTYPE YYSTYPE;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 0ccdfd7..16a6f1e 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -35,6 +35,8 @@ add_library(quickstep_types_DateOperatorOverloads ../empty_src.cpp DateOperatorO
 add_library(quickstep_types_DatetimeIntervalType DatetimeIntervalType.cpp DatetimeIntervalType.hpp)
 add_library(quickstep_types_DatetimeLit ../empty_src.cpp DatetimeLit.hpp)
 add_library(quickstep_types_DatetimeType DatetimeType.cpp DatetimeType.hpp)
+add_library(quickstep_types_DecimalLit ../empty_src.cpp DecimalLit.hpp)
+add_library(quickstep_types_DecimalType DecimalType.cpp DecimalType.hpp)
 add_library(quickstep_types_DoubleType DoubleType.cpp DoubleType.hpp)
 add_library(quickstep_types_FloatType FloatType.cpp FloatType.hpp)
 add_library(quickstep_types_IntType IntType.cpp IntType.hpp)
@@ -94,6 +96,16 @@ target_link_libraries(quickstep_types_DatetimeType
                       quickstep_types_port_timegm
                       quickstep_utility_CheckSnprintf
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_types_DecimalType
+                      glog
+                      quickstep_types_DecimalLit
+                      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_DoubleType
                       quickstep_types_NullCoercibilityCheckMacro
                       quickstep_types_NumericSuperType
@@ -158,6 +170,7 @@ target_link_libraries(quickstep_types_TypeFactory
                       quickstep_types_CharType
                       quickstep_types_DatetimeIntervalType
                       quickstep_types_DatetimeType
+                      quickstep_types_DecimalType
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
                       quickstep_types_IntType
@@ -173,6 +186,7 @@ target_link_libraries(quickstep_types_TypedValue
                       farmhash
                       glog
                       quickstep_types_DatetimeLit
+                      quickstep_types_DecimalLit
                       quickstep_types_IntervalLit
                       quickstep_types_TypeID
                       quickstep_types_Type_proto
@@ -213,6 +227,8 @@ target_link_libraries(quickstep_types
                       quickstep_types_DatetimeIntervalType
                       quickstep_types_DatetimeLit
                       quickstep_types_DatetimeType
+                      quickstep_types_DecimalLit
+                      quickstep_types_DecimalType
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
                       quickstep_types_IntType
@@ -295,6 +311,17 @@ target_link_libraries(DatetimeType_unittest
                       quickstep_utility_MemStream)
 add_test(DatetimeType_unittest DatetimeType_unittest)
 
+add_executable(DecimalType_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/DecimalType_unittest.cpp")
+target_link_libraries(DecimalType_unittest
+                      gtest
+                      gtest_main
+                      quickstep_types_DecimalLit
+                      quickstep_types_DecimalType
+                      quickstep_types_Type
+                      quickstep_types_TypeFactory
+                      quickstep_types_TypedValue)
+add_test(DecimalType_unittest DecimalType_unittest)
+
 add_executable(DoubleType_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/DoubleType_unittest.cpp")
 target_link_libraries(DoubleType_unittest
                       glog

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/DecimalLit.hpp
----------------------------------------------------------------------
diff --git a/types/DecimalLit.hpp b/types/DecimalLit.hpp
new file mode 100644
index 0000000..db21b4d
--- /dev/null
+++ b/types/DecimalLit.hpp
@@ -0,0 +1,293 @@
+/**
+ *   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.
+ *   limitations under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_DECIMAL_LIT_HPP_
+#define QUICKSTEP_TYPES_DECIMAL_LIT_HPP_
+
+#include <cstdint>
+#include <cmath>
+
+namespace quickstep {
+
+/** \addtogroup Type
+ *  @{
+ */
+
+/**
+ * @brief A literal representing fixed-precision decimal.
+ **/
+struct DecimalLit {
+  /**
+   * @brief Underlying data type.
+   **/
+  typedef std::int64_t data_type;
+
+  DecimalLit() = default;
+
+  explicit DecimalLit(const int value)
+    : data_(static_cast<data_type>(value * kMaxFractionInt)) {
+  }
+
+  explicit DecimalLit(const std::int64_t value)
+    : data_(static_cast<data_type>(value * kMaxFractionInt)) {
+  }
+
+  explicit DecimalLit(const float value)
+    : data_(static_cast<data_type>(value * kMaxFractionInt)) {
+  }
+
+  explicit DecimalLit(const double value)
+    : data_(static_cast<data_type>(value * kMaxFractionInt)) {
+  }
+
+  inline explicit operator int() const {
+    return static_cast<int>(getIntegerPart());
+  }
+
+  inline explicit operator std::int64_t() const {
+    return static_cast<std::int64_t>(getIntegerPart());
+  }
+
+  inline explicit operator float() const {
+    return static_cast<float>(data_) / kMaxFractionInt;
+  }
+
+  inline explicit operator double() const {
+    return static_cast<double>(data_) / kMaxFractionInt;
+  }
+
+  data_type data_;
+
+  /**
+   * @brief Number of decimals after point.
+   **/
+  static constexpr std::int64_t kPrecisionWidth = 2;
+
+  /**
+   * @brief Normalization factor between Decimal type and floating point types.
+   *        It is always equal to pow(10, kPrecisionWidth).
+   **/
+  static constexpr std::int64_t kMaxFractionInt = 100;
+
+  /**
+   * @brief Getter for the fractional part of the Decimal type.
+   *
+   * @return Fractional part of the Decimal number as unsigned.
+   **/
+  inline std::uint64_t getFractionalPart() const {
+    return static_cast<std::uint64_t>(static_cast<std::uint64_t>(std::abs(data_)) % kMaxFractionInt);
+  }
+
+  /**
+   * @brief Getter for the integer part of the Decimal type.
+   *
+   * @return Integer part of the Decimal number as signed.
+   **/
+  inline std::int64_t getIntegerPart() const {
+    return static_cast<std::int64_t>(data_ / kMaxFractionInt);
+  }
+
+  /**
+   * @brief Operator overloading for "less than".
+   *
+   * @param other Other DecimalLit to be compared.
+   * @return True if this is less than other,
+   *         false otherwise.
+   **/
+  inline bool operator<(const DecimalLit& other) const {
+    return data_ < other.data_;
+  }
+
+  /**
+   * @brief Operator overloading for "greater than".
+   *
+   * @param other Other DecimalLit to be compared.
+   * @return True if this is greater than other,
+   *         false otherwise.
+   **/
+  inline bool operator>(const DecimalLit& other) const {
+    return data_ > other.data_;
+  }
+
+  /**
+   * @brief Operator overloading for "less than or equal to".
+   *
+   * @param other Other DecimalLit to be compared.
+   * @return True if this is less than or equal to other,
+   *         false otherwise.
+   **/
+  inline bool operator<=(const DecimalLit& other) const {
+    return data_ <= other.data_;
+  }
+
+  /**
+   * @brief Operator overloading for "greater than or equal to".
+   *
+   * @param other Other DecimalLit to be compared.
+   * @return True if this is greater than or equal to other,
+   *         false otherwise.
+   **/
+  inline bool operator>=(const DecimalLit& other) const {
+    return data_ >= other.data_;
+  }
+
+  /**
+   * @brief Operator overloading for "equal to".
+   *
+   * @param other Other DecimalLit to be compared.
+   * @return True if this is equal to other,
+   *         false otherwise.
+   **/
+  inline bool operator==(const DecimalLit& other) const {
+    return data_ == other.data_;
+  }
+
+  /**
+   * @brief Operator overloading for "not equal to".
+   *
+   * @param other Other DecimalLit to be compared.
+   * @return True if this is not equal to other,
+   *         false otherwise.
+   **/
+  inline bool operator!=(const DecimalLit& other) const {
+    return data_ != other.data_;
+  }
+
+  /**
+   * @brief Operator overloading for "negate".
+   *
+   * @return Negative of this.
+   **/
+  inline DecimalLit operator-() const {
+    DecimalLit result;
+    result.data_ = -result.data_;
+    return result;
+  }
+
+  /**
+   * @brief Operator overloading for "plus".
+   *
+   * @param other Other DecimalLit to be added.
+   * @return Sum of this and other.
+   **/
+  inline DecimalLit operator+(const DecimalLit& other) const {
+    DecimalLit result;
+    result.data_ = data_ + other.data_;
+    return result;
+  }
+
+  /**
+   * @brief Operator overloading for "subtract".
+   *
+   * @param other Other DecimalLit to be subtract.
+   * @return Subtraction of other from this.
+   **/
+  inline DecimalLit operator-(const DecimalLit& other) const {
+    DecimalLit result;
+    result.data_ = data_ - other.data_;
+    return result;
+  }
+
+  /**
+   * @brief Operator overloading for "multiply".
+   *
+   * @param other Other DecimalLit to be multiplied.
+   * @return Multiplication of this and other.
+   **/
+  inline DecimalLit operator*(const DecimalLit& other) const {
+    DecimalLit result;
+    result.data_ = (data_ * other.data_) / kMaxFractionInt;
+    return result;
+  }
+
+  /**
+   * @brief Operator overloading for "division".
+   *
+   * @param other Divisor DecimalLit.
+   * @return Division of this with other.
+   **/
+  inline DecimalLit operator/(const DecimalLit& other) const {
+    DecimalLit result;
+    result.data_ = (data_ * kMaxFractionInt) / other.data_;
+    return result;
+  }
+
+  /**
+   * @brief Operator overloading for "modulo".
+   *
+   * @param other Mod DecimalLit.
+   * @return This modulo other.
+   **/
+  inline DecimalLit operator%(const DecimalLit& other) const {
+    DecimalLit result;
+    result.data_ = data_ % other.data_;
+    return result;
+  }
+
+  /**
+   * @brief Operator overloading for "inplace add".
+   *
+   * @param other DecimalLit to be added.
+   * @return Reference to this.
+   **/
+  inline DecimalLit& operator+=(const DecimalLit& other) {
+    data_ += other.data_;
+    return *this;
+  }
+
+  /**
+   * @brief Operator overloading for "inplace subtract".
+   *
+   * @param other DecimalLit to be subtracted.
+   * @return Reference to this.
+   **/
+  inline DecimalLit& operator-=(const DecimalLit& other) {
+    data_ -= other.data_;
+    return *this;
+  }
+
+  /**
+   * @brief Operator overloading for "inplace multiply".
+   *
+   * @param other DecimalLit to be multiplied.
+   * @return Reference to this.
+   **/
+  inline DecimalLit& operator*=(const DecimalLit& other) {
+    data_ = (data_ * other.data_) / kMaxFractionInt;
+    return *this;
+  }
+
+  /**
+   * @brief Operator overloading for "inplace divide".
+   *
+   * @param other DecimalLit to be divided.
+   * @return Reference to this.
+   **/
+  inline DecimalLit& operator/=(const DecimalLit& other) {
+    data_ = (data_ * kMaxFractionInt) / other.data_;
+    return *this;
+  }
+};
+
+//** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_DECIMAL_LIT_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/DecimalType.cpp
----------------------------------------------------------------------
diff --git a/types/DecimalType.cpp b/types/DecimalType.cpp
new file mode 100644
index 0000000..661dad1
--- /dev/null
+++ b/types/DecimalType.cpp
@@ -0,0 +1,120 @@
+/**
+ *   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.
+ *   limitations under the License.
+ **/
+
+#include "types/DecimalType.hpp"
+
+#include <cstdint>
+#include <cstdio>
+#include <iomanip>
+#include <string>
+#include <sstream>
+
+#include "types/DecimalLit.hpp"
+#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 {
+
+class Type;
+
+const TypeID DecimalType::kStaticTypeID = kDecimal;
+
+bool DecimalType::isSafelyCoercibleFrom(const Type &original_type) const {
+  QUICKSTEP_NULL_COERCIBILITY_CHECK();
+  return QUICKSTEP_EQUALS_ANY_CONSTANT(original_type.getTypeID(),
+                                       kInt, kDecimal);
+}
+
+TypedValue DecimalType::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(DecimalLit(original_value.getLiteral<int>()));
+    case kLong:
+      return TypedValue(DecimalLit(original_value.getLiteral<std::int64_t>()));
+    case kFloat:
+      return TypedValue(DecimalLit(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 DecimalType::printValueToString(const TypedValue &value) const {
+  DCHECK(!value.isNull());
+
+  DecimalLit decimal = value.getLiteral<DecimalLit>();
+  std::stringstream ss;
+  ss << decimal.getIntegerPart() << "."
+     << std::setfill('0') << std::setw(DecimalLit::kPrecisionWidth)
+     <<  decimal.getFractionalPart();
+  return ss.str();
+}
+
+void DecimalType::printValueToFile(const TypedValue &value,
+                                   FILE *file,
+                                   const int padding) const {
+  DCHECK(!value.isNull());
+
+  DecimalLit decimal = value.getLiteral<DecimalLit>();
+
+  std::fprintf(file, "%*ld.%0*lu",
+               static_cast<int>(padding -
+                                (DecimalLit::kPrecisionWidth
+                                 + 1 /* Less one space for point. */)),
+               decimal.getIntegerPart(),
+               static_cast<int>(DecimalLit::kPrecisionWidth),
+               decimal.getFractionalPart());
+}
+
+bool DecimalType::parseValueFromString(const std::string &value_string,
+                                       TypedValue *value) const {
+  double parsed_double;
+  int read_chars;
+
+  int matched = std::sscanf(value_string.c_str(),
+                            "%lf%n",
+                            &parsed_double,
+                            &read_chars);
+
+  if (matched != 1 || read_chars != static_cast<int>(value_string.length()))  {
+    return false;
+  }
+
+  *value = TypedValue(DecimalLit(parsed_double));
+  return true;
+}
+
+}  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/DecimalType.hpp
----------------------------------------------------------------------
diff --git a/types/DecimalType.hpp b/types/DecimalType.hpp
new file mode 100644
index 0000000..a028290
--- /dev/null
+++ b/types/DecimalType.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.
+ *   limitations under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_DECIMAL_TYPE_HPP_
+#define QUICKSTEP_TYPES_DECIMAL_TYPE_HPP_
+
+#include <limits>
+#include <string>
+
+#include "types/DecimalLit.hpp"
+#include "types/NumericSuperType.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "utility/Macros.hpp"
+
+namespace quickstep {
+
+class Type;
+
+/** \addtogroup Types
+ *  @{
+ */
+
+/**
+ * @brief A type representing a fixed-precision number.
+ **/
+class DecimalType : public NumericSuperType<DecimalLit> {
+ 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 DecimalType& InstanceNonNullable() {
+    static DecimalType 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 DecimalType& InstanceNullable() {
+    static DecimalType instance(true);
+    return instance;
+  }
+
+  static const DecimalType& 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;
+  }
+
+  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;
+
+  TypedValue coerceValue(const TypedValue &original_value,
+                         const Type &original_type) const override;
+
+  TypedValue makeZeroValue() const override {
+    return TypedValue(DecimalLit(0));
+  }
+
+ private:
+  static constexpr int kPrintWidth =
+      std::numeric_limits<DecimalLit::data_type>::digits10
+      + 1   // Decimal point '.'
+      + 1;  // Minus sign '-'
+
+  explicit DecimalType(const bool nullable)
+       : NumericSuperType<DecimalLit>(kDecimal, nullable) {
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(DecimalType);
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_DECIMAL_TYPE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index ec487e7..ac4183b 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -51,7 +51,7 @@ class NumericSuperType : public Type {
   }
 
   TypedValue makeZeroValue() const override {
-    return TypedValue(static_cast<CppType>(0));
+    return TypedValue(CppType());
   }
 
  protected:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/NumericTypeUnifier.hpp
----------------------------------------------------------------------
diff --git a/types/NumericTypeUnifier.hpp b/types/NumericTypeUnifier.hpp
index 6ea8510..c2fb949 100644
--- a/types/NumericTypeUnifier.hpp
+++ b/types/NumericTypeUnifier.hpp
@@ -19,6 +19,7 @@
 
 namespace quickstep {
 
+class DecimalType;
 class DoubleType;
 class FloatType;
 class IntType;
@@ -76,6 +77,11 @@ struct NumericTypeUnifier<IntType, DoubleType> {
 };
 
 template<>
+struct NumericTypeUnifier<IntType, DecimalType> {
+  typedef DecimalType type;
+};
+
+template<>
 struct NumericTypeUnifier<LongType, IntType> {
   typedef LongType type;
 };
@@ -96,6 +102,11 @@ struct NumericTypeUnifier<LongType, DoubleType> {
 };
 
 template<>
+struct NumericTypeUnifier<LongType, DecimalType> {
+  typedef DecimalType type;
+};
+
+template<>
 struct NumericTypeUnifier<FloatType, IntType> {
   typedef FloatType type;
 };
@@ -116,6 +127,11 @@ struct NumericTypeUnifier<FloatType, DoubleType> {
 };
 
 template<>
+struct NumericTypeUnifier<FloatType, DecimalType> {
+  typedef DecimalType type;
+};
+
+template<>
 struct NumericTypeUnifier<DoubleType, IntType> {
   typedef DoubleType type;
 };
@@ -135,6 +151,36 @@ struct NumericTypeUnifier<DoubleType, DoubleType> {
   typedef DoubleType type;
 };
 
+template<>
+struct NumericTypeUnifier<DoubleType, DecimalType> {
+  typedef DecimalType type;
+};
+
+template<>
+struct NumericTypeUnifier<DecimalType, IntType> {
+  typedef DecimalType type;
+};
+
+template<>
+struct NumericTypeUnifier<DecimalType, LongType> {
+  typedef DecimalType type;
+};
+
+template<>
+struct NumericTypeUnifier<DecimalType, FloatType> {
+  typedef DecimalType type;
+};
+
+template<>
+struct NumericTypeUnifier<DecimalType, DoubleType> {
+  typedef DecimalType type;
+};
+
+template<>
+struct NumericTypeUnifier<DecimalType, DecimalType> {
+  typedef DecimalType type;
+};
+
 }  // namespace quickstep
 
 #endif  // QUICKSTEP_TYPES_NUMERIC_TYPE_UNIFIER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/Type.cpp
----------------------------------------------------------------------
diff --git a/types/Type.cpp b/types/Type.cpp
index 8981bc2..4f199f1 100644
--- a/types/Type.cpp
+++ b/types/Type.cpp
@@ -41,6 +41,9 @@ serialization::Type Type::getProto() const {
     case kDouble:
       proto.set_type_id(serialization::Type::DOUBLE);
       break;
+    case kDecimal:
+      proto.set_type_id(serialization::Type::DECIMAL);
+      break;
     case kDatetime:
       proto.set_type_id(serialization::Type::DATETIME);
       break;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index fc6f4e2..33f38aa 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -34,6 +34,7 @@ namespace quickstep {
 
 struct DatetimeIntervalLit;
 struct DatetimeLit;
+struct DecimalLit;
 struct YearMonthIntervalLit;
 
 /** \addtogroup Types
@@ -370,6 +371,8 @@ class Type {
         return TypedValue(*static_cast<const float*>(value_ptr));
       case kDouble:
         return TypedValue(*static_cast<const double*>(value_ptr));
+      case kDecimal:
+        return TypedValue(*static_cast<const DecimalLit*>(value_ptr));
       case kDatetime:
         return TypedValue(*static_cast<const DatetimeLit*>(value_ptr));
       case kDatetimeInterval:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/Type.proto
----------------------------------------------------------------------
diff --git a/types/Type.proto b/types/Type.proto
index dbf248e..337d962 100644
--- a/types/Type.proto
+++ b/types/Type.proto
@@ -25,10 +25,11 @@ message Type {
     DOUBLE = 3;
     CHAR = 4;
     VAR_CHAR = 5;
-    DATETIME = 6;
-    DATETIME_INTERVAL = 7;
-    YEAR_MONTH_INTERVAL = 8;
-    NULL_TYPE = 9;
+    DECIMAL = 6;
+    DATETIME = 7;
+    DATETIME_INTERVAL = 8;
+    YEAR_MONTH_INTERVAL = 9;
+    NULL_TYPE = 10;
   }
 
   required TypeID type_id = 1;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index a8f2961..e0b52d8 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -22,6 +22,7 @@
 #include "types/CharType.hpp"
 #include "types/DatetimeIntervalType.hpp"
 #include "types/DatetimeType.hpp"
+#include "types/DecimalType.hpp"
 #include "types/DoubleType.hpp"
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
@@ -49,6 +50,8 @@ const Type& TypeFactory::GetType(const TypeID id,
       return FloatType::Instance(nullable);
     case kDouble:
       return DoubleType::Instance(nullable);
+    case kDecimal:
+      return DecimalType::Instance(nullable);
     case kDatetime:
       return DatetimeType::Instance(nullable);
     case kDatetimeInterval:
@@ -90,6 +93,7 @@ bool TypeFactory::ProtoIsValid(const serialization::Type &proto) {
     case serialization::Type::LONG:
     case serialization::Type::FLOAT:
     case serialization::Type::DOUBLE:
+    case serialization::Type::DECIMAL:
     case serialization::Type::DATETIME:
     case serialization::Type::DATETIME_INTERVAL:
     case serialization::Type::YEAR_MONTH_INTERVAL:
@@ -119,6 +123,8 @@ const Type& TypeFactory::ReconstructFromProto(const serialization::Type &proto)
       return FloatType::Instance(proto.nullable());
     case serialization::Type::DOUBLE:
       return DoubleType::Instance(proto.nullable());
+    case serialization::Type::DECIMAL:
+      return DecimalType::Instance(proto.nullable());
     case serialization::Type::DATETIME:
       return DatetimeType::Instance(proto.nullable());
     case serialization::Type::DATETIME_INTERVAL:
@@ -155,6 +161,8 @@ const Type* TypeFactory::GetUnifyingType(const Type &first, const Type &second)
       if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
             || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
         unifier = &(DoubleType::Instance(true));
+      } else if (first.getTypeID() == kDecimal || second.getTypeID() == kDecimal) {
+        unifier = &(DecimalType::Instance(true));
       }
     }
   } else {
@@ -163,6 +171,8 @@ const Type* TypeFactory::GetUnifyingType(const Type &first, const Type &second)
       if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
             || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {
         unifier = &(DoubleType::Instance(false));
+      } else if (first.getTypeID() == kDecimal || second.getTypeID() == kDecimal) {
+        unifier = &(DecimalType::Instance(false));
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/TypeFactory.hpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.hpp b/types/TypeFactory.hpp
index ed9be5e..029d2bb 100644
--- a/types/TypeFactory.hpp
+++ b/types/TypeFactory.hpp
@@ -52,6 +52,7 @@ class TypeFactory {
       case kLong:
       case kFloat:
       case kDouble:
+      case kDecimal:
       case kDatetime:
       case kDatetimeInterval:
       case kYearMonthInterval:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/TypeID.cpp
----------------------------------------------------------------------
diff --git a/types/TypeID.cpp b/types/TypeID.cpp
index 1aeea04..901b232 100644
--- a/types/TypeID.cpp
+++ b/types/TypeID.cpp
@@ -26,6 +26,7 @@ const char *kTypeNames[] = {
   "Double",
   "Char",
   "VarChar",
+  "Decimal",
   "Datetime",
   "DatetimeInterval",
   "YearMonthInterval",

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/TypeID.hpp
----------------------------------------------------------------------
diff --git a/types/TypeID.hpp b/types/TypeID.hpp
index 23d32da..ab52b96 100644
--- a/types/TypeID.hpp
+++ b/types/TypeID.hpp
@@ -34,6 +34,7 @@ enum TypeID {
   kDouble,
   kChar,
   kVarChar,
+  kDecimal,
   kDatetime,
   kDatetimeInterval,
   kYearMonthInterval,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/TypedValue.cpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.cpp b/types/TypedValue.cpp
index bc1ebd9..2989c37 100644
--- a/types/TypedValue.cpp
+++ b/types/TypedValue.cpp
@@ -49,6 +49,7 @@ bool TypedValue::isPlausibleInstanceOf(const TypeSignature type) const {
     case kLong:
     case kFloat:
     case kDouble:
+    case kDecimal:
     case kDatetime:
     case kDatetimeInterval:
     case kYearMonthInterval:
@@ -104,6 +105,12 @@ serialization::TypedValue TypedValue::getProto() const {
         proto.set_double_value(getLiteral<double>());
       }
       break;
+    case kDecimal:
+      proto.set_type_id(serialization::Type::DECIMAL);
+      if (!isNull()) {
+        proto.set_decimal_value(value_union_.decimal_value.data_);
+      }
+      break;
     case kDatetime:
       proto.set_type_id(serialization::Type::DATETIME);
       if (!isNull()) {
@@ -171,6 +178,15 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
       return proto.has_double_value() ?
           TypedValue(static_cast<double>(proto.double_value())) :
           TypedValue(kDouble);
+    case serialization::Type::DECIMAL: {
+      if (proto.has_decimal_value()) {
+        DecimalLit result;
+        result.data_ = proto.decimal_value();
+        return TypedValue(result);
+      } else {
+        return TypedValue(kDecimal);
+      }
+    }
     case serialization::Type::DATETIME:
       if (proto.has_datetime_value()) {
         DatetimeLit datetime;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/TypedValue.hpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.hpp b/types/TypedValue.hpp
index 6e22111..06d69ad 100644
--- a/types/TypedValue.hpp
+++ b/types/TypedValue.hpp
@@ -25,6 +25,7 @@
 #include <functional>
 
 #include "types/DatetimeLit.hpp"
+#include "types/DecimalLit.hpp"
 #include "types/IntervalLit.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.pb.h"
@@ -126,6 +127,11 @@ class TypedValue {
     value_union_.double_value = literal_double == 0 ? 0 : literal_double;
   }
 
+  explicit TypedValue(const DecimalLit literal_decimal)
+      : value_info_(static_cast<std::uint64_t>(kDecimal)) {
+    value_union_.decimal_value = literal_decimal;
+  }
+
   /**
    * @brief Constructor for a literal value of DatetimeType.
    **/
@@ -276,6 +282,7 @@ class TypedValue {
       case kLong:
       case kFloat:
       case kDouble:
+      case kDecimal:
       case kDatetime:
       case kDatetimeInterval:
       case kYearMonthInterval:
@@ -307,6 +314,7 @@ class TypedValue {
         return sizeof(value_union_.int_value) <= sizeof(std::size_t);
       case kLong:
       case kDouble:
+      case kDecimal:
       case kDatetime:
       case kDatetimeInterval:
       case kYearMonthInterval:
@@ -384,6 +392,7 @@ class TypedValue {
         return sizeof(int);
       case kLong:
       case kDouble:
+      case kDecimal:
       case kDatetime:
       case kDatetimeInterval:
       case kYearMonthInterval:
@@ -469,6 +478,7 @@ class TypedValue {
                    || getTypeID() == kLong
                    || getTypeID() == kFloat
                    || getTypeID() == kDouble
+                   || getTypeID() == kDecimal
                    || getTypeID() == kDatetime
                    || getTypeID() == kDatetimeInterval
                    || getTypeID() == kYearMonthInterval));
@@ -564,6 +574,7 @@ class TypedValue {
       case kLong:
       case kFloat:
       case kDouble:
+      case kDecimal:
       case kDatetime:
       case kDatetimeInterval:
       case kYearMonthInterval:
@@ -659,6 +670,7 @@ class TypedValue {
       case kLong:
       case kFloat:
       case kDouble:
+      case kDecimal:
       case kDatetime:
       case kDatetimeInterval:
       case kYearMonthInterval:
@@ -778,6 +790,7 @@ class TypedValue {
     float float_value;
     double double_value;
     const void* out_of_line_data;
+    DecimalLit decimal_value;
     DatetimeLit datetime_value;
     DatetimeIntervalLit datetime_interval_value;
     YearMonthIntervalLit year_month_interval_value;
@@ -804,6 +817,7 @@ class TypedValue {
 
   static_assert(sizeof(ValueUnion) == sizeof(std::int64_t)
                     && sizeof(ValueUnion) == sizeof(double)
+                    && sizeof(ValueUnion) == sizeof(DecimalLit)
                     && sizeof(ValueUnion) == sizeof(DatetimeLit)
                     && sizeof(ValueUnion) == sizeof(DatetimeIntervalLit)
                     && sizeof(ValueUnion) == sizeof(YearMonthIntervalLit),
@@ -853,6 +867,13 @@ inline double TypedValue::getLiteral<double>() const {
 }
 
 template <>
+inline DecimalLit TypedValue::getLiteral<DecimalLit>() const {
+  DCHECK_EQ(kDecimal, getTypeID());
+  DCHECK(!isNull());
+  return value_union_.decimal_value;
+}
+
+template <>
 inline DatetimeLit TypedValue::getLiteral<DatetimeLit>() const {
   DCHECK_EQ(kDatetime, getTypeID());
   DCHECK(!isNull());

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/TypedValue.proto
----------------------------------------------------------------------
diff --git a/types/TypedValue.proto b/types/TypedValue.proto
index 78a38cb..a2b52f3 100644
--- a/types/TypedValue.proto
+++ b/types/TypedValue.proto
@@ -28,7 +28,8 @@ message TypedValue {
   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 int64 decimal_value = 7;
+  optional int64 datetime_value = 8;
+  optional int64 datetime_interval_value = 9;
+  optional int64 year_month_interval_value = 10;
 }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/binary_operations/AddBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/AddBinaryOperation.cpp b/types/operations/binary_operations/AddBinaryOperation.cpp
index 6e6e839..18118d0 100644
--- a/types/operations/binary_operations/AddBinaryOperation.cpp
+++ b/types/operations/binary_operations/AddBinaryOperation.cpp
@@ -44,7 +44,8 @@ bool AddBinaryOperation::canApplyToTypes(const Type &left, const Type &right) co
     case kInt:  // Fall through.
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       return (right.getSuperTypeID() == Type::kNumeric);
     }
     case kDatetime: {
@@ -229,12 +230,14 @@ TypedValue AddBinaryOperation::applyToChecked(const TypedValue &left,
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       switch (right_type.getTypeID()) {
         case kInt:
         case kLong:
         case kFloat:
         case kDouble:
+        case kDecimal:
           return applyToCheckedNumericHelper<AddFunctor>(left, left_type,
                                                          right, right_type);
         default:
@@ -304,7 +307,8 @@ UncheckedBinaryOperator* AddBinaryOperation::makeUncheckedBinaryOperatorForTypes
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       if (right.getSuperTypeID() == Type::kNumeric) {
         return makeNumericBinaryOperatorOuterHelper<AddArithmeticUncheckedBinaryOperator>(left, right);
       }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/binary_operations/ArithmeticBinaryOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryOperation.hpp b/types/operations/binary_operations/ArithmeticBinaryOperation.hpp
index 3cad289..931c805 100644
--- a/types/operations/binary_operations/ArithmeticBinaryOperation.hpp
+++ b/types/operations/binary_operations/ArithmeticBinaryOperation.hpp
@@ -22,6 +22,7 @@
 
 #include <string>
 
+#include "types/DecimalType.hpp"
 #include "types/DoubleType.hpp"
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
@@ -309,6 +310,14 @@ UncheckedBinaryOperator* ArithmeticBinaryOperation::makeNumericBinaryOperatorOut
         return makeNumericBinaryOperatorInnerHelper<OperatorType, DoubleType, false>(
             left, right);
       }
+    case kDecimal:
+      if (left.isNullable()) {
+        return makeNumericBinaryOperatorInnerHelper<OperatorType, DecimalType,
+                                                    true>(left, right);
+      } else {
+        return makeNumericBinaryOperatorInnerHelper<OperatorType, DecimalType,
+                                                    false>(left, right);
+      }
     default:
       throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
   }
@@ -362,6 +371,16 @@ UncheckedBinaryOperator* ArithmeticBinaryOperation::makeNumericBinaryOperatorInn
                                 typename LeftType::cpptype, left_nullable,
                                 typename DoubleType::cpptype, false>();
       }
+    case kDecimal:
+      if (right.isNullable()) {
+        return new OperatorType<typename NumericTypeUnifier<LeftType, DecimalType>::type,
+                                typename LeftType::cpptype, left_nullable,
+                                typename DecimalType::cpptype, true>();
+      } else {
+        return new OperatorType<typename NumericTypeUnifier<LeftType, DecimalType>::type,
+                                typename LeftType::cpptype, left_nullable,
+                                typename DecimalType::cpptype, false>();
+      }
     default:
       throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/binary_operations/ArithmeticBinaryOperators.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryOperators.hpp b/types/operations/binary_operations/ArithmeticBinaryOperators.hpp
index e5e1493..408a16b 100644
--- a/types/operations/binary_operations/ArithmeticBinaryOperators.hpp
+++ b/types/operations/binary_operations/ArithmeticBinaryOperators.hpp
@@ -35,6 +35,7 @@
 #include "storage/ValueAccessorUtil.hpp"
 #endif  // QUICKSTEP_ENABLE_VECTOR_COPY_ELISION_SELECTION
 
+#include "types/DecimalLit.hpp"
 #include "types/TypedValue.hpp"
 #include "types/containers/ColumnVector.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
@@ -75,6 +76,27 @@ struct AddFunctor<float, std::int64_t> {
   }
 };
 
+template <>
+struct AddFunctor<DecimalLit, DecimalLit> {
+  inline DecimalLit operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left + right;
+  }
+};
+
+template <typename RightArgument>
+struct AddFunctor<DecimalLit, RightArgument> {
+  inline DecimalLit operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left + DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument>
+struct AddFunctor<LeftArgument, DecimalLit> {
+  inline DecimalLit operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) + right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct SubtractFunctor {
   inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left - right) {
     return left - right;
@@ -98,6 +120,27 @@ struct SubtractFunctor<float, std::int64_t> {
   }
 };
 
+template <>
+struct SubtractFunctor<DecimalLit, DecimalLit> {
+  inline DecimalLit operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left - right;
+  }
+};
+
+template <typename RightArgument>
+struct SubtractFunctor<DecimalLit, RightArgument> {
+  inline DecimalLit operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left - DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument>
+struct SubtractFunctor<LeftArgument, DecimalLit> {
+  inline DecimalLit operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) - right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct MultiplyFunctor {
   inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left * right) {
     return left * right;
@@ -121,6 +164,27 @@ struct MultiplyFunctor<float, std::int64_t> {
   }
 };
 
+template <>
+struct MultiplyFunctor<DecimalLit, DecimalLit> {
+  inline DecimalLit operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left * right;
+  }
+};
+
+template <typename RightArgument>
+struct MultiplyFunctor<DecimalLit, RightArgument> {
+  inline DecimalLit operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left * DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument>
+struct MultiplyFunctor<LeftArgument, DecimalLit> {
+  inline DecimalLit operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) * right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct DivideFunctor {
   inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left / right) {
     return left / right;
@@ -144,6 +208,27 @@ struct DivideFunctor<float, std::int64_t> {
   }
 };
 
+template <>
+struct DivideFunctor<DecimalLit, DecimalLit> {
+  inline DecimalLit operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left / right;
+  }
+};
+
+template <typename RightArgument>
+struct DivideFunctor<DecimalLit, RightArgument> {
+  inline DecimalLit operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left / DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument>
+struct DivideFunctor<LeftArgument, DecimalLit> {
+  inline DecimalLit operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) / right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct IntegerModuloFunctor {
   inline auto operator() (const LeftArgument &left, const RightArgument &right) const -> decltype(left % right) {
     return left % right;
@@ -162,6 +247,27 @@ template <typename LeftArgument, typename RightArgument> struct FloatModuloFunct
   }
 };
 
+template <>
+struct FloatModuloFunctor<DecimalLit, DecimalLit> {
+  inline DecimalLit operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left % right;
+  }
+};
+
+template <typename RightArgument>
+struct FloatModuloFunctor<DecimalLit, RightArgument> {
+  inline DecimalLit operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left % DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument>
+struct FloatModuloFunctor<LeftArgument, DecimalLit> {
+  inline DecimalLit operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) % right;
+  }
+};
+
 template <template <typename LeftCppType, typename RightCppType> class OpFunctor,
           typename ResultType,
           typename LeftCppType, bool left_nullable,

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/binary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMakeLists.txt b/types/operations/binary_operations/CMakeLists.txt
index 63db377..d503688 100644
--- a/types/operations/binary_operations/CMakeLists.txt
+++ b/types/operations/binary_operations/CMakeLists.txt
@@ -68,6 +68,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_AddBinaryOpera
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperation
                       glog
+                      quickstep_types_DecimalType
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
                       quickstep_types_IntType
@@ -87,6 +88,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBina
                       quickstep_storage_StorageBlockInfo
                       quickstep_storage_ValueAccessor
                       quickstep_storage_ValueAccessorUtil
+                      quickstep_types_DecimalLit
                       quickstep_types_TypedValue
                       quickstep_types_containers_ColumnVector
                       quickstep_types_operations_binaryoperations_BinaryOperation

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/binary_operations/DivideBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/DivideBinaryOperation.cpp b/types/operations/binary_operations/DivideBinaryOperation.cpp
index 23cbb99..2eb902c 100644
--- a/types/operations/binary_operations/DivideBinaryOperation.cpp
+++ b/types/operations/binary_operations/DivideBinaryOperation.cpp
@@ -47,6 +47,7 @@ bool DivideBinaryOperation::canApplyToTypes(const Type &left, const Type &right)
     case kLong:
     case kFloat:
     case kDouble:
+    case kDecimal:
     case kDatetimeInterval:
     case kYearMonthInterval: {
       return (right.getSuperTypeID() == Type::kNumeric);
@@ -238,7 +239,8 @@ TypedValue DivideBinaryOperation::applyToChecked(const TypedValue &left,
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       if (right_type.getSuperTypeID() == Type::kNumeric) {
         return applyToCheckedNumericHelper<DivideFunctor>(left, left_type,
                                                           right, right_type);
@@ -321,7 +323,8 @@ UncheckedBinaryOperator* DivideBinaryOperation::makeUncheckedBinaryOperatorForTy
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       if (right.getSuperTypeID() == Type::kNumeric) {
         return makeNumericBinaryOperatorOuterHelper<DivideArithmeticUncheckedBinaryOperator>(left, right);
       }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/binary_operations/ModuloBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ModuloBinaryOperation.cpp b/types/operations/binary_operations/ModuloBinaryOperation.cpp
index 9af5470..18144f2 100644
--- a/types/operations/binary_operations/ModuloBinaryOperation.cpp
+++ b/types/operations/binary_operations/ModuloBinaryOperation.cpp
@@ -223,6 +223,13 @@ TypedValue ModuloBinaryOperation::applyToChecked(const TypedValue &left,
       }
       break;
     }
+    case kDecimal: {
+      if (right_type.getSuperTypeID() == Type::kNumeric) {
+        return applyToCheckedNumericHelper<FloatModuloFunctor>(left, left_type,
+                                                                 right, right_type);
+      }
+      break;
+    }
     default:
       break;
   }
@@ -248,6 +255,12 @@ UncheckedBinaryOperator* ModuloBinaryOperation::makeUncheckedBinaryOperatorForTy
       }
       break;
     }
+    case kDecimal: {
+      if (right.getSuperTypeID() == Type::kNumeric) {
+        return makeNumericBinaryOperatorOuterHelper<FloatModuloArithmeticUncheckedBinaryOperator>(left, right);
+      }
+      break;
+    }
     default:
       break;
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/binary_operations/MultiplyBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/MultiplyBinaryOperation.cpp b/types/operations/binary_operations/MultiplyBinaryOperation.cpp
index 970953d..dd342c5 100644
--- a/types/operations/binary_operations/MultiplyBinaryOperation.cpp
+++ b/types/operations/binary_operations/MultiplyBinaryOperation.cpp
@@ -51,6 +51,9 @@ bool MultiplyBinaryOperation::canApplyToTypes(const Type &left, const Type &righ
               right.getTypeID() == kDatetimeInterval   ||
               right.getTypeID() == kYearMonthInterval);
     }
+    case kDecimal: {
+      return (right.getSuperTypeID() == Type::kNumeric);
+    }
     case kDatetimeInterval:
     case kYearMonthInterval: {
       return (right.getSuperTypeID() == Type::kNumeric);
@@ -217,7 +220,8 @@ TypedValue MultiplyBinaryOperation::applyToChecked(const TypedValue &left,
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       if (right_type.getSuperTypeID() == Type::kNumeric) {
         return applyToCheckedNumericHelper<MultiplyFunctor>(left, left_type,
                                                             right, right_type);
@@ -311,6 +315,12 @@ UncheckedBinaryOperator* MultiplyBinaryOperation::makeUncheckedBinaryOperatorFor
       }
       break;
     }
+    case kDecimal: {
+      if (right.getSuperTypeID() == Type::kNumeric) {
+        return makeNumericBinaryOperatorOuterHelper<MultiplyArithmeticUncheckedBinaryOperator>(left, right);
+      }
+      break;
+    }
     case kDatetimeInterval: {
       switch (right.getTypeID()) {
         case kInt: {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/binary_operations/SubtractBinaryOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/SubtractBinaryOperation.cpp b/types/operations/binary_operations/SubtractBinaryOperation.cpp
index e410488..3464599 100644
--- a/types/operations/binary_operations/SubtractBinaryOperation.cpp
+++ b/types/operations/binary_operations/SubtractBinaryOperation.cpp
@@ -44,7 +44,8 @@ bool SubtractBinaryOperation::canApplyToTypes(const Type &left, const Type &righ
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       return (right.getSuperTypeID() == Type::kNumeric);
     }
     case kDatetime: {
@@ -287,7 +288,8 @@ TypedValue SubtractBinaryOperation::applyToChecked(const TypedValue &left,
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       if (right_type.getSuperTypeID() == Type::kNumeric) {
         return applyToCheckedNumericHelper<SubtractFunctor>(left, left_type,
                                                             right, right_type);
@@ -352,7 +354,8 @@ UncheckedBinaryOperator* SubtractBinaryOperation::makeUncheckedBinaryOperatorFor
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       if (right.getSuperTypeID() == Type::kNumeric) {
         return makeNumericBinaryOperatorOuterHelper<SubtractArithmeticUncheckedBinaryOperator>(left, right);
       }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/comparisons/BasicComparison.cpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/BasicComparison.cpp b/types/operations/comparisons/BasicComparison.cpp
index 21b92ca..e705646 100644
--- a/types/operations/comparisons/BasicComparison.cpp
+++ b/types/operations/comparisons/BasicComparison.cpp
@@ -38,12 +38,14 @@ bool BasicComparison::canCompareTypes(const Type &left, const Type &right) const
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       switch (right.getTypeID()) {
         case kInt:
         case kLong:
         case kFloat:
         case kDouble:
+        case kDecimal:
           return true;
         default:
           return false;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/comparisons/BasicComparison.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/BasicComparison.hpp b/types/operations/comparisons/BasicComparison.hpp
index 9741c32..7f2aad9 100644
--- a/types/operations/comparisons/BasicComparison.hpp
+++ b/types/operations/comparisons/BasicComparison.hpp
@@ -23,6 +23,7 @@
 #include <string>
 
 #include "types/DatetimeLit.hpp"
+#include "types/DecimalLit.hpp"
 #include "types/IntervalLit.hpp"
 #include "types/Type.hpp"
 #include "types/TypeErrors.hpp"
@@ -147,12 +148,14 @@ bool BasicComparison::compareTypedValuesCheckedHelper(const TypedValue &left,
     case kInt:
     case kLong:
     case kFloat:
-    case kDouble: {
+    case kDouble:
+    case kDecimal: {
       switch (right_type.getTypeID()) {
         case kInt:
         case kLong:
         case kFloat:
         case kDouble:
+        case kDecimal:
           break;
         default: {
           LOG(FATAL) << "Comparison " << getName() << " can not be applied to types "
@@ -252,6 +255,11 @@ bool BasicComparison::compareTypedValuesCheckedHelper(const TypedValue &left,
       return comparison_functor(left_coerced.getLiteral<double>(),
                                 right_coerced.getLiteral<double>());
     }
+    case kDecimal: {
+      ComparisonFunctor<DecimalLit> comparison_functor;
+      return comparison_functor(left_coerced.getLiteral<DecimalLit>(),
+                                right_coerced.getLiteral<DecimalLit>());
+    }
     default: {
       LOG(FATAL) << "Comparison " << getName() << " can not be applied to types "
                  << left_type.getName() << " and " << right_type.getName();
@@ -310,6 +318,12 @@ UncheckedComparator* BasicComparison::makeNumericComparatorOuterHelper(
       } else {
         return makeNumericComparatorInnerHelper<ComparatorType, double, false>(left, right);
       }
+    case kDecimal:
+      if (left.isNullable()) {
+        return makeNumericComparatorInnerHelper<ComparatorType, DecimalLit, true>(left, right);
+      } else {
+        return makeNumericComparatorInnerHelper<ComparatorType, DecimalLit, false>(left, right);
+      }
     default:
       throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
   }
@@ -347,6 +361,12 @@ UncheckedComparator* BasicComparison::makeNumericComparatorInnerHelper(
       } else {
         return new ComparatorType<LeftCppType, left_type_nullable, double, false>();
       }
+    case kDecimal:
+      if (right.isNullable()) {
+        return new ComparatorType<LeftCppType, left_type_nullable, DecimalLit, true>();
+      } else {
+        return new ComparatorType<LeftCppType, left_type_nullable, DecimalLit, false>();
+      }
     default:
       throw OperationInapplicableToType(getName(), 2, left.getName().c_str(), right.getName().c_str());
   }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/comparisons/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/CMakeLists.txt b/types/operations/comparisons/CMakeLists.txt
index d2dfecf..266d1a2 100644
--- a/types/operations/comparisons/CMakeLists.txt
+++ b/types/operations/comparisons/CMakeLists.txt
@@ -65,6 +65,7 @@ target_link_libraries(quickstep_types_operations_comparisons_AsciiStringComparat
 target_link_libraries(quickstep_types_operations_comparisons_BasicComparison
                       glog
                       quickstep_types_DatetimeLit
+                      quickstep_types_DecimalLit
                       quickstep_types_IntervalLit
                       quickstep_types_Type
                       quickstep_types_TypeErrors

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/comparisons/ComparisonUtil.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/ComparisonUtil.hpp b/types/operations/comparisons/ComparisonUtil.hpp
index d7da3fd..9ffeeec 100644
--- a/types/operations/comparisons/ComparisonUtil.hpp
+++ b/types/operations/comparisons/ComparisonUtil.hpp
@@ -149,6 +149,11 @@ auto InvokeOnLessComparatorForTypeIgnoreNullability(const Type &type,
                                      double, false> comp;
       return functor(comp);
     }
+    case kDecimal: {
+      LessLiteralUncheckedComparator<DecimalLit, false,
+                                     DecimalLit, false> comp;
+      return functor(comp);
+    }
     case kChar: {
       const std::size_t string_length
           = static_cast<const AsciiStringSuperType&>(type).getStringLength();
@@ -254,6 +259,10 @@ auto InvokeOnLessComparatorForDifferentTypesIgnoreNullability(
           LessLiteralUncheckedComparator<int, false, double, false> comp;
           return functor(comp);
         }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<int, false, DecimalLit, false> comp;
+          return functor(comp);
+        }
         default:
           return comparison_util_detail::InvokeOnLessComparatorForDifferentTypesFallback(
               left_type, right_type, functor);
@@ -280,6 +289,11 @@ auto InvokeOnLessComparatorForDifferentTypesIgnoreNullability(
                                          double, false> comp;
           return functor(comp);
         }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<std::int64_t, false,
+                                         DecimalLit, false> comp;
+          return functor(comp);
+        }
         default:
           return comparison_util_detail::InvokeOnLessComparatorForDifferentTypesFallback(
               left_type, right_type, functor);
@@ -303,6 +317,10 @@ auto InvokeOnLessComparatorForDifferentTypesIgnoreNullability(
           LessLiteralUncheckedComparator<float, false, double, false> comp;
           return functor(comp);
         }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<float, false, DecimalLit, false> comp;
+          return functor(comp);
+        }
         default:
           return comparison_util_detail::InvokeOnLessComparatorForDifferentTypesFallback(
               left_type, right_type, functor);
@@ -326,6 +344,37 @@ auto InvokeOnLessComparatorForDifferentTypesIgnoreNullability(
           LessLiteralUncheckedComparator<double, false, double, false> comp;
           return functor(comp);
         }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<double, false, DecimalLit, false> comp;
+          return functor(comp);
+        }
+        default:
+          return comparison_util_detail::InvokeOnLessComparatorForDifferentTypesFallback(
+              left_type, right_type, functor);
+      }
+    }
+    case kDecimal: {
+      switch (right_type.getTypeID()) {
+        case kInt: {
+          LessLiteralUncheckedComparator<DecimalLit, false, int, false> comp;
+          return functor(comp);
+        }
+        case kLong: {
+          LessLiteralUncheckedComparator<DecimalLit, false, std::int64_t, false> comp;
+          return functor(comp);
+        }
+        case kFloat: {
+          LessLiteralUncheckedComparator<DecimalLit, false, float, false> comp;
+          return functor(comp);
+        }
+        case kDouble: {
+          LessLiteralUncheckedComparator<DecimalLit, false, double, false> comp;
+          return functor(comp);
+        }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<DecimalLit, false, DecimalLit, false> comp;
+          return functor(comp);
+        }
         default:
           return comparison_util_detail::InvokeOnLessComparatorForDifferentTypesFallback(
               left_type, right_type, functor);
@@ -544,6 +593,11 @@ auto InvokeOnBothLessComparatorsForDifferentTypesIgnoreNullability(
           LessLiteralUncheckedComparator<double, false, int, false> comp_reversed;
           return functor(comp, comp_reversed);
         }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<int, false, DecimalLit, false> comp;
+          LessLiteralUncheckedComparator<DecimalLit, false, int, false> comp_reversed;
+          return functor(comp, comp_reversed);
+        }
         default:
           return comparison_util_detail::InvokeOnBothLessComparatorsForDifferentTypesFallback(
               left_type, right_type, functor);
@@ -575,6 +629,11 @@ auto InvokeOnBothLessComparatorsForDifferentTypesIgnoreNullability(
                                          std::int64_t, false> comp_reversed;
           return functor(comp, comp_reversed);
         }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<std::int64_t, false, DecimalLit, false> comp;
+          LessLiteralUncheckedComparator<DecimalLit, false, std::int64_t, false> comp_reversed;
+          return functor(comp, comp_reversed);
+        }
         default:
           return comparison_util_detail::InvokeOnBothLessComparatorsForDifferentTypesFallback(
               left_type, right_type, functor);
@@ -601,6 +660,11 @@ auto InvokeOnBothLessComparatorsForDifferentTypesIgnoreNullability(
           LessLiteralUncheckedComparator<double, false, float, false> comp_reversed;
           return functor(comp, comp_reversed);
         }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<float, false, DecimalLit, false> comp;
+          LessLiteralUncheckedComparator<DecimalLit, false, float, false> comp_reversed;
+          return functor(comp, comp_reversed);
+        }
         default:
           return comparison_util_detail::InvokeOnBothLessComparatorsForDifferentTypesFallback(
               left_type, right_type, functor);
@@ -627,11 +691,47 @@ auto InvokeOnBothLessComparatorsForDifferentTypesIgnoreNullability(
           LessLiteralUncheckedComparator<double, false, double, false> comp;
           return functor(comp, comp);
         }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<double, false, DecimalLit, false> comp;
+          LessLiteralUncheckedComparator<DecimalLit, false, double, false> comp_reversed;
+          return functor(comp, comp_reversed);
+        }
         default:
           return comparison_util_detail::InvokeOnBothLessComparatorsForDifferentTypesFallback(
               left_type, right_type, functor);
       }
     }
+    case kDecimal: {
+      switch (right_type.getTypeID()) {
+        case kInt: {
+          LessLiteralUncheckedComparator<DecimalLit, false, int, false> comp;
+          LessLiteralUncheckedComparator<int, false, DecimalLit, false> comp_reversed;
+          return functor(comp, comp_reversed);
+        }
+        case kLong: {
+          LessLiteralUncheckedComparator<DecimalLit, false, std::int64_t, false> comp;
+          LessLiteralUncheckedComparator<std::int64_t, false, DecimalLit, false> comp_reversed;
+          return functor(comp, comp_reversed);
+        }
+        case kFloat: {
+          LessLiteralUncheckedComparator<DecimalLit, false, float, false> comp;
+          LessLiteralUncheckedComparator<float, false, DecimalLit, false> comp_reversed;
+          return functor(comp, comp_reversed);
+        }
+        case kDouble: {
+          LessLiteralUncheckedComparator<DecimalLit, false, double, false> comp;
+          LessLiteralUncheckedComparator<double, false, DecimalLit, false> comp_reversed;
+          return functor(comp, comp_reversed);
+        }
+        case kDecimal: {
+          LessLiteralUncheckedComparator<DecimalLit, false, DecimalLit, false> comp;
+          return functor(comp, comp);
+        }
+      default:
+        return comparison_util_detail::InvokeOnBothLessComparatorsForDifferentTypesFallback(
+            left_type, right_type, functor);
+      }
+    }
     case kChar: {
       const std::size_t left_string_length
           = static_cast<const AsciiStringSuperType&>(left_type).getStringLength();
@@ -959,6 +1059,8 @@ inline bool CheckUntypedValuesEqual(const Type &type, const void *left, const vo
       return STLLiteralEqual<float>()(left, right);
     case kDouble:
       return STLLiteralEqual<double>()(left, right);
+    case kDecimal:
+      return STLLiteralEqual<DecimalLit>()(left, right);
     case kChar:
       return STLCharEqual(static_cast<const AsciiStringSuperType&>(type).getStringLength())(left, right);
     case kVarChar:
@@ -1216,6 +1318,8 @@ inline TypedValue GetLastValueForType(const Type &type) {
       return TypedValue(std::numeric_limits<float>::max());
     case kDouble:
       return TypedValue(std::numeric_limits<double>::max());
+    case kDecimal:
+      return TypedValue(DecimalLit{std::numeric_limits<std::int64_t>::max()});
     case kChar:
       return TypedValue(kChar, kLastString, 2);
     case kVarChar:

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/comparisons/LiteralComparators.hpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/LiteralComparators.hpp b/types/operations/comparisons/LiteralComparators.hpp
index 3bf6b00..d009b23 100644
--- a/types/operations/comparisons/LiteralComparators.hpp
+++ b/types/operations/comparisons/LiteralComparators.hpp
@@ -45,6 +45,27 @@ template <typename LeftArgument, typename RightArgument> struct EqualFunctor
   }
 };
 
+template <> struct EqualFunctor<DecimalLit, DecimalLit>
+    : public std::binary_function<DecimalLit, DecimalLit, bool> {
+  inline bool operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left == right;
+  }
+};
+
+template <typename RightArgument> struct EqualFunctor<DecimalLit, RightArgument>
+    : public std::binary_function<DecimalLit, RightArgument, bool> {
+  inline bool operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left == DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument> struct EqualFunctor<LeftArgument, DecimalLit>
+    : public std::binary_function<LeftArgument, DecimalLit, bool> {
+  inline bool operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) == right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct NotEqualFunctor
     : public std::binary_function<LeftArgument, RightArgument, bool> {
   inline bool operator() (const LeftArgument &left, const RightArgument &right) const {
@@ -52,6 +73,27 @@ template <typename LeftArgument, typename RightArgument> struct NotEqualFunctor
   }
 };
 
+template <> struct NotEqualFunctor<DecimalLit, DecimalLit>
+    : public std::binary_function<DecimalLit, DecimalLit, bool> {
+  inline bool operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left != right;
+  }
+};
+
+template <typename RightArgument> struct NotEqualFunctor<DecimalLit, RightArgument>
+    : public std::binary_function<DecimalLit, RightArgument, bool> {
+  inline bool operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left != DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument> struct NotEqualFunctor<LeftArgument, DecimalLit>
+    : public std::binary_function<LeftArgument, DecimalLit, bool> {
+  inline bool operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) != right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct LessFunctor
     : public std::binary_function<LeftArgument, RightArgument, bool> {
   inline bool operator() (const LeftArgument &left, const RightArgument &right) const {
@@ -59,6 +101,27 @@ template <typename LeftArgument, typename RightArgument> struct LessFunctor
   }
 };
 
+template <> struct LessFunctor<DecimalLit, DecimalLit>
+    : public std::binary_function<DecimalLit, DecimalLit, bool> {
+  inline bool operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left < right;
+  }
+};
+
+template <typename RightArgument> struct LessFunctor<DecimalLit, RightArgument>
+    : public std::binary_function<DecimalLit, RightArgument, bool> {
+  inline bool operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left < DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument> struct LessFunctor<LeftArgument, DecimalLit>
+    : public std::binary_function<LeftArgument, DecimalLit, bool> {
+  inline bool operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) < right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct LessOrEqualFunctor
     : public std::binary_function<LeftArgument, RightArgument, bool> {
   inline bool operator() (const LeftArgument &left, const RightArgument &right) const {
@@ -66,6 +129,27 @@ template <typename LeftArgument, typename RightArgument> struct LessOrEqualFunct
   }
 };
 
+template <> struct LessOrEqualFunctor<DecimalLit, DecimalLit>
+    : public std::binary_function<DecimalLit, DecimalLit, bool> {
+  inline bool operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left <= right;
+  }
+};
+
+template <typename RightArgument> struct LessOrEqualFunctor<DecimalLit, RightArgument>
+    : public std::binary_function<DecimalLit, RightArgument, bool> {
+  inline bool operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left <= DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument> struct LessOrEqualFunctor<LeftArgument, DecimalLit>
+    : public std::binary_function<LeftArgument, DecimalLit, bool> {
+  inline bool operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) <= right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct GreaterFunctor
     : public std::binary_function<LeftArgument, RightArgument, bool> {
   inline bool operator() (const LeftArgument &left, const RightArgument &right) const {
@@ -73,6 +157,27 @@ template <typename LeftArgument, typename RightArgument> struct GreaterFunctor
   }
 };
 
+template <> struct GreaterFunctor<DecimalLit, DecimalLit>
+    : public std::binary_function<DecimalLit, DecimalLit, bool> {
+  inline bool operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left > right;
+  }
+};
+
+template <typename RightArgument> struct GreaterFunctor<DecimalLit, RightArgument>
+    : public std::binary_function<DecimalLit, RightArgument, bool> {
+  inline bool operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left > DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument> struct GreaterFunctor<LeftArgument, DecimalLit>
+    : public std::binary_function<LeftArgument, DecimalLit, bool> {
+  inline bool operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) > right;
+  }
+};
+
 template <typename LeftArgument, typename RightArgument> struct GreaterOrEqualFunctor
     : public std::binary_function<LeftArgument, RightArgument, bool> {
   inline bool operator() (const LeftArgument &left, const RightArgument &right) const {
@@ -80,6 +185,28 @@ template <typename LeftArgument, typename RightArgument> struct GreaterOrEqualFu
   }
 };
 
+template <> struct GreaterOrEqualFunctor<DecimalLit, DecimalLit>
+    : public std::binary_function<DecimalLit, DecimalLit, bool> {
+  inline bool operator() (const DecimalLit &left, const DecimalLit &right) const {
+    return left >= right;
+  }
+};
+
+template <typename RightArgument> struct GreaterOrEqualFunctor<DecimalLit, RightArgument>
+    : public std::binary_function<DecimalLit, RightArgument, bool> {
+  inline bool operator() (const DecimalLit &left, const RightArgument &right) const {
+    return left >= DecimalLit(right);
+  }
+};
+
+template <typename LeftArgument> struct GreaterOrEqualFunctor<LeftArgument, DecimalLit>
+    : public std::binary_function<LeftArgument, DecimalLit, bool> {
+  inline bool operator() (const LeftArgument &left, const DecimalLit &right) const {
+    return DecimalLit(left) >= right;
+  }
+};
+
+
 template <template <typename LeftArgument, typename RightArgument> class ComparisonFunctor,
           typename LeftCppType, bool left_nullable,
           typename RightCppType, bool right_nullable>

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/unary_operations/ArithmeticUnaryOperations.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/ArithmeticUnaryOperations.cpp b/types/operations/unary_operations/ArithmeticUnaryOperations.cpp
index 1e61db3..003c17e 100644
--- a/types/operations/unary_operations/ArithmeticUnaryOperations.cpp
+++ b/types/operations/unary_operations/ArithmeticUnaryOperations.cpp
@@ -20,6 +20,7 @@
 #include <string>
 
 #include "types/DatetimeIntervalType.hpp"
+#include "types/DecimalType.hpp"
 #include "types/DoubleType.hpp"
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
@@ -40,7 +41,7 @@ namespace quickstep {
 bool ArithmeticUnaryOperation::canApplyToType(const Type &type) const {
   return QUICKSTEP_EQUALS_ANY_CONSTANT(
       type.getTypeID(),
-      kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
+      kInt, kLong, kFloat, kDouble, kDecimal, kDatetimeInterval, kYearMonthInterval);
 }
 
 const Type* ArithmeticUnaryOperation::resultTypeForArgumentType(const Type &type) const {
@@ -66,7 +67,7 @@ const Type* ArithmeticUnaryOperation::pushDownTypeHint(const Type *type_hint) co
 bool NegateUnaryOperation::resultTypeIsPlausible(const Type &result_type) const {
   return QUICKSTEP_EQUALS_ANY_CONSTANT(
       result_type.getTypeID(),
-      kInt, kLong, kFloat, kDouble, kDatetimeInterval, kYearMonthInterval);
+      kInt, kLong, kFloat, kDouble, kDecimal, kDatetimeInterval, kYearMonthInterval);
 }
 
 TypedValue NegateUnaryOperation::applyToChecked(const TypedValue &argument,
@@ -86,6 +87,8 @@ TypedValue NegateUnaryOperation::applyToChecked(const TypedValue &argument,
       return TypedValue(-argument.getLiteral<typename FloatType::cpptype>());
     case kDouble:
       return TypedValue(-argument.getLiteral<typename DoubleType::cpptype>());
+    case kDecimal:
+      return TypedValue(-argument.getLiteral<typename DecimalType::cpptype>());
     case kDatetimeInterval:
       return TypedValue(-argument.getLiteral<typename DatetimeIntervalType::cpptype>());
     case kYearMonthInterval:
@@ -123,6 +126,12 @@ UncheckedUnaryOperator* NegateUnaryOperation::makeUncheckedUnaryOperatorForType(
       } else {
         return new NegateUncheckedUnaryOperator<DoubleType, false>();
       }
+    case kDecimal:
+      if (type.isNullable()) {
+        return new NegateUncheckedUnaryOperator<DecimalType, true>();
+      } else {
+        return new NegateUncheckedUnaryOperator<DecimalType, false>();
+      }
     case kDatetimeInterval:
       if (type.isNullable()) {
         return new NegateUncheckedUnaryOperator<DatetimeIntervalType, true>();

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index 5c54d9c..619f562 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -29,6 +29,7 @@ add_library(quickstep_types_operations_unaryoperations_UnaryOperationID UnaryOpe
 target_link_libraries(quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
                       glog
                       quickstep_types_DatetimeIntervalType
+                      quickstep_types_DecimalType
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
                       quickstep_types_IntType
@@ -75,6 +76,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_NumericCastOper
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_ValueAccessor
                       quickstep_storage_ValueAccessorUtil
+                      quickstep_types_DecimalType
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
                       quickstep_types_IntType

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/operations/unary_operations/NumericCastOperation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/NumericCastOperation.hpp b/types/operations/unary_operations/NumericCastOperation.hpp
index 250df6d..9eb50c2 100644
--- a/types/operations/unary_operations/NumericCastOperation.hpp
+++ b/types/operations/unary_operations/NumericCastOperation.hpp
@@ -29,6 +29,7 @@
 #include "catalog/CatalogTypedefs.hpp"
 #include "storage/ValueAccessor.hpp"
 #include "storage/ValueAccessorUtil.hpp"
+#include "types/DecimalType.hpp"
 #include "types/DoubleType.hpp"
 #include "types/FloatType.hpp"
 #include "types/IntType.hpp"
@@ -126,7 +127,7 @@ class UncheckedNumericCastOperator : public UncheckedUnaryOperator {
           result->appendNullValue();
         } else {
           *static_cast<typename TargetType::cpptype*>(result->getPtrForDirectWrite())
-              = static_cast<typename SourceType::cpptype>(*scalar_arg);
+              = static_cast<typename TargetType::cpptype>(*scalar_arg);
         }
       }
       return result;
@@ -285,6 +286,8 @@ class NumericCastOperation : public UnaryOperation {
         return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, FloatType>();
       case kDouble:
         return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, DoubleType>();
+      case kDecimal:
+        return makeUncheckedUnaryOperatorHelperForTargetNullability<SourceType, source_nullability, DecimalType>();
       default:
         FATAL_ERROR("Unhandled type " << kTypeNames[target_type_.getTypeID()]);
     }

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/0dd7978b/types/tests/DecimalType_unittest.cpp
----------------------------------------------------------------------
diff --git a/types/tests/DecimalType_unittest.cpp b/types/tests/DecimalType_unittest.cpp
new file mode 100644
index 0000000..e0e76af
--- /dev/null
+++ b/types/tests/DecimalType_unittest.cpp
@@ -0,0 +1,82 @@
+/**
+ *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
+ *     University of Wisconsin—Madison.
+ *
+ *   Licensed 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 <string>
+
+#include "types/DecimalLit.hpp"
+#include "types/DecimalType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypedValue.hpp"
+
+#include "gtest/gtest.h"
+
+namespace quickstep {
+
+TEST(DecimalTypeTest, PrintValueTest) {
+  const Type &decimal_type = TypeFactory::GetType(kDecimal);
+
+  // Try integer version.
+  DecimalLit integer_decimal = DecimalLit(36509);
+  TypedValue value_for_integer_decimal(integer_decimal);
+  EXPECT_EQ(std::string("36509.00"),
+            decimal_type.printValueToString(value_for_integer_decimal));
+
+  // Try double version.
+  DecimalLit double_decimal = DecimalLit(36509.65);
+  TypedValue value_for_double_decimal(double_decimal);
+  EXPECT_EQ(std::string("36509.65"),
+            decimal_type.printValueToString(value_for_double_decimal));
+
+  // Try truncation of double version.
+  DecimalLit double_decimal_truncated = DecimalLit(36509.6526762);
+  TypedValue value_for_double_decimal_truncated(double_decimal_truncated);
+  EXPECT_EQ(std::string("36509.65"),
+            decimal_type.printValueToString(
+                value_for_double_decimal_truncated));
+
+  // Test that number is truncated, not rounded.
+  double_decimal_truncated = DecimalLit(36509.6599999);
+  TypedValue value_for_double_decimal_truncated_other(double_decimal_truncated);
+  EXPECT_EQ(std::string("36509.65"),
+            decimal_type.printValueToString(
+                value_for_double_decimal_truncated));
+}
+
+TEST(DecimalTypeTest, DecimalLitOperationsTest) {
+  const Type &decimal_type = TypeFactory::GetType(kDecimal);
+
+  DecimalLit decimal_a(560.35);
+  DecimalLit decimal_b(439.65);
+
+  EXPECT_EQ(std::string("1000.00"),
+            decimal_type.printValueToString(TypedValue(decimal_a + decimal_b)));
+
+  EXPECT_EQ(std::string("120.70"),
+            decimal_type.printValueToString(TypedValue(decimal_a - decimal_b)));
+
+  EXPECT_EQ(std::string("246357.87"),
+            decimal_type.printValueToString(TypedValue(decimal_a * decimal_b)));
+
+  EXPECT_EQ(std::string("1.27"),
+            decimal_type.printValueToString(TypedValue(decimal_a / decimal_b)));
+
+  EXPECT_EQ(std::string("120.70"),
+            decimal_type.printValueToString(TypedValue(decimal_a % decimal_b)));
+}
+
+}  // namespace quickstep


Mime
View raw message