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