You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2017/10/05 22:03:19 UTC
[24/51] [abbrv] incubator-quickstep git commit: Refactor type system
and operations.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/TypeIDSelectors.hpp
----------------------------------------------------------------------
diff --git a/types/TypeIDSelectors.hpp b/types/TypeIDSelectors.hpp
new file mode 100644
index 0000000..d75a887
--- /dev/null
+++ b/types/TypeIDSelectors.hpp
@@ -0,0 +1,152 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_TYPE_ID_SELECTORS_HPP_
+#define QUICKSTEP_TYPES_TYPE_ID_SELECTORS_HPP_
+
+#include <type_traits>
+
+#include "types/TypeID.hpp"
+#include "utility/meta/Common.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+struct TypeIDSelectorAll;
+
+struct TypeIDSelectorNumeric;
+
+struct TypeIDSelectorParameterized;
+
+struct TypeIDSelectorNonParameterized;
+
+template <TypeID ...candidates>
+struct TypeIDSelectorEqualsAny;
+
+
+// Forward declaration
+template <TypeID type_id>
+struct TypeIDTrait;
+
+struct TypeIDSelectorAll {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+ };
+};
+
+struct TypeIDSelectorNumeric {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreturn-type"
+ inline static auto Invoke(const FunctorT &functor)
+ -> decltype(functor(TypeIDConstant())) {
+ DLOG(FATAL) << "Unexpected TypeID: "
+ << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+ }
+#pragma GCC diagnostic pop
+ };
+};
+
+template <typename TypeIDConstant, typename FunctorT>
+struct TypeIDSelectorNumeric::Implementation<
+ TypeIDConstant, FunctorT,
+ std::enable_if_t<TypeIDTrait<TypeIDConstant::value>
+ ::kStaticSuperTypeID == Type::kNumeric>> {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+};
+
+template <TypeID ...candidates>
+struct TypeIDSelectorEqualsAny {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreturn-type"
+ inline static auto Invoke(const FunctorT &functor)
+ -> decltype(functor(TypeIDConstant())) {
+ DLOG(FATAL) << "Unexpected TypeID: "
+ << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+ }
+#pragma GCC diagnostic pop
+ };
+};
+
+template <TypeID ...candidates>
+template <typename TypeIDConstant, typename FunctorT>
+struct TypeIDSelectorEqualsAny<candidates...>::Implementation<
+ TypeIDConstant, FunctorT,
+ std::enable_if_t<
+ meta::EqualsAny<TypeIDConstant,
+ std::integral_constant<TypeID, candidates>...>::value>> {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+};
+
+namespace internal {
+
+template <bool require_parameterized>
+struct TypeIDSelectorParameterizedHelper {
+ template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+ struct Implementation {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wreturn-type"
+ inline static auto Invoke(const FunctorT &functor)
+ -> decltype(functor(TypeIDConstant())) {
+ DLOG(FATAL) << "Unexpected TypeID: "
+ << kTypeNames[static_cast<int>(TypeIDConstant::value)];
+ }
+#pragma GCC diagnostic pop
+ };
+};
+
+template <bool require_non_parameterized>
+template <typename TypeIDConstant, typename FunctorT>
+struct TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementation<
+ TypeIDConstant, FunctorT,
+ std::enable_if_t<TypeIDTrait<TypeIDConstant::value>::kParameterized
+ ^ require_non_parameterized>> {
+ inline static auto Invoke(const FunctorT &functor) {
+ return functor(TypeIDConstant());
+ }
+};
+
+} // namespace internal
+
+struct TypeIDSelectorNonParameterized
+ : internal::TypeIDSelectorParameterizedHelper<true> {};
+
+struct TypeIDSelectorParameterized
+ : internal::TypeIDSelectorParameterizedHelper<false> {};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_ID_SELECTORS_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
new file mode 100644
index 0000000..f4c9fb9
--- /dev/null
+++ b/types/TypeRegistrar.hpp
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
+#define QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
+
+#include <cstdint>
+#include <type_traits>
+
+#include "types/DatetimeLit.hpp"
+#include "types/IntervalLit.hpp"
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeIDSelectors.hpp"
+#include "utility/meta/Common.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+template <TypeID type_id>
+struct TypeIDTrait;
+
+#define REGISTER_TYPE(T, type_id, super_type_id, parameterized, layout, CppType) \
+ class T; \
+ template <> struct TypeIDTrait<type_id> { \
+ typedef T TypeClass; \
+ typedef CppType cpptype; \
+ static constexpr TypeID kStaticTypeID = type_id; \
+ static constexpr Type::SuperTypeID kStaticSuperTypeID = super_type_id; \
+ static constexpr bool kParameterized = parameterized; \
+ static constexpr TypeStorageLayout kLayout = layout; \
+ };
+
+REGISTER_TYPE(BoolType, kBool, \
+ Type::kNumeric, false, kNativeEmbedded, bool);
+REGISTER_TYPE(IntType, kInt, \
+ Type::kNumeric, false, kNativeEmbedded, int);
+REGISTER_TYPE(LongType, kLong, \
+ Type::kNumeric, false, kNativeEmbedded, std::int64_t);
+REGISTER_TYPE(FloatType, kFloat, \
+ Type::kNumeric, false, kNativeEmbedded, float);
+REGISTER_TYPE(DoubleType, kDouble, \
+ Type::kNumeric, false, kNativeEmbedded, double);
+REGISTER_TYPE(DateType, kDate, \
+ Type::kOther, false, kNativeEmbedded, DateLit);
+REGISTER_TYPE(DatetimeType, kDatetime, \
+ Type::kOther, false, kNativeEmbedded, DatetimeLit);
+REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval, \
+ Type::kOther, false, kNativeEmbedded, DatetimeIntervalLit);
+REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval, \
+ Type::kOther, false, kNativeEmbedded, YearMonthIntervalLit);
+REGISTER_TYPE(CharType, kChar, \
+ Type::kAsciiString, true, kNonNativeInline, void);
+REGISTER_TYPE(VarCharType, kVarChar, \
+ Type::kAsciiString, true, kOutOfLine, void);
+REGISTER_TYPE(NullType, kNullType, \
+ Type::kOther, false, kNonNativeInline, void);
+
+#undef REGISTER_TYPE
+
+using TypeIDSequenceAll =
+ meta::MakeSequence<static_cast<std::size_t>(kNumTypeIDs)>
+ ::type::template cast_to<TypeID>;
+
+template <typename Selector = TypeIDSelectorAll, typename FunctorT>
+auto InvokeOnTypeID(const TypeID type_id, const FunctorT &functor);
+
+namespace internal {
+
+template <int l, int r, typename Selector, typename FunctorT>
+inline auto InvokeOnTypeIDInner(const int value,
+ const FunctorT &functor) {
+ DCHECK_LE(l, r);
+ if (l == r) {
+ constexpr TypeID type_id = static_cast<TypeID>(r);
+ return Selector::template Implementation<
+ std::integral_constant<TypeID, type_id>, FunctorT>::Invoke(functor);
+ }
+ constexpr int m = (l + r) >> 1;
+ if (value <= m) {
+ return InvokeOnTypeIDInner<l, m, Selector, FunctorT>(value, functor);
+ } else {
+ return InvokeOnTypeIDInner<m+1, r, Selector, FunctorT>(value, functor);
+ }
+}
+
+} // namespace internal
+
+template <typename Selector, typename FunctorT>
+auto InvokeOnTypeID(const TypeID type_id,
+ const FunctorT &functor) {
+ return internal::InvokeOnTypeIDInner<0, static_cast<int>(kNumTypeIDs)-1,
+ Selector, FunctorT>(
+ static_cast<int>(type_id), functor);
+}
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
new file mode 100644
index 0000000..27ba02a
--- /dev/null
+++ b/types/TypeSynthesizer.hpp
@@ -0,0 +1,210 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_
+#define QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_
+
+#include <cstddef>
+#include <type_traits>
+
+#include "types/Type.hpp"
+#include "types/Type.pb.h"
+#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "utility/Macros.hpp"
+#include "utility/PtrMap.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+template <typename TypeClass, bool parameterized>
+class TypeInstance;
+
+
+template <TypeID type_id>
+class TypeSynthesizer
+ : public Type,
+ public TypeInstance<typename TypeIDTrait<type_id>::TypeClass,
+ TypeIDTrait<type_id>::kParameterized> {
+ public:
+ using Trait = TypeIDTrait<type_id>;
+ using TypeClass = typename Trait::TypeClass;
+
+ static constexpr Type::SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
+ static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID;
+ static constexpr bool kParameterized = Trait::kParameterized;
+ static constexpr TypeStorageLayout kLayout = Trait::kLayout;
+
+ typedef typename Trait::cpptype cpptype;
+
+ serialization::Type getProto() const override {
+ serialization::Type proto;
+
+ proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
+ proto.set_nullable(nullable_);
+
+ if (kParameterized) {
+ proto.set_length(parameter_);
+ }
+
+ return proto;
+ }
+
+ const Type& getNullableVersion() const override {
+ return getInstance<kParameterized>(true);
+ }
+
+ const Type& getNonNullableVersion() const override {
+ return getInstance<kParameterized>(false);
+ }
+
+ protected:
+ template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+ explicit TypeSynthesizer(const bool nullable,
+ std::enable_if_t<layout == kNativeEmbedded ||
+ layout == kNativeInline>* = 0)
+ : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+ sizeof(cpptype), sizeof(cpptype)) {
+ DCHECK(!kParameterized);
+ }
+
+ template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+ TypeSynthesizer(const bool nullable,
+ const std::size_t minimum_byte_length,
+ const std::size_t maximum_byte_length,
+ const std::size_t parameter,
+ std::enable_if_t<parameterized &&
+ (layout == kNonNativeInline ||
+ layout == kOutOfLine)>* = 0)
+ : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+ minimum_byte_length, maximum_byte_length, parameter) {
+ DCHECK(kLayout != kNonNativeInline || minimum_byte_length == maximum_byte_length);
+ }
+
+ template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+ TypeSynthesizer(const bool nullable,
+ const std::size_t minimum_byte_length,
+ const std::size_t maximum_byte_length,
+ std::enable_if_t<!parameterized &&
+ (layout == kNonNativeInline ||
+ layout == kOutOfLine)>* = 0)
+ : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+ minimum_byte_length, maximum_byte_length) {
+ DCHECK(kLayout != kNonNativeInline || minimum_byte_length == maximum_byte_length);
+ }
+
+ private:
+ template <bool has_param>
+ inline const Type& getInstance(const bool nullable,
+ std::enable_if_t<has_param>* = 0) const {
+ return TypeInstance<TypeClass, kParameterized>::Instance(parameter_, nullable);
+ }
+
+ template <bool has_param>
+ inline const Type& getInstance(const bool nullable,
+ std::enable_if_t<!has_param>* = 0) const {
+ return TypeInstance<TypeClass, kParameterized>::Instance(nullable);
+ }
+
+ friend class TypeInstance<TypeClass, kParameterized>;
+
+ DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
+};
+
+template <TypeID type_id>
+constexpr Type::SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
+
+template <TypeID type_id>
+constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
+
+template <TypeID type_id>
+constexpr bool TypeSynthesizer<type_id>::kParameterized;
+
+template <TypeID type_id>
+constexpr TypeStorageLayout TypeSynthesizer<type_id>::kLayout;
+
+
+template <typename TypeClass>
+class TypeInstance<TypeClass, false> {
+ public:
+ static const TypeClass& InstanceNonNullable() {
+ return InstanceInternal<false>();
+ }
+
+ static const TypeClass& InstanceNullable() {
+ return InstanceInternal<true>();
+ }
+
+ static const TypeClass& Instance(const bool nullable) {
+ if (nullable) {
+ return InstanceNullable();
+ } else {
+ return InstanceNonNullable();
+ }
+ }
+
+ private:
+ template <bool nullable>
+ inline static const TypeClass& InstanceInternal() {
+ static TypeClass instance(nullable);
+ return instance;
+ }
+};
+
+template <typename TypeClass>
+class TypeInstance<TypeClass, true> {
+ public:
+ static const TypeClass& InstanceNonNullable(const std::size_t length) {
+ return InstanceInternal<false>(length);
+ }
+
+ static const TypeClass& InstanceNullable(const std::size_t length) {
+ return InstanceInternal<true>(length);
+ }
+
+ static const TypeClass& Instance(const bool nullable, const std::size_t length) {
+ if (nullable) {
+ return InstanceNullable(length);
+ } else {
+ return InstanceNonNullable(length);
+ }
+ }
+
+ private:
+ template <bool nullable>
+ inline static const TypeClass& InstanceInternal(const std::size_t length) {
+ static PtrMap<size_t, TypeClass> instance_map;
+ auto imit = instance_map.find(length);
+ if (imit == instance_map.end()) {
+ imit = instance_map.insert(length, new TypeClass(length, nullable)).first;
+ }
+ return *(imit->second);
+ }
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
new file mode 100644
index 0000000..b146f02
--- /dev/null
+++ b/types/TypeUtil.hpp
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_TYPE_UTIL_HPP_
+#define QUICKSTEP_TYPES_TYPE_UTIL_HPP_
+
+#include <type_traits>
+
+#include "types/BoolType.hpp"
+#include "types/CharType.hpp"
+#include "types/DateType.hpp"
+#include "types/DatetimeIntervalType.hpp"
+#include "types/DatetimeType.hpp"
+#include "types/DoubleType.hpp"
+#include "types/FloatType.hpp"
+#include "types/IntType.hpp"
+#include "types/LongType.hpp"
+#include "types/NullType.hpp"
+#include "types/Type.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "types/VarCharType.hpp"
+#include "types/YearMonthIntervalType.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+class TypeUtil {
+ public:
+ static bool IsParameterized(const TypeID type_id) {
+ return InvokeOnTypeID(
+ type_id,
+ [&](auto tid) -> bool { // NOLINT(build/c++11)
+ return TypeIDTrait<decltype(tid)::value>::kParameterized;
+ });
+ }
+
+ private:
+ TypeUtil() {}
+
+ DISALLOW_COPY_AND_ASSIGN(TypeUtil);
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_TYPE_UTIL_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/TypedValue.cpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.cpp b/types/TypedValue.cpp
index 8dd8b60..ad1eb0f 100644
--- a/types/TypedValue.cpp
+++ b/types/TypedValue.cpp
@@ -47,6 +47,7 @@ bool TypedValue::isPlausibleInstanceOf(const TypeSignature type) const {
}
switch (type_id) {
+ case kBool:
case kInt:
case kLong:
case kFloat:
@@ -82,33 +83,34 @@ serialization::TypedValue TypedValue::getProto() const {
// NOTE(chasseur): To represent a NULL value, only the 'type_id' field of the
// proto is filled in, and all the optional value fields are omitted.
+ proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(getTypeID()));
switch (getTypeID()) {
+ case kBool:
+ if (!isNull()) {
+ proto.set_int_value(getLiteral<bool>());
+ }
+ break;
case kInt:
- proto.set_type_id(serialization::Type::INT);
if (!isNull()) {
proto.set_int_value(getLiteral<int>());
}
break;
case kLong:
- proto.set_type_id(serialization::Type::LONG);
if (!isNull()) {
proto.set_long_value(getLiteral<std::int64_t>());
}
break;
case kFloat:
- proto.set_type_id(serialization::Type::FLOAT);
if (!isNull()) {
proto.set_float_value(getLiteral<float>());
}
break;
case kDouble:
- proto.set_type_id(serialization::Type::DOUBLE);
if (!isNull()) {
proto.set_double_value(getLiteral<double>());
}
break;
case kDate:
- proto.set_type_id(serialization::Type::DATE);
if (!isNull()) {
serialization::TypedValue::DateLit *literal_date_proto = proto.mutable_date_value();
literal_date_proto->set_year(value_union_.date_value.year);
@@ -117,37 +119,31 @@ serialization::TypedValue TypedValue::getProto() const {
}
break;
case kDatetime:
- proto.set_type_id(serialization::Type::DATETIME);
if (!isNull()) {
proto.set_datetime_value(value_union_.datetime_value.ticks);
}
break;
case kDatetimeInterval:
- proto.set_type_id(serialization::Type::DATETIME_INTERVAL);
if (!isNull()) {
proto.set_datetime_interval_value(value_union_.datetime_interval_value.interval_ticks);
}
break;
case kYearMonthInterval:
- proto.set_type_id(serialization::Type::YEAR_MONTH_INTERVAL);
if (!isNull()) {
proto.set_year_month_interval_value(value_union_.year_month_interval_value.months);
}
break;
case kChar:
- proto.set_type_id(serialization::Type::CHAR);
if (!isNull()) {
proto.set_out_of_line_data(static_cast<const char*>(getOutOfLineData()), getDataSize());
}
break;
case kVarChar:
- proto.set_type_id(serialization::Type::VAR_CHAR);
if (!isNull()) {
proto.set_out_of_line_data(static_cast<const char*>(getOutOfLineData()), getDataSize());
}
break;
case kNullType:
- proto.set_type_id(serialization::Type::NULL_TYPE);
DCHECK(isNull());
break;
default:
@@ -166,24 +162,29 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
<< "Attempted to create TypedValue from an invalid proto description:\n"
<< proto.DebugString();
- switch (proto.type_id()) {
- case serialization::Type::INT:
+ const TypeID type_id = TypeIDFactory::ReconstructFromProto(proto.type_id());
+ switch (type_id) {
+ case kBool:
+ return proto.has_bool_value() ?
+ TypedValue(static_cast<bool>(proto.bool_value())) :
+ TypedValue(kBool);
+ case kInt:
return proto.has_int_value() ?
TypedValue(static_cast<int>(proto.int_value())) :
TypedValue(kInt);
- case serialization::Type::LONG:
+ case kLong:
return proto.has_long_value() ?
TypedValue(static_cast<std::int64_t>(proto.long_value())) :
TypedValue(kLong);
- case serialization::Type::FLOAT:
+ case kFloat:
return proto.has_float_value() ?
TypedValue(static_cast<float>(proto.float_value())) :
TypedValue(kFloat);
- case serialization::Type::DOUBLE:
+ case kDouble:
return proto.has_double_value() ?
TypedValue(static_cast<double>(proto.double_value())) :
TypedValue(kDouble);
- case serialization::Type::DATE:
+ case kDate:
if (proto.has_date_value()) {
return TypedValue(DateLit::Create(proto.date_value().year(),
proto.date_value().month(),
@@ -191,7 +192,7 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
} else {
return TypedValue(kDate);
}
- case serialization::Type::DATETIME:
+ case kDatetime:
if (proto.has_datetime_value()) {
DatetimeLit datetime;
datetime.ticks = proto.datetime_value();
@@ -199,7 +200,7 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
} else {
return TypedValue(kDatetime);
}
- case serialization::Type::DATETIME_INTERVAL:
+ case kDatetimeInterval:
if (proto.has_datetime_interval_value()) {
DatetimeIntervalLit interval;
interval.interval_ticks = proto.datetime_interval_value();
@@ -207,7 +208,7 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
} else {
return TypedValue(kDatetimeInterval);
}
- case serialization::Type::YEAR_MONTH_INTERVAL:
+ case kYearMonthInterval:
if (proto.has_year_month_interval_value()) {
YearMonthIntervalLit interval;
interval.months = proto.year_month_interval_value();
@@ -215,19 +216,19 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
} else {
return TypedValue(kYearMonthInterval);
}
- case serialization::Type::CHAR:
+ case kChar:
return proto.has_out_of_line_data() ?
TypedValue(kChar,
static_cast<const void*>(proto.out_of_line_data().c_str()),
proto.out_of_line_data().size()).ensureNotReference() :
TypedValue(kChar);
- case serialization::Type::VAR_CHAR:
+ case kVarChar:
return proto.has_out_of_line_data() ?
TypedValue(kVarChar,
static_cast<const void*>(proto.out_of_line_data().c_str()),
proto.out_of_line_data().size()).ensureNotReference() :
TypedValue(kVarChar);
- case serialization::Type::NULL_TYPE:
+ case kNullType:
return TypedValue(kNullType);
default:
FATAL_ERROR("Unrecognized TypeID in TypedValue::ReconstructFromProto");
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/TypedValue.hpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.hpp b/types/TypedValue.hpp
index 0ba3d53..196e8ec 100644
--- a/types/TypedValue.hpp
+++ b/types/TypedValue.hpp
@@ -90,6 +90,16 @@ class TypedValue {
}
/**
+ * @brief Constructor for a literal value of BoolType.
+ **/
+ explicit TypedValue(const bool literal_bool)
+ : value_info_(static_cast<std::uint64_t>(kBool)) {
+ // Zero-out all bytes in the union for getHash() and fastEqualCheck().
+ value_union_.hash64 = 0;
+ value_union_.bool_value = literal_bool;
+ }
+
+ /**
* @brief Constructor for a literal value of IntType.
**/
explicit TypedValue(const int literal_int)
@@ -264,9 +274,9 @@ class TypedValue {
* TypedValue will take ownership of this memory.
* @param value_size The number of bytes of data at value_ptr.
**/
- static TypedValue CreateWithOwnedData(const TypeID type_id,
- void *value_ptr,
- const std::size_t value_size) {
+ inline static TypedValue CreateWithOwnedData(const TypeID type_id,
+ void *value_ptr,
+ const std::size_t value_size) {
TypedValue val(type_id, value_ptr, value_size);
val.value_info_ |= kOwnershipMask;
return val;
@@ -282,6 +292,7 @@ class TypedValue {
**/
static bool RepresentedInline(const TypeID type_id) {
switch (type_id) {
+ case kBool:
case kInt:
case kLong:
case kFloat:
@@ -313,6 +324,8 @@ class TypedValue {
**/
static bool HashIsReversible(const TypeID type_id) {
switch (type_id) {
+ case kBool:
+ return true;
case kInt:
case kFloat:
return sizeof(value_union_.int_value) <= sizeof(std::size_t);
@@ -391,6 +404,8 @@ class TypedValue {
inline std::size_t getDataSize() const {
DCHECK(!isNull());
switch (getTypeID()) {
+ case kBool:
+ return sizeof(bool);
case kInt:
case kFloat:
return sizeof(int);
@@ -478,7 +493,8 @@ class TypedValue {
* @return The out-of-line data this TypedValue points to.
**/
inline const void* getOutOfLineData() const {
- DCHECK(!(getTypeID() == kInt
+ DCHECK(!(getTypeID() == kBool
+ || getTypeID() == kInt
|| getTypeID() == kLong
|| getTypeID() == kFloat
|| getTypeID() == kDouble
@@ -547,6 +563,10 @@ class TypedValue {
value_info_ >> kSizeShift);
} else {
switch (getTypeID()) {
+ case kBool:
+ // 1 byte copy.
+ *static_cast<bool*>(destination) = value_union_.bool_value;
+ break;
case kInt:
case kFloat:
// 4 bytes byte-for-byte copy.
@@ -574,6 +594,7 @@ class TypedValue {
**/
inline std::size_t getHash() const {
switch (getTypeID()) {
+ case kBool:
case kInt:
case kLong:
case kFloat:
@@ -670,6 +691,7 @@ class TypedValue {
DCHECK(!other.isNull());
DCHECK_EQ(getTypeID(), other.getTypeID());
switch (getTypeID()) {
+ case kBool:
case kInt:
case kLong:
case kFloat:
@@ -710,6 +732,16 @@ class TypedValue {
}
}
+ bool operator==(const TypedValue &other) const {
+ if (getTypeID() != other.getTypeID()) {
+ return false;
+ }
+ if (isNull() || other.isNull()) {
+ return isNull() == other.isNull();
+ }
+ return fastEqualCheck(other);
+ }
+
/**
* @brief Generate a serialized Protocol Buffer representation
* of this TypedValue.
@@ -789,6 +821,7 @@ class TypedValue {
inline void reverseHash(const std::size_t hash);
union ValueUnion {
+ bool bool_value;
int int_value;
std::int64_t long_value;
float float_value;
@@ -842,6 +875,13 @@ class TypedValue {
// Explicit specializations of getLiteral().
template <>
+inline bool TypedValue::getLiteral<bool>() const {
+ DCHECK_EQ(kBool, getTypeID());
+ DCHECK(!isNull());
+ return value_union_.bool_value;
+}
+
+template <>
inline int TypedValue::getLiteral<int>() const {
DCHECK_EQ(kInt, getTypeID());
DCHECK(!isNull());
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/TypedValue.proto
----------------------------------------------------------------------
diff --git a/types/TypedValue.proto b/types/TypedValue.proto
index 7f3ab7a..7cf3eca 100644
--- a/types/TypedValue.proto
+++ b/types/TypedValue.proto
@@ -22,17 +22,18 @@ package quickstep.serialization;
import "types/Type.proto";
message TypedValue {
- required Type.TypeID type_id = 1;
+ required TypeID type_id = 1;
// NOTE(zuyu): For a NULL value, none of the optional fields are filled in.
- optional int32 int_value = 2;
- optional int64 long_value = 3;
- optional float float_value = 4;
- optional double double_value = 5;
- optional bytes out_of_line_data = 6;
- optional int64 datetime_value = 7;
- optional int64 datetime_interval_value = 8;
- optional int64 year_month_interval_value = 9;
+ optional bool bool_value = 2;
+ optional int32 int_value = 3;
+ optional int64 long_value = 4;
+ optional float float_value = 5;
+ optional double double_value = 6;
+ optional bytes out_of_line_data = 7;
+ optional int64 datetime_value = 8;
+ optional int64 datetime_interval_value = 9;
+ optional int64 year_month_interval_value = 10;
message DateLit {
required int32 year = 1;
@@ -40,5 +41,5 @@ message TypedValue {
required uint32 day = 3;
}
- optional DateLit date_value = 10;
+ optional DateLit date_value = 11;
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/VarCharType.cpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.cpp b/types/VarCharType.cpp
index 02845b1..7eeb04c 100644
--- a/types/VarCharType.cpp
+++ b/types/VarCharType.cpp
@@ -42,38 +42,6 @@ using std::string;
namespace quickstep {
-template <bool nullable_internal>
-const VarCharType& VarCharType::InstanceInternal(const std::size_t length) {
- static PtrMap<size_t, VarCharType> instance_map;
- PtrMap<size_t, VarCharType>::iterator imit = instance_map.find(length);
- if (imit == instance_map.end()) {
- imit = instance_map.insert(length, new VarCharType(length, nullable_internal)).first;
- }
- return *(imit->second);
-}
-
-const VarCharType& VarCharType::InstanceNonNullable(const std::size_t length) {
- return InstanceInternal<false>(length);
-}
-
-const VarCharType& VarCharType::InstanceNullable(const std::size_t length) {
- return InstanceInternal<true>(length);
-}
-
-const VarCharType& VarCharType::InstanceFromProto(const serialization::Type &proto) {
- return Instance(proto.GetExtension(serialization::VarCharType::length), proto.nullable());
-}
-
-serialization::Type VarCharType::getProto() const {
- serialization::Type proto;
- proto.set_type_id(serialization::Type::VAR_CHAR);
-
- proto.set_nullable(nullable_);
-
- proto.SetExtension(serialization::VarCharType::length, length_);
- return proto;
-}
-
size_t VarCharType::estimateAverageByteLength() const {
if (length_ > 160) {
return 80;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index bb50e92..05b2aae 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -24,8 +24,8 @@
#include <cstdio>
#include <string>
+#include "types/AsciiStringSuperType.hpp"
#include "types/Type.hpp"
-#include "types/Type.pb.h"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"
@@ -43,72 +43,9 @@ namespace quickstep {
* character. This means that the VARCHAR(X) type requires from 1 to X+1
* bytes of storage, depending on string length.
**/
-class VarCharType : public AsciiStringSuperType {
+class VarCharType : public AsciiStringSuperType<kVarChar> {
public:
/**
- * @brief Get a reference to the non-nullable singleton instance of this Type
- * for the specified length.
- *
- * @param length The length parameter of the VarCharType.
- * @return A reference to the non-nullable singleton instance of this Type
- * for the specified length.
- **/
- static const VarCharType& InstanceNonNullable(const std::size_t length);
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type for
- * the specified length.
- *
- * @param length The length parameter of the VarCharType.
- * @return A reference to the nullable singleton instance of this Type for
- * the specified length.
- **/
- static const VarCharType& InstanceNullable(const std::size_t length);
-
- /**
- * @brief Get a reference to the singleton instance of this Type for the
- * specified length and nullability.
- *
- * @param length The length parameter of the VarCharType.
- * @param nullable Whether to get the nullable version of this Type.
- * @return A reference to the singleton instance of this Type for the
- * specified length and nullability.
- **/
- static const VarCharType& Instance(const std::size_t length, const bool nullable) {
- if (nullable) {
- return InstanceNullable(length);
- } else {
- return InstanceNonNullable(length);
- }
- }
-
- /**
- * @brief Get a reference to the singleton instance of this Type described
- * by the given Protocol Buffer serialization.
- *
- * @param type The serialized Protocol Buffer representation of the desired
- * VarCharType.
- * @return A reference to the singleton instance of this Type for the given
- * Protocol Buffer.
- **/
- static const VarCharType& InstanceFromProto(const serialization::Type &type);
-
- /**
- * @brief Generate a serialized Protocol Buffer representation of this Type.
- *
- * @return The serialized Protocol Buffer representation of this Type.
- **/
- serialization::Type getProto() const override;
-
- const Type& getNullableVersion() const override {
- return InstanceNullable(length_);
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable(length_);
- }
-
- /**
* @note Includes an extra byte for a terminating null character.
**/
std::size_t estimateAverageByteLength() const override;
@@ -137,11 +74,9 @@ class VarCharType : public AsciiStringSuperType {
private:
VarCharType(const std::size_t length, const bool nullable)
- : AsciiStringSuperType(kVarChar, nullable, 1, length + 1, length) {
- }
+ : AsciiStringSuperType<kVarChar>(nullable, 1, length + 1, length) {}
- template <bool nullable_internal>
- static const VarCharType& InstanceInternal(const std::size_t length);
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(VarCharType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/YearMonthIntervalType.cpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.cpp b/types/YearMonthIntervalType.cpp
index 3c15a91..d656fca 100644
--- a/types/YearMonthIntervalType.cpp
+++ b/types/YearMonthIntervalType.cpp
@@ -30,7 +30,6 @@
#include "types/IntervalLit.hpp"
#include "types/IntervalParser.hpp"
-#include "types/NullCoercibilityCheckMacro.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
@@ -46,16 +45,6 @@ using std::snprintf;
namespace quickstep {
-bool YearMonthIntervalType::isCoercibleFrom(const Type &original_type) const {
- QUICKSTEP_NULL_COERCIBILITY_CHECK();
- return (original_type.getTypeID() == kYearMonthInterval);
-}
-
-bool YearMonthIntervalType::isSafelyCoercibleFrom(const Type &original_type) const {
- QUICKSTEP_NULL_COERCIBILITY_CHECK();
- return (original_type.getTypeID() == kYearMonthInterval);
-}
-
std::string YearMonthIntervalType::printValueToString(const TypedValue &value) const {
DCHECK(!value.isNull());
@@ -127,14 +116,6 @@ std::string YearMonthIntervalType::printValueToString(const TypedValue &value) c
return std::string(interval_buf);
}
-void YearMonthIntervalType::printValueToFile(const TypedValue &value,
- FILE *file,
- const int padding) const {
- // We simply re-use the logic from printValueToString(), as trying to do
- // padding on-the fly with so many different fields is too much of a hassle.
- std::fprintf(file, "%*s", static_cast<int>(padding), printValueToString(value).c_str());
-}
-
bool YearMonthIntervalType::parseValueFromString(const std::string &value_string,
TypedValue *value) const {
// Try simple-format parse first.
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index a2ba175..e890ea9 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -27,6 +27,7 @@
#include "types/IntervalLit.hpp"
#include "types/Type.hpp"
#include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
#include "types/TypedValue.hpp"
#include "utility/Macros.hpp"
@@ -39,73 +40,14 @@ namespace quickstep {
/**
* @brief A type representing the year-month interval.
**/
-class YearMonthIntervalType : public Type {
+class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
public:
- typedef YearMonthIntervalLit cpptype;
-
- static const TypeID kStaticTypeID = kYearMonthInterval;
-
- /**
- * @brief Get a reference to the non-nullable singleton instance of this
- * Type.
- *
- * @return A reference to the non-nullable singleton instance of this Type.
- **/
- static const YearMonthIntervalType& InstanceNonNullable() {
- static YearMonthIntervalType instance(false);
- return instance;
- }
-
- /**
- * @brief Get a reference to the nullable singleton instance of this Type.
- *
- * @return A reference to the nullable singleton instance of this Type.
- **/
- static const YearMonthIntervalType& InstanceNullable() {
- static YearMonthIntervalType instance(true);
- return instance;
- }
-
- /**
- * @brief Get a reference to a singleton instance of this Type.
- *
- * @param nullable Whether to get the nullable version of this Type.
- * @return A reference to the desired singleton instance of this Type.
- **/
- static const YearMonthIntervalType& Instance(const bool nullable) {
- if (nullable) {
- return InstanceNullable();
- } else {
- return InstanceNonNullable();
- }
- }
-
- const Type& getNullableVersion() const override {
- return InstanceNullable();
- }
-
- const Type& getNonNullableVersion() const override {
- return InstanceNonNullable();
- }
-
- std::size_t estimateAverageByteLength() const override {
- return sizeof(YearMonthIntervalLit);
- }
-
- bool isCoercibleFrom(const Type &original_type) const override;
-
- bool isSafelyCoercibleFrom(const Type &original_type) const override;
-
int getPrintWidth() const override {
return YearMonthIntervalLit::kPrintingChars;
}
std::string printValueToString(const TypedValue &value) const override;
- void printValueToFile(const TypedValue &value,
- FILE *file,
- const int padding = 0) const override;
-
TypedValue makeZeroValue() const override {
return TypedValue(YearMonthIntervalLit{0});
}
@@ -115,8 +57,9 @@ class YearMonthIntervalType : public Type {
private:
explicit YearMonthIntervalType(const bool nullable)
- : Type(Type::kOther, kYearMonthInterval, nullable, sizeof(YearMonthIntervalLit), sizeof(YearMonthIntervalLit)) {
- }
+ : TypeSynthesizer<kYearMonthInterval>(nullable) {}
+
+ template <typename, bool> friend class TypeInstance;
DISALLOW_COPY_AND_ASSIGN(YearMonthIntervalType);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/containers/ColumnVector.cpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.cpp b/types/containers/ColumnVector.cpp
index dfc0fae..ef3587e 100644
--- a/types/containers/ColumnVector.cpp
+++ b/types/containers/ColumnVector.cpp
@@ -41,4 +41,8 @@ ColumnVector* ColumnVector::MakeVectorOfValue(
}
}
+constexpr bool NativeColumnVector::kNative;
+
+constexpr bool IndirectColumnVector::kNative;
+
} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/containers/ColumnVector.hpp
----------------------------------------------------------------------
diff --git a/types/containers/ColumnVector.hpp b/types/containers/ColumnVector.hpp
index 5ef9871..0d6447d 100644
--- a/types/containers/ColumnVector.hpp
+++ b/types/containers/ColumnVector.hpp
@@ -129,6 +129,8 @@ class ColumnVector {
**/
class NativeColumnVector : public ColumnVector {
public:
+ static constexpr bool kNative = true;
+
/**
* @brief Constructor for a NativeColumnVector which owns its own array of
* values.
@@ -140,8 +142,8 @@ class NativeColumnVector : public ColumnVector {
NativeColumnVector(const Type &type, const std::size_t reserved_length)
: ColumnVector(type),
type_length_(type.maximumByteLength()),
- values_(std::malloc(type.maximumByteLength() * reserved_length)),
reserved_length_(reserved_length),
+ values_(std::malloc(type.maximumByteLength() * reserved_length)),
actual_length_(0u),
null_bitmap_(type.isNullable() ? new BitVector<false>(reserved_length) : nullptr) {
DCHECK(UsableForType(type_));
@@ -395,8 +397,9 @@ class NativeColumnVector : public ColumnVector {
private:
const std::size_t type_length_;
- void *values_;
const std::size_t reserved_length_;
+
+ void *values_;
std::size_t actual_length_;
std::unique_ptr<BitVector<false>> null_bitmap_;
@@ -409,6 +412,8 @@ class NativeColumnVector : public ColumnVector {
**/
class IndirectColumnVector : public ColumnVector {
public:
+ static constexpr bool kNative = false;
+
/**
* @brief Constructor.
*
@@ -503,11 +508,21 @@ class IndirectColumnVector : public ColumnVector {
* @param value A value to append to this NativeColumnVector.
**/
inline void appendTypedValue(TypedValue &&value) {
- DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
+ DCHECK(value.isPlausibleInstanceOf(type_.getSignature())) << type_.getName();
DCHECK_LT(values_.size(), reserved_length_);
values_.emplace_back(std::move(value));
}
+ inline void appendNullValue() {
+ DCHECK(type_.isNullable());
+ DCHECK_LT(values_.size(), reserved_length_);
+ values_.emplace_back(type_.makeNullValue());
+ }
+
+ inline void fillWithNulls() {
+ fillWithValue(type_.makeNullValue());
+ }
+
/**
* @brief Fill this entire ColumnVector with copies of value.
*
@@ -569,6 +584,7 @@ class IndirectColumnVector : public ColumnVector {
private:
const bool type_is_nullable_;
const std::size_t reserved_length_;
+
std::vector<TypedValue> values_;
DISALLOW_COPY_AND_ASSIGN(IndirectColumnVector);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/CMakeLists.txt b/types/operations/CMakeLists.txt
index c5dad0f..948d013 100644
--- a/types/operations/CMakeLists.txt
+++ b/types/operations/CMakeLists.txt
@@ -25,19 +25,62 @@ QS_PROTOBUF_GENERATE_CPP(types_operations_Operation_proto_srcs
# Declare micro-libs:
add_library(quickstep_types_operations_Operation Operation.cpp Operation.hpp)
+add_library(quickstep_types_operations_OperationFactory OperationFactory.cpp OperationFactory.hpp)
+add_library(quickstep_types_operations_OperationUtil ../../empty_src.cpp OperationUtil.hpp)
+add_library(quickstep_types_operations_OperationSignature OperationSignature.cpp OperationSignature.hpp)
add_library(quickstep_types_operations_Operation_proto ${types_operations_Operation_proto_srcs})
# Link dependencies:
target_link_libraries(quickstep_types_operations_Operation
+ quickstep_types_operations_OperationSignature
+ quickstep_utility_Macros)
+target_link_libraries(quickstep_types_operations_OperationFactory
+ quickstep_types_Type
+ quickstep_types_TypeFactory
+ quickstep_types_TypeID
+ quickstep_types_TypeUtil
+ quickstep_types_TypedValue
+ quickstep_types_operations_Operation
+ quickstep_types_operations_OperationSignature
+ quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
+ quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
+ quickstep_types_operations_binaryoperations_BinaryOperation
+ quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+ quickstep_types_operations_binaryoperations_CMathBinaryOperations
+ quickstep_types_operations_unaryoperations_ArithmeticUnaryOperations
+ quickstep_types_operations_unaryoperations_AsciiStringUnaryOperations
+ quickstep_types_operations_unaryoperations_CMathUnaryOperations
+ quickstep_types_operations_unaryoperations_CastOperation
+ quickstep_types_operations_unaryoperations_DateExtractOperation
+ quickstep_types_operations_unaryoperations_SubstringOperation
+ quickstep_types_operations_unaryoperations_UnaryOperation
+ quickstep_types_operations_unaryoperations_UnaryOperationWrapper
+ quickstep_utility_HashPair
+ quickstep_utility_Macros
+ quickstep_utility_StringUtil)
+target_link_libraries(quickstep_types_operations_OperationUtil
+ quickstep_catalog_CatalogTypedefs
+ quickstep_types_Type
+ quickstep_types_TypedValue
+ quickstep_types_containers_ColumnVector)
+target_link_libraries(quickstep_types_operations_OperationSignature
+ quickstep_types_TypeID
+ quickstep_types_Type_proto
+ quickstep_types_operations_Operation_proto
+ quickstep_utility_HashPair
quickstep_utility_Macros)
target_link_libraries(quickstep_types_operations_Operation_proto
quickstep_types_Type_proto
+ quickstep_types_TypedValue_proto
${PROTOBUF_LIBRARY})
# Module all-in-one library:
add_library(quickstep_types_operations ../../empty_src.cpp)
target_link_libraries(quickstep_types_operations
quickstep_types_operations_Operation
+ quickstep_types_operations_OperationFactory
+ quickstep_types_operations_OperationUtil
+ quickstep_types_operations_OperationSignature
quickstep_types_operations_Operation_proto
quickstep_types_operations_binaryoperations
quickstep_types_operations_comparisons
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/operations/Operation.hpp
----------------------------------------------------------------------
diff --git a/types/operations/Operation.hpp b/types/operations/Operation.hpp
index 51178b5..6da0f4c 100644
--- a/types/operations/Operation.hpp
+++ b/types/operations/Operation.hpp
@@ -20,6 +20,10 @@
#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_HPP_
#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_HPP_
+#include <string>
+#include <vector>
+
+#include "types/operations/OperationSignature.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
@@ -28,6 +32,9 @@ namespace quickstep {
* @{
*/
+class Operation;
+typedef std::shared_ptr<const Operation> OperationPtr;
+
/**
* @brief An operation which can be applied to typed values. Each exact
* concrete Operation is a singleton.
@@ -72,7 +79,7 @@ class Operation {
* @return The human-readable name of this Operation.
**/
inline const char* getName() const {
- return name_;
+ return "NoName";
}
/**
@@ -81,7 +88,11 @@ class Operation {
* @return The short name of this Operation.
**/
inline const char* getShortName() const {
- return short_name_;
+ return "NoShortName";
+ }
+
+ virtual std::vector<OperationSignaturePtr> getSignatures() const {
+ return {};
}
/**
@@ -98,19 +109,12 @@ class Operation {
}
protected:
- Operation(const OperationSuperTypeID super_type_id,
- const char *name,
- const char *short_name)
- : super_type_id_(super_type_id),
- name_(name),
- short_name_(short_name) {
+ explicit Operation(const OperationSuperTypeID super_type_id)
+ : super_type_id_(super_type_id) {
}
private:
const OperationSuperTypeID super_type_id_;
- const char *name_;
- const char *short_name_;
-
DISALLOW_COPY_AND_ASSIGN(Operation);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/operations/Operation.proto
----------------------------------------------------------------------
diff --git a/types/operations/Operation.proto b/types/operations/Operation.proto
index d6391f0..da2a282 100644
--- a/types/operations/Operation.proto
+++ b/types/operations/Operation.proto
@@ -20,6 +20,7 @@ syntax = "proto2";
package quickstep.serialization;
import "types/Type.proto";
+import "types/TypedValue.proto";
message Comparison {
enum ComparisonID {
@@ -38,58 +39,8 @@ message Comparison {
required ComparisonID comparison_id = 1;
}
-message UnaryOperation {
- enum UnaryOperationID {
- NEGATE = 0;
- CAST = 1;
- DATE_EXTRACT = 2;
- SUBSTRING = 3;
- }
-
- required UnaryOperationID operation_id = 1;
-
- extensions 32 to max;
-}
-
-message CastOperation {
- extend UnaryOperation {
- // Required when operation_id = CAST.
- optional Type target_type = 64;
- }
-}
-
-message DateExtractOperation {
- enum Unit {
- YEAR = 0;
- MONTH = 1;
- DAY = 2;
- HOUR = 3;
- MINUTE = 4;
- SECOND = 5;
- }
-
- extend UnaryOperation {
- // Required when operation_id = DATE_EXTRACT.
- optional Unit unit = 96;
- }
-}
-
-message SubstringOperation {
- extend UnaryOperation {
- // Required when operation_id = SUBSTRING.
- optional int64 start_position = 100;
- optional int64 substring_length = 101;
- }
-}
-
-message BinaryOperation {
- enum BinaryOperationID {
- ADD = 0;
- SUBTRACT = 1;
- MULTIPLY = 2;
- DIVIDE = 3;
- MODULO = 4;
- }
-
- required BinaryOperationID operation_id = 1;
+message OperationSignature {
+ required string operation_name = 1;
+ repeated TypeID argument_type_ids = 2;
+ required uint32 num_static_arguments = 3;
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/operations/OperationFactory.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.cpp b/types/operations/OperationFactory.cpp
new file mode 100644
index 0000000..531318b
--- /dev/null
+++ b/types/operations/OperationFactory.cpp
@@ -0,0 +1,357 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/operations/OperationFactory.hpp"
+
+#include <list>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "types/Type.hpp"
+#include "types/TypeFactory.hpp"
+#include "types/TypeID.hpp"
+#include "types/TypeUtil.hpp"
+#include "types/TypedValue.hpp"
+#include "types/operations/Operation.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/binary_operations/ArithmeticBinaryOperations.hpp"
+#include "types/operations/binary_operations/AsciiStringBinaryOperations.hpp"
+#include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "types/operations/binary_operations/CMathBinaryOperations.hpp"
+#include "types/operations/unary_operations/ArithmeticUnaryOperations.hpp"
+#include "types/operations/unary_operations/AsciiStringUnaryOperations.hpp"
+#include "types/operations/unary_operations/CMathUnaryOperations.hpp"
+#include "types/operations/unary_operations/CastOperation.hpp"
+#include "types/operations/unary_operations/DateExtractOperation.hpp"
+#include "types/operations/unary_operations/SubstringOperation.hpp"
+#include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
+#include "utility/StringUtil.hpp"
+
+namespace quickstep {
+
+namespace {
+
+struct FunctorPackDispatcher {
+ template <typename FunctorT>
+ inline static std::list<OperationPtr> Generate(
+ std::enable_if_t<FunctorT::kOperationSuperTypeID == Operation::kUnaryOperation>* = 0) {
+ return { std::make_shared<const UnaryOperationWrapper<FunctorT>>() };
+ }
+
+ template <typename FunctorT>
+ inline static std::list<OperationPtr> Generate(
+ std::enable_if_t<FunctorT::kOperationSuperTypeID == Operation::kBinaryOperation>* = 0) {
+ return { std::make_shared<const BinaryOperationWrapper<FunctorT>>() };
+ }
+
+ template <typename FunctorT>
+ inline static std::list<OperationPtr> Generate(
+ decltype(FunctorT::template GenerateOperations<FunctorPackDispatcher>())* = 0) {
+ return FunctorT::template GenerateOperations<FunctorPackDispatcher>();
+ }
+};
+
+} // namespace
+
+OperationFactory::OperationFactory() {
+ registerOperation<CastOperation>();
+ registerOperation<DateExtractOperation>();
+ registerOperation<SubstringOperation>();
+
+ registerFunctorPack<ArithmeticUnaryFunctorPack>();
+ registerFunctorPack<AsciiStringUnaryFunctorPack>();
+ registerFunctorPack<CMathUnaryFunctorPack>();
+
+ registerFunctorPack<ArithmeticBinaryFunctorPack>();
+ registerFunctorPack<AsciiStringBinaryFunctorPack>();
+ registerFunctorPack<CMathBinaryFunctorPack>();
+}
+
+OperationSignaturePtr OperationFactory::resolveOperation(
+ const std::string &operation_name,
+ const std::shared_ptr<const std::vector<const Type*>> &argument_types,
+ const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+ std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+ std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+ std::string *message) const {
+ const std::string lower_case_name = ToLower(operation_name);
+ const std::size_t arity = argument_types->size();
+ const auto &indices_it =
+ primary_index_.find(std::make_pair(lower_case_name, arity));
+
+ if (indices_it == primary_index_.end()) {
+ *message = "Unrecognized function " + operation_name
+ + " with " + std::to_string(arity) + " arguments";
+ }
+
+ ResolveStatus status;
+ OperationSignaturePtr op_signature = nullptr;
+ const auto &secondary_index = indices_it->second;
+
+ std::vector<TypeID> argument_type_ids;
+ for (const auto *type : *argument_types) {
+ argument_type_ids.emplace_back(type->getTypeID());
+ }
+
+ // First, try full exact matching.
+ status = resolveOperationWithFullTypeMatch(secondary_index,
+ argument_type_ids,
+ *argument_types,
+ *static_arguments,
+ coerced_static_arguments,
+ &op_signature,
+ message);
+ if (status == ResolveStatus::kSuccess) {
+ DCHECK(op_signature != nullptr);
+ *coerced_argument_types = argument_types;
+ return op_signature;
+ } else if (status == ResolveStatus::kError) {
+ return nullptr;
+ }
+
+ // Otherwise, try partial (non-static arguments) exact matching.
+ status = resolveOperationWithPartialTypeMatch(secondary_index,
+ argument_type_ids,
+ *argument_types,
+ *static_arguments,
+ coerced_argument_types,
+ coerced_static_arguments,
+ &op_signature,
+ message);
+ if (status == ResolveStatus::kSuccess) {
+ DCHECK(op_signature != nullptr);
+ return op_signature;
+ } else if (status == ResolveStatus::kError) {
+ return nullptr;
+ }
+
+ // TODO
+ *message = "Unexpected argument types for function " + operation_name;
+ return nullptr;
+}
+
+OperationFactory::ResolveStatus OperationFactory::resolveOperationWithFullTypeMatch(
+ const PartialSignatureIndex &secondary_index,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::vector<const Type*> &argument_types,
+ const std::vector<TypedValue> &static_arguments,
+ std::shared_ptr<const std::vector<TypedValue>> *partial_static_arguments,
+ OperationSignaturePtr *resolved_op_signature,
+ std::string *message) const {
+ const std::size_t max_num_static_arguments = static_arguments.size();
+ auto it = secondary_index.lower_bound(
+ std::make_pair(&argument_type_ids, max_num_static_arguments));
+
+ if (it != secondary_index.end() && *it->first.first == argument_type_ids) {
+ const OperationSignaturePtr op_signature = it->second;
+ const OperationPtr operation = getOperation(op_signature);
+
+ *partial_static_arguments =
+ std::make_shared<const std::vector<TypedValue>>(
+ static_arguments.begin()
+ + (max_num_static_arguments - op_signature->getNumStaticArguments()),
+ static_arguments.end());
+
+ if (canApplyOperationTo(operation,
+ argument_types,
+ **partial_static_arguments,
+ message)) {
+ *resolved_op_signature = op_signature;
+ return ResolveStatus::kSuccess;
+ } else {
+ return ResolveStatus::kError;
+ }
+ }
+
+ return ResolveStatus::kNotFound;
+}
+
+OperationFactory::ResolveStatus OperationFactory::resolveOperationWithPartialTypeMatch(
+ const PartialSignatureIndex &secondary_index,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::vector<const Type*> &argument_types,
+ const std::vector<TypedValue> &static_arguments,
+ std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+ std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+ OperationSignaturePtr *resolved_op_signature,
+ std::string *message) const {
+ const std::size_t arity = argument_types.size();
+ const std::size_t max_num_static_arguments = static_arguments.size();
+ const std::size_t first_static_argument_position = arity - max_num_static_arguments;
+
+ auto it = secondary_index.lower_bound(
+ std::make_pair(&argument_type_ids, max_num_static_arguments));
+ while (it != secondary_index.end()) {
+ const std::vector<TypeID> &expected_type_ids = *it->first.first;
+ DCHECK_GE(expected_type_ids.size(), it->first.second);
+ const std::size_t num_non_static_arguments =
+ expected_type_ids.size() - it->first.second;
+
+ if (!std::equal(expected_type_ids.begin(),
+ expected_type_ids.begin() + num_non_static_arguments,
+ argument_type_ids.begin())) {
+ break;
+ }
+
+ // Coerce static arguments
+ std::vector<const Type*> coerced_static_arg_types;
+ std::vector<TypedValue> coerced_static_args;
+
+ bool is_coercible = true;
+ for (std::size_t i = num_non_static_arguments; i < arity; ++i) {
+ const Type &arg_type = *argument_types.at(i);
+ const TypedValue &arg_value =
+ static_arguments.at(i - first_static_argument_position);
+ const TypeID &expected_type_id = expected_type_ids.at(i);
+
+ if (arg_type.getTypeID() == expected_type_id) {
+ coerced_static_arg_types.emplace_back(&arg_type);
+ coerced_static_args.emplace_back(arg_value);
+ } else {
+ const Type *expected_type = nullptr;
+ if (TypeFactory::TypeRequiresLengthParameter(expected_type_id)) {
+ // TODO: refactor type system to make this coercion extensible.
+ if (expected_type_id == kChar && arg_type.getTypeID() == kVarChar) {
+ expected_type = &TypeFactory::GetType(
+ expected_type_id, arg_type.maximumByteLength() - 1);
+ } else if (expected_type_id == kVarChar && arg_type.getTypeID() == kChar) {
+ expected_type = &TypeFactory::GetType(
+ expected_type_id, arg_type.maximumByteLength() + 1);
+ }
+ } else {
+ expected_type = &TypeFactory::GetType(expected_type_id);
+ }
+
+ if (expected_type != nullptr && expected_type->isSafelyCoercibleFrom(arg_type)) {
+ coerced_static_arg_types.emplace_back(expected_type);
+ coerced_static_args.emplace_back(
+ expected_type->coerceValue(arg_value, arg_type));
+ } else {
+ is_coercible = false;
+ break;
+ }
+ }
+ }
+
+ if (is_coercible) {
+ std::vector<const Type*> coerced_arg_types(
+ argument_types.begin(),
+ argument_types.begin() + num_non_static_arguments);
+ for (const Type *type : coerced_static_arg_types) {
+ coerced_arg_types.emplace_back(type);
+ }
+
+ const OperationPtr operation = getOperation(it->second);
+ if (canApplyOperationTo(operation,
+ coerced_arg_types,
+ coerced_static_args,
+ message)) {
+ *coerced_argument_types =
+ std::make_shared<const std::vector<const Type*>>(std::move(coerced_arg_types));
+ *coerced_static_arguments =
+ std::make_shared<const std::vector<TypedValue>>(std::move(coerced_static_args));
+ *resolved_op_signature = it->second;
+ return ResolveStatus::kSuccess;
+ }
+ }
+
+ ++it;
+ }
+
+ return ResolveStatus::kNotFound;
+}
+
+bool OperationFactory::canApplyOperationTo(
+ const OperationPtr operation,
+ const std::vector<const Type*> &argument_types,
+ const std::vector<TypedValue> &static_arguments,
+ std::string *message) const {
+ switch (operation->getOperationSuperTypeID()) {
+ case Operation::kUnaryOperation: {
+ const UnaryOperationPtr unary_operation =
+ std::static_pointer_cast<const UnaryOperation>(operation);
+ return unary_operation->canApplyTo(*argument_types[0],
+ static_arguments,
+ message);
+ }
+ case Operation::kBinaryOperation: {
+ const BinaryOperationPtr binary_operation =
+ std::static_pointer_cast<const BinaryOperation>(operation);
+ return binary_operation->canApplyTo(*argument_types[0],
+ *argument_types[1],
+ static_arguments,
+ message);
+ }
+ default: {
+ const auto operation_id =
+ static_cast<std::underlying_type_t<Operation::OperationSuperTypeID>>(
+ operation->getOperationSuperTypeID());
+ LOG(FATAL) << "Unknown opeation super type id: " << operation_id;
+ }
+ }
+}
+
+
+const OperationFactory& OperationFactory::Instance() {
+ static OperationFactory instance;
+ return instance;
+}
+
+template <typename OperationT>
+void OperationFactory::registerOperation() {
+ registerOperationInternal(std::make_shared<const OperationT>());
+}
+
+template <typename FunctorPackT>
+void OperationFactory::registerFunctorPack() {
+ for (const OperationPtr &operation :
+ FunctorPackT::template GenerateOperations<FunctorPackDispatcher>()) {
+ registerOperationInternal(operation);
+ }
+}
+
+void OperationFactory::registerOperationInternal(const OperationPtr &operation) {
+ DCHECK(operation->getOperationSuperTypeID() == Operation::kUnaryOperation ||
+ operation->getOperationSuperTypeID() == Operation::kBinaryOperation);
+
+ for (const OperationSignaturePtr op_sig_orig : operation->getSignatures()) {
+ DCHECK(operation->getOperationSuperTypeID() != Operation::kUnaryOperation ||
+ op_sig_orig->getNonStaticArity() == 1u);
+ DCHECK(operation->getOperationSuperTypeID() != Operation::kBinaryOperation ||
+ op_sig_orig->getNonStaticArity() == 2u);
+
+ const OperationSignaturePtr op_sig =
+ OperationSignature::Create(ToLower(op_sig_orig->getName()),
+ op_sig_orig->getArgumentTypeIDs(),
+ op_sig_orig->getNumStaticArguments());
+
+ // TODO: print error message for collision
+ operations_.emplace(op_sig, operation);
+
+ const PartialSignature sig_ref =
+ std::make_pair(&op_sig->getArgumentTypeIDs(),
+ op_sig->getNumStaticArguments());
+ primary_index_[std::make_pair(op_sig->getName(),
+ op_sig->getArity())].emplace(sig_ref, op_sig);
+ }
+}
+
+
+} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/operations/OperationFactory.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationFactory.hpp b/types/operations/OperationFactory.hpp
new file mode 100644
index 0000000..3e90b6d
--- /dev/null
+++ b/types/operations/OperationFactory.hpp
@@ -0,0 +1,203 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_FACTORY_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_FACTORY_HPP_
+
+#include <memory>
+#include <set>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/TypedValue.hpp"
+#include "types/operations/Operation.hpp"
+#include "types/operations/OperationSignature.hpp"
+#include "types/operations/binary_operations/BinaryOperation.hpp"
+#include "types/operations/unary_operations/UnaryOperation.hpp"
+#include "utility/HashPair.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class Type;
+
+/** \addtogroup Types
+ * @{
+ */
+
+class OperationFactory {
+ public:
+ static const OperationFactory& Instance();
+
+ inline bool hasOperation(const std::string &operation_name,
+ const std::size_t arity) const {
+ const auto indices_it =
+ primary_index_.find(std::make_pair(operation_name, arity));
+ return indices_it != primary_index_.end();
+ }
+
+ inline OperationPtr getOperation(const OperationSignaturePtr &op_signature) const {
+ DCHECK(operations_.find(op_signature) != operations_.end());
+ return operations_.at(op_signature);
+ }
+
+ inline OperationPtr getOperation(const std::string &operation_name,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::size_t num_static_arguments = 0) const {
+ return getOperation(
+ OperationSignature::Create(
+ operation_name, argument_type_ids, num_static_arguments));
+ }
+
+ inline UnaryOperationPtr getUnaryOperation(
+ const OperationSignaturePtr &op_signature) const {
+ const OperationPtr operation = getOperation(op_signature);
+ DCHECK(operation->getOperationSuperTypeID() == Operation::kUnaryOperation);
+ return std::static_pointer_cast<const UnaryOperation>(operation);
+ }
+
+ inline UnaryOperationPtr getUnaryOperation(
+ const std::string &operation_name,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::size_t num_static_arguments = 0) const {
+ return getUnaryOperation(
+ OperationSignature::Create(
+ operation_name, argument_type_ids, num_static_arguments));
+ }
+
+ inline BinaryOperationPtr getBinaryOperation(
+ const OperationSignaturePtr &op_signature) const {
+ const OperationPtr operation = getOperation(op_signature);
+ DCHECK(operation->getOperationSuperTypeID() == Operation::kBinaryOperation);
+ return std::static_pointer_cast<const BinaryOperation>(operation);
+ }
+
+ inline BinaryOperationPtr getBinaryOperation(
+ const std::string &operation_name,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::size_t num_static_arguments = 0) const {
+ return getBinaryOperation(
+ OperationSignature::Create(
+ operation_name, argument_type_ids, num_static_arguments));
+ }
+
+ OperationSignaturePtr resolveOperation(
+ const std::string &operation_name,
+ const std::shared_ptr<const std::vector<const Type*>> &argument_types,
+ const std::shared_ptr<const std::vector<TypedValue>> &static_arguments,
+ std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+ std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+ std::string *message) const;
+
+ private:
+ OperationFactory();
+
+ template <typename OperationT>
+ void registerOperation();
+
+ template <typename FunctorPackT>
+ void registerFunctorPack();
+
+ void registerOperationInternal(const OperationPtr &operation);
+
+ using PartialSignature = std::pair<const std::vector<TypeID>*, std::size_t>;
+
+ struct PartialSignatureLess {
+ inline bool operator()(const PartialSignature &lhs,
+ const PartialSignature &rhs) const {
+ int cmp_code = static_cast<int>(lhs.first->size())
+ - static_cast<int>(lhs.first->size());
+ if (cmp_code != 0) {
+ return cmp_code < 0;
+ }
+ for (std::size_t i = 0; i < lhs.first->size(); ++i) {
+ cmp_code = static_cast<int>(lhs.first->at(i))
+ - static_cast<int>(rhs.first->at(i));
+ if (cmp_code != 0) {
+ return cmp_code < 0;
+ }
+ }
+ return lhs.second > rhs.second;
+ }
+ };
+
+ using PartialSignatureIndex = std::map<PartialSignature,
+ OperationSignaturePtr,
+ PartialSignatureLess>;
+
+ enum class ResolveStatus {
+ kSuccess = 0,
+ kError,
+ kNotFound
+ };
+
+ ResolveStatus resolveOperationWithFullTypeMatch(
+ const PartialSignatureIndex &secondary_index,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::vector<const Type*> &argument_types,
+ const std::vector<TypedValue> &static_arguments,
+ std::shared_ptr<const std::vector<TypedValue>> *trimmed_static_arguments,
+ OperationSignaturePtr *resolved_op_signature,
+ std::string *message) const;
+
+ ResolveStatus resolveOperationWithPartialTypeMatch(
+ const PartialSignatureIndex &secondary_index,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::vector<const Type*> &argument_types,
+ const std::vector<TypedValue> &static_arguments,
+ std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+ std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+ OperationSignaturePtr *resolved_op_signature,
+ std::string *message) const;
+
+// ResolveStatus resolveOperationGeneric(
+// const std::set<OperationSignaturePtr> signatures,
+// const std::vector<TypeID> &argument_type_ids,
+// const std::vector<const Type*> &argument_types,
+// const std::vector<TypedValue> &static_arguments,
+// std::shared_ptr<const std::vector<const Type*>> *coerced_argument_types,
+// std::shared_ptr<const std::vector<TypedValue>> *coerced_static_arguments,
+// OperationSignaturePtr *op_signature,
+// std::string *message) const;
+
+ bool canApplyOperationTo(const OperationPtr operation,
+ const std::vector<const Type*> &argument_types,
+ const std::vector<TypedValue> &static_arguments,
+ std::string *message) const;
+
+ std::unordered_map<OperationSignaturePtr,
+ OperationPtr,
+ OperationSignatureHash,
+ OperationSignatureEqual> operations_;
+
+ std::unordered_map<std::pair<std::string, std::size_t>,
+ PartialSignatureIndex> primary_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(OperationFactory);
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_OPERATIONS_OPERATION_FACTORY_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/operations/OperationSignature.cpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationSignature.cpp b/types/operations/OperationSignature.cpp
new file mode 100644
index 0000000..6b6c4a6
--- /dev/null
+++ b/types/operations/OperationSignature.cpp
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#include "types/operations/OperationSignature.hpp"
+
+#include <cstdint>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/Type.pb.h"
+#include "types/operations/Operation.pb.h"
+
+namespace quickstep {
+
+serialization::OperationSignature OperationSignature::getProto() const {
+ serialization::OperationSignature op_signature;
+
+ op_signature.set_operation_name(operation_name_);
+ for (const TypeID tid : argument_type_ids_) {
+ op_signature.add_argument_type_ids()->CopyFrom(TypeIDFactory::GetProto(tid));
+ }
+ op_signature.set_num_static_arguments(
+ static_cast<std::uint32_t>(num_static_arguments_));
+
+ return op_signature;
+}
+
+OperationSignaturePtr OperationSignature::ReconstructFromProto(
+ const serialization::OperationSignature &proto) {
+ std::vector<TypeID> argument_type_ids;
+ for (int i = 0; i < proto.argument_type_ids_size(); ++i) {
+ argument_type_ids.emplace_back(
+ TypeIDFactory::ReconstructFromProto(proto.argument_type_ids(i)));
+ }
+
+ return Create(proto.operation_name(),
+ argument_type_ids,
+ proto.num_static_arguments());
+}
+
+std::string OperationSignature::toString() const {
+ const std::size_t num_regular_arguments =
+ argument_type_ids_.size() - num_static_arguments_;
+
+ std::string str;
+ str.append(operation_name_);
+ str.push_back('(');
+ for (std::size_t i = 0; i < num_regular_arguments; ++i) {
+ if (i != 0) {
+ str.append(", ");
+ }
+ str.append(
+ kTypeNames[static_cast<std::underlying_type_t<TypeID>>(
+ argument_type_ids_[i])]);
+ }
+ if (num_static_arguments_ > 0) {
+ str.append(", static(");
+ for (std::size_t i = 0; i < num_static_arguments_; ++i) {
+ if (i != 0) {
+ str.append(", ");
+ }
+ str.append(
+ kTypeNames[static_cast<std::underlying_type_t<TypeID>>(
+ argument_type_ids_[i + num_regular_arguments])]);
+ }
+ str.push_back(')');
+ }
+ str.push_back(')');
+
+ return str;
+}
+
+} // namespace quickstep
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5cd81aa8/types/operations/OperationSignature.hpp
----------------------------------------------------------------------
diff --git a/types/operations/OperationSignature.hpp b/types/operations/OperationSignature.hpp
new file mode 100644
index 0000000..6659a85
--- /dev/null
+++ b/types/operations/OperationSignature.hpp
@@ -0,0 +1,182 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_OPERATIONS_OPERATION_SIGNATURE_HPP_
+#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SIGNATURE_HPP_
+
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "types/TypeID.hpp"
+#include "types/operations/Operation.pb.h"
+
+#include "utility/HashPair.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ * @{
+ */
+
+class OperationSignature;
+typedef std::shared_ptr<const OperationSignature> OperationSignaturePtr;
+
+class OperationSignature {
+ public:
+ serialization::OperationSignature getProto() const;
+
+ static OperationSignaturePtr ReconstructFromProto(
+ const serialization::OperationSignature &proto);
+
+ inline const std::string& getName() const {
+ return operation_name_;
+ }
+
+ inline std::size_t getArity() const {
+ return argument_type_ids_.size();
+ }
+
+ inline std::size_t getNonStaticArity() const {
+ return argument_type_ids_.size() - num_static_arguments_;
+ }
+
+ inline const std::vector<TypeID>& getArgumentTypeIDs() const {
+ return argument_type_ids_;
+ }
+
+ inline std::size_t getNumStaticArguments() const {
+ return num_static_arguments_;
+ }
+
+ inline bool operator==(const OperationSignature &r) const {
+ return operation_name_ == r.operation_name_
+ && argument_type_ids_ == r.argument_type_ids_
+ && num_static_arguments_ == r.num_static_arguments_;
+ }
+
+ inline bool operator!=(const OperationSignature &r) const {
+ return !(*this == r);
+ }
+
+ inline bool operator<(const OperationSignature &r) const {
+ int cmp_code = operation_name_.compare(r.operation_name_);
+ if (cmp_code != 0) {
+ return cmp_code < 0;
+ }
+ cmp_code = static_cast<int>(getArity() - r.getArity());
+ if (cmp_code != 0) {
+ return cmp_code < 0;
+ }
+ cmp_code = static_cast<int>(num_static_arguments_ - r.num_static_arguments_);
+ if (cmp_code != 0) {
+ return cmp_code > 0;
+ }
+ for (std::size_t i = 0; i < getArity(); ++i) {
+ const auto l_tid =
+ static_cast<std::underlying_type_t<TypeID>>(argument_type_ids_.at(i));
+ const auto r_tid =
+ static_cast<std::underlying_type_t<TypeID>>(r.argument_type_ids_.at(i));
+ if (l_tid != r_tid) {
+ return l_tid < r_tid;
+ }
+ }
+ return false;
+ }
+
+ inline std::size_t hash() const {
+ std::size_t hash_code = std::hash<std::string>()(operation_name_);
+ for (const TypeID tid : argument_type_ids_) {
+ hash_code = CombineHashes(hash_code, static_cast<std::size_t>(tid));
+ }
+ hash_code = CombineHashes(hash_code, num_static_arguments_);
+ return hash_code;
+ }
+
+ std::string toString() const;
+
+ static OperationSignaturePtr Create(
+ const std::string &operation_name,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::size_t num_static_arguments) {
+ return OperationSignaturePtr(
+ new OperationSignature(operation_name,
+ argument_type_ids,
+ num_static_arguments));
+ }
+
+ static OperationSignaturePtr Create(
+ const std::string &operation_name,
+ const std::vector<TypeID> ®ular_argument_type_ids,
+ const std::vector<TypeID> &static_argument_type_ids) {
+ std::vector<TypeID> argument_type_ids = regular_argument_type_ids;
+ argument_type_ids.insert(argument_type_ids.end(),
+ static_argument_type_ids.begin(),
+ static_argument_type_ids.end());
+ return OperationSignaturePtr(
+ new OperationSignature(operation_name,
+ argument_type_ids,
+ static_argument_type_ids.size()));
+ }
+
+ private:
+ OperationSignature(const std::string &operation_name,
+ const std::vector<TypeID> &argument_type_ids,
+ const std::size_t num_static_arguments)
+ : operation_name_(operation_name),
+ argument_type_ids_(argument_type_ids),
+ num_static_arguments_(num_static_arguments) {
+ DCHECK_GE(argument_type_ids_.size(), num_static_arguments_);
+ }
+
+ const std::string operation_name_;
+ const std::vector<TypeID> argument_type_ids_;
+ const std::size_t num_static_arguments_;
+
+ DISALLOW_COPY_AND_ASSIGN(OperationSignature);
+};
+
+/**
+ * @brief Implements the equal function for operation signatures.
+ */
+struct OperationSignatureEqual {
+ inline bool operator()(const OperationSignaturePtr &lhs,
+ const OperationSignaturePtr &rhs) const {
+ return *lhs == *rhs;
+ }
+};
+
+/**
+ * @brief Implements the hash function for operation signatures.
+ */
+struct OperationSignatureHash {
+ inline std::size_t operator()(const OperationSignaturePtr &op_sig) const {
+ return op_sig->hash();
+ }
+};
+
+/** @} */
+
+} // namespace quickstep
+
+#endif // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SIGNATURE_HPP_