From 0b8034d2378d9097179c4b232542bbcd64bad4d4 Mon Sep 17 00:00:00 2001 From: Deepak Majeti Date: Tue, 31 May 2022 10:45:13 -0400 Subject: [PATCH 1/3] Add equivalent function to Type --- velox/type/Type.cpp | 47 ++++++++++--- velox/type/Type.h | 124 +++++++++++++++++++--------------- velox/type/tests/TypeTest.cpp | 56 ++++++++++++--- 3 files changed, 158 insertions(+), 69 deletions(-) diff --git a/velox/type/Type.cpp b/velox/type/Type.cpp index 65d391f37eae..be7816bdea74 100644 --- a/velox/type/Type.cpp +++ b/velox/type/Type.cpp @@ -196,7 +196,7 @@ const std::shared_ptr& ArrayType::childAt(uint32_t idx) const { ArrayType::ArrayType(std::shared_ptr child) : child_{std::move(child)} {} -bool ArrayType::operator==(const Type& other) const { +bool ArrayType::equivalent(const Type& other) const { if (&other == this) { return true; } @@ -230,6 +230,20 @@ std::string FixedSizeArrayType::toString() const { return ss.str(); } +bool FixedSizeArrayType::equivalent(const Type& other) const { + if (!ArrayType::equivalent(other)) { + return false; + } + auto otherFixedSizeArray = dynamic_cast(&other); + if (!otherFixedSizeArray) { + return false; + } + if (fixedElementsWidth() != otherFixedSizeArray->fixedElementsWidth()) { + return false; + } + return true; +} + const std::shared_ptr& MapType::childAt(uint32_t idx) const { if (idx == 0) { return keyType(); @@ -329,7 +343,7 @@ std::optional RowType::getChildIdxIfExists( return std::nullopt; } -bool RowType::operator==(const Type& other) const { +bool RowType::equivalent(const Type& other) const { if (&other == this) { return true; } @@ -341,11 +355,21 @@ bool RowType::operator==(const Type& other) const { return false; } for (size_t i = 0; i < size(); ++i) { - // todo: case sensitivity - if (nameOf(i) != otherTyped.nameOf(i)) { + if (*childAt(i) != *otherTyped.childAt(i)) { return false; } - if (*childAt(i) != *otherTyped.childAt(i)) { + } + return true; +} + +bool RowType::operator==(const Type& other) const { + if (!this->equivalent(other)) { + return false; + } + auto& otherTyped = other.asRow(); + for (size_t i = 0; i < size(); ++i) { + // todo: case sensitivity + if (nameOf(i) != otherTyped.nameOf(i)) { return false; } } @@ -411,7 +435,7 @@ bool Type::kindEquals(const std::shared_ptr& other) const { return true; } -bool MapType::operator==(const Type& other) const { +bool MapType::equivalent(const Type& other) const { if (&other == this) { return true; } @@ -422,7 +446,7 @@ bool MapType::operator==(const Type& other) const { return *keyType_ == *otherMap.keyType_ && *valueType_ == *otherMap.valueType_; } -bool FunctionType::operator==(const Type& other) const { +bool FunctionType::equivalent(const Type& other) const { if (&other == this) { return true; } @@ -450,13 +474,20 @@ folly::dynamic FunctionType::serialize() const { OpaqueType::OpaqueType(const std::type_index& typeIndex) : typeIndex_(typeIndex) {} -bool OpaqueType::operator==(const Type& other) const { +bool OpaqueType::equivalent(const Type& other) const { if (&other == this) { return true; } if (other.kind() != TypeKind::OPAQUE) { return false; } + return true; +} + +bool OpaqueType::operator==(const Type& other) const { + if (!this->equivalent(other)) { + return false; + } auto& otherTyped = *reinterpret_cast(&other); return typeIndex_ == otherTyped.typeIndex_; } diff --git a/velox/type/Type.h b/velox/type/Type.h index 14181981a77d..33d9003f41b6 100644 --- a/velox/type/Type.h +++ b/velox/type/Type.h @@ -471,7 +471,19 @@ class Type : public Tree>, virtual std::string toString() const = 0; - virtual bool operator==(const Type& other) const = 0; + // Types are weakly matched. + // Examples: Two RowTypes are equivalent if the children types are equivalent, + // but the children names could be different. Two OpaqueTypes are equivalent + // if the typeKind matches, but the typeIndex could be different. + virtual bool equivalent(const Type& other) const = 0; + + // Types are strongly matched. + // Examples: Two RowTypes are == if the children types and the children names + // are same. Two OpaqueTypes are == if the typeKind and the typeIndex are + // same. Same as equivalent for most types except for Row, Opaque types. + virtual bool operator==(const Type& other) const { + return this->equivalent(other); + } inline bool operator!=(const Type& other) const { return !(*this == other); @@ -492,10 +504,10 @@ class Type : public Tree>, static std::shared_ptr create(const folly::dynamic& obj); - // recursive kind hashing (ignores names) + // recursive kind hashing (uses only typeKind) size_t hashKind() const; - // recursive kind match (ignores names) + // recursive kind match (uses only typeKind) bool kindEquals(const std::shared_ptr& other) const; template @@ -556,8 +568,49 @@ class TypeBase : public Type { } }; -using ShortDecimalType = DecimalType; -using LongDecimalType = DecimalType; +template +class ScalarType : public TypeBase { + public: + uint32_t size() const override { + return 0; + } + + const std::shared_ptr& childAt(uint32_t) const override { + throw std::invalid_argument{"scalar type has no children"}; + } + + std::string toString() const override { + return TypeTraits::name; + } + + size_t cppSizeInBytes() const override { + if (TypeTraits::isFixedWidth) { + return sizeof(typename TypeTraits::NativeType); + } + // TODO: velox throws here for non fixed width types. + return Type::cppSizeInBytes(); + } + + FOLLY_NOINLINE static const std::shared_ptr> create(); + + bool equivalent(const Type& other) const override { + return KIND == other.kind(); + } + + // TODO: velox implementation is in cpp + folly::dynamic serialize() const override { + folly::dynamic obj = folly::dynamic::object; + obj["name"] = "Type"; + obj["type"] = TypeTraits::name; + return obj; + } +}; + +template +const std::shared_ptr> ScalarType::create() { + static const auto instance = std::make_shared>(); + return instance; +} /// This class represents the fixed-point numbers. /// The parameter "precision" represents the number of digits the @@ -577,7 +630,7 @@ class DecimalType : public ScalarType { VELOX_CHECK_LE(precision, kMaxPrecision); } - inline bool operator==(const Type& otherDecimal) const override { + inline bool equivalent(const Type& otherDecimal) const override { if (this->kind() != otherDecimal.kind()) { return false; } @@ -611,49 +664,8 @@ class DecimalType : public ScalarType { const uint8_t scale_; }; -template -class ScalarType : public TypeBase { - public: - uint32_t size() const override { - return 0; - } - - const std::shared_ptr& childAt(uint32_t) const override { - throw std::invalid_argument{"scalar type has no children"}; - } - - std::string toString() const override { - return TypeTraits::name; - } - - size_t cppSizeInBytes() const override { - if (TypeTraits::isFixedWidth) { - return sizeof(typename TypeTraits::NativeType); - } - // TODO: velox throws here for non fixed width types. - return Type::cppSizeInBytes(); - } - - FOLLY_NOINLINE static const std::shared_ptr> create(); - - bool operator==(const Type& other) const override { - return KIND == other.kind(); - } - - // TODO: velox implementation is in cpp - folly::dynamic serialize() const override { - folly::dynamic obj = folly::dynamic::object; - obj["name"] = "Type"; - obj["type"] = TypeTraits::name; - return obj; - } -}; - -template -const std::shared_ptr> ScalarType::create() { - static const auto instance = std::make_shared>(); - return instance; -} +using ShortDecimalType = DecimalType; +using LongDecimalType = DecimalType; class UnknownType : public TypeBase { public: @@ -675,7 +687,7 @@ class UnknownType : public TypeBase { return 0; } - bool operator==(const Type& other) const override { + bool equivalent(const Type& other) const override { return TypeKind::UNKNOWN == other.kind(); } @@ -703,7 +715,7 @@ class ArrayType : public TypeBase { std::string toString() const override; - bool operator==(const Type& other) const override; + bool equivalent(const Type& other) const override; folly::dynamic serialize() const override; @@ -734,6 +746,8 @@ class FixedSizeArrayType : public ArrayType { return "FIXED_SIZE_ARRAY"; } + bool equivalent(const Type& other) const override; + std::string toString() const override; private: @@ -762,7 +776,7 @@ class MapType : public TypeBase { const std::shared_ptr& childAt(uint32_t idx) const override; - bool operator==(const Type& other) const override; + bool equivalent(const Type& other) const override; folly::dynamic serialize() const override; @@ -798,6 +812,8 @@ class RowType : public TypeBase { return names_.at(idx); } + bool equivalent(const Type& other) const override; + bool operator==(const Type& other) const override; std::string toString() const override; @@ -847,7 +863,7 @@ class FunctionType : public TypeBase { return children_; } - bool operator==(const Type& other) const override; + bool equivalent(const Type& other) const override; std::string toString() const override; @@ -884,6 +900,8 @@ class OpaqueType : public TypeBase { std::string toString() const override; + bool equivalent(const Type& other) const override; + bool operator==(const Type& other) const override; const std::type_index& typeIndex() const { diff --git a/velox/type/tests/TypeTest.cpp b/velox/type/tests/TypeTest.cpp index 2c36141602e1..f1ba51d2c839 100644 --- a/velox/type/tests/TypeTest.cpp +++ b/velox/type/tests/TypeTest.cpp @@ -465,6 +465,11 @@ TEST(TypeTest, equality) { EXPECT_TRUE(*ARRAY(INTEGER()) == *ARRAY(INTEGER())); EXPECT_FALSE(*ARRAY(INTEGER()) == *ARRAY(REAL())); EXPECT_FALSE(*ARRAY(INTEGER()) == *ARRAY(ARRAY(INTEGER()))); + EXPECT_TRUE( + *FIXED_SIZE_ARRAY(10, INTEGER()) == *FIXED_SIZE_ARRAY(10, INTEGER())); + EXPECT_FALSE(*FIXED_SIZE_ARRAY(10, INTEGER()) == *ARRAY(INTEGER())); + EXPECT_FALSE( + *FIXED_SIZE_ARRAY(10, INTEGER()) == *FIXED_SIZE_ARRAY(9, INTEGER())); // struct EXPECT_TRUE( @@ -510,14 +515,29 @@ TEST(TypeTest, cpp2Type) { EXPECT_EQ(*type, *MAP(INTEGER(), MAP(BIGINT(), REAL()))); } -TEST(TypeTest, kindHash) { - EXPECT_EQ(BIGINT()->hashKind(), BIGINT()->hashKind()); - EXPECT_EQ(TIMESTAMP()->hashKind(), TIMESTAMP()->hashKind()); - EXPECT_EQ(DATE()->hashKind(), DATE()->hashKind()); - EXPECT_EQ(INTERVAL_DAY_TIME()->hashKind(), INTERVAL_DAY_TIME()->hashKind()); - EXPECT_NE(BIGINT()->hashKind(), INTEGER()->hashKind()); - EXPECT_EQ( - ROW({{"a", BIGINT()}})->hashKind(), ROW({{"b", BIGINT()}})->hashKind()); +TEST(TypeTest, equivalent) { + EXPECT_TRUE(ROW({{"a", BIGINT()}})->equivalent(*ROW({{"b", BIGINT()}}))); + EXPECT_FALSE(ROW({{"a", BIGINT()}})->equivalent(*ROW({{"a", INTEGER()}}))); + EXPECT_TRUE(MAP(BIGINT(), BIGINT())->equivalent(*MAP(BIGINT(), BIGINT()))); + EXPECT_FALSE( + MAP(BIGINT(), BIGINT())->equivalent(*MAP(BIGINT(), ARRAY(BIGINT())))); + EXPECT_TRUE(ARRAY(BIGINT())->equivalent(*ARRAY(BIGINT()))); + EXPECT_FALSE(ARRAY(BIGINT())->equivalent(*ARRAY(INTEGER()))); + EXPECT_FALSE(ARRAY(BIGINT())->equivalent(*ROW({{"a", BIGINT()}}))); + EXPECT_FALSE(FIXED_SIZE_ARRAY(10, BIGINT())->equivalent(*ARRAY(BIGINT()))); + EXPECT_FALSE(FIXED_SIZE_ARRAY(10, BIGINT()) + ->equivalent(*FIXED_SIZE_ARRAY(9, BIGINT()))); + EXPECT_TRUE(FIXED_SIZE_ARRAY(10, BIGINT()) + ->equivalent(*FIXED_SIZE_ARRAY(10, BIGINT()))); + EXPECT_TRUE(SHORT_DECIMAL(10, 5)->equivalent(*SHORT_DECIMAL(10, 5))); + EXPECT_FALSE(SHORT_DECIMAL(10, 6)->equivalent(*SHORT_DECIMAL(10, 5))); + EXPECT_FALSE(SHORT_DECIMAL(11, 5)->equivalent(*SHORT_DECIMAL(10, 5))); + EXPECT_TRUE(LONG_DECIMAL(30, 5)->equivalent(*LONG_DECIMAL(30, 5))); + EXPECT_FALSE(LONG_DECIMAL(30, 6)->equivalent(*LONG_DECIMAL(30, 5))); + EXPECT_FALSE(LONG_DECIMAL(31, 5)->equivalent(*LONG_DECIMAL(30, 5))); +} + +TEST(TypeTest, kindEquals) { EXPECT_TRUE(ROW({{"a", BIGINT()}})->kindEquals(ROW({{"b", BIGINT()}}))); EXPECT_FALSE(ROW({{"a", BIGINT()}})->kindEquals(ROW({{"a", INTEGER()}}))); EXPECT_TRUE(MAP(BIGINT(), BIGINT())->kindEquals(MAP(BIGINT(), BIGINT()))); @@ -526,7 +546,27 @@ TEST(TypeTest, kindHash) { EXPECT_TRUE(ARRAY(BIGINT())->kindEquals(ARRAY(BIGINT()))); EXPECT_FALSE(ARRAY(BIGINT())->kindEquals(ARRAY(INTEGER()))); EXPECT_FALSE(ARRAY(BIGINT())->kindEquals(ROW({{"a", BIGINT()}}))); + EXPECT_TRUE(FIXED_SIZE_ARRAY(10, BIGINT())->kindEquals(ARRAY(BIGINT()))); + EXPECT_TRUE(FIXED_SIZE_ARRAY(10, BIGINT()) + ->kindEquals(FIXED_SIZE_ARRAY(9, BIGINT()))); + EXPECT_TRUE(FIXED_SIZE_ARRAY(10, BIGINT()) + ->kindEquals(FIXED_SIZE_ARRAY(10, BIGINT()))); + EXPECT_TRUE(SHORT_DECIMAL(10, 5)->kindEquals(SHORT_DECIMAL(10, 5))); + EXPECT_TRUE(SHORT_DECIMAL(10, 6)->kindEquals(SHORT_DECIMAL(10, 5))); + EXPECT_TRUE(SHORT_DECIMAL(11, 5)->kindEquals(SHORT_DECIMAL(10, 5))); + EXPECT_TRUE(LONG_DECIMAL(30, 5)->kindEquals(LONG_DECIMAL(30, 5))); + EXPECT_TRUE(LONG_DECIMAL(30, 6)->kindEquals(LONG_DECIMAL(30, 5))); + EXPECT_TRUE(LONG_DECIMAL(31, 5)->kindEquals(LONG_DECIMAL(30, 5))); +} +TEST(TypeTest, kindHash) { + EXPECT_EQ(BIGINT()->hashKind(), BIGINT()->hashKind()); + EXPECT_EQ(TIMESTAMP()->hashKind(), TIMESTAMP()->hashKind()); + EXPECT_EQ(DATE()->hashKind(), DATE()->hashKind()); + EXPECT_EQ(INTERVAL_DAY_TIME()->hashKind(), INTERVAL_DAY_TIME()->hashKind()); + EXPECT_NE(BIGINT()->hashKind(), INTEGER()->hashKind()); + EXPECT_EQ( + ROW({{"a", BIGINT()}})->hashKind(), ROW({{"b", BIGINT()}})->hashKind()); EXPECT_EQ( MAP(BIGINT(), BIGINT())->hashKind(), MAP(BIGINT(), BIGINT())->hashKind()); EXPECT_NE( From 96f501bdc773a8d648bcc4ac292feb663c181d54 Mon Sep 17 00:00:00 2001 From: Deepak Majeti Date: Wed, 8 Jun 2022 11:54:11 -0400 Subject: [PATCH 2/3] use equivalent inside SignatureBinder --- velox/expression/SignatureBinder.cpp | 4 +-- .../expression/tests/SignatureBinderTest.cpp | 25 +++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/velox/expression/SignatureBinder.cpp b/velox/expression/SignatureBinder.cpp index d41e6cf6c139..d1812472b075 100644 --- a/velox/expression/SignatureBinder.cpp +++ b/velox/expression/SignatureBinder.cpp @@ -38,7 +38,7 @@ bool SignatureBinder::tryBind() { if (actualTypes_.size() > formalArgsCnt) { auto& type = actualTypes_[formalArgsCnt - 1]; for (auto i = formalArgsCnt; i < actualTypes_.size(); i++) { - if (!type->kindEquals(actualTypes_[i]) && + if (!type->equivalent(*actualTypes_[i]) && actualTypes_[i]->kind() != TypeKind::UNKNOWN) { return false; } @@ -98,7 +98,7 @@ bool SignatureBinder::tryBind( return true; } - return it->second->kindEquals(actualType); + return it->second->equivalent(*actualType); } TypePtr SignatureBinder::tryResolveType( diff --git a/velox/expression/tests/SignatureBinderTest.cpp b/velox/expression/tests/SignatureBinderTest.cpp index a5d3bc9af264..6193e2909ac4 100644 --- a/velox/expression/tests/SignatureBinderTest.cpp +++ b/velox/expression/tests/SignatureBinderTest.cpp @@ -30,6 +30,13 @@ void testSignatureBinder( ASSERT_TRUE(expectedReturnType->kindEquals(returnType)); } +void assertCannotResolve( + const std::shared_ptr& signature, + const std::vector& actualTypes) { + exec::SignatureBinder binder(*signature, actualTypes); + ASSERT_FALSE(binder.tryBind()); +} + TEST(SignatureBinderTest, generics) { // array(T), T -> boolean { @@ -41,6 +48,17 @@ TEST(SignatureBinderTest, generics) { .build(); testSignatureBinder(signature, {ARRAY(BIGINT()), BIGINT()}, BOOLEAN()); + testSignatureBinder( + signature, {ARRAY(DECIMAL(20, 3)), DECIMAL(20, 3)}, BOOLEAN()); + assertCannotResolve(signature, {ARRAY(DECIMAL(20, 3)), DECIMAL(20, 4)}); + testSignatureBinder( + signature, + {ARRAY(FIXED_SIZE_ARRAY(20, BIGINT())), FIXED_SIZE_ARRAY(20, BIGINT())}, + BOOLEAN()); + assertCannotResolve( + signature, + {ARRAY(FIXED_SIZE_ARRAY(20, BIGINT())), + FIXED_SIZE_ARRAY(10, BIGINT())}); } // array(array(T)), array(T) -> boolean @@ -146,13 +164,6 @@ TEST(SignatureBinderTest, variableArity) { } } -void assertCannotResolve( - const std::shared_ptr& signature, - const std::vector& actualTypes) { - exec::SignatureBinder binder(*signature, actualTypes); - ASSERT_FALSE(binder.tryBind()); -} - TEST(SignatureBinderTest, unresolvable) { // integer -> varchar { From bc9998e0efa01cea734599c04e2dabb883249b1c Mon Sep 17 00:00:00 2001 From: Deepak Majeti Date: Wed, 8 Jun 2022 12:36:10 -0400 Subject: [PATCH 3/3] Fix comments --- velox/type/Type.h | 146 +++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/velox/type/Type.h b/velox/type/Type.h index 33d9003f41b6..239946b4b5ce 100644 --- a/velox/type/Type.h +++ b/velox/type/Type.h @@ -47,20 +47,20 @@ namespace facebook::velox { using int128_t = __int128_t; -// Velox type system supports a small set of SQL-compatible composeable types: -// BOOLEAN, TINYINT, SMALLINT, INTEGER, BIGINT, REAL, DOUBLE, VARCHAR, -// VARBINARY, TIMESTAMP, DATE, INTERVAL_DAY_TIME, ARRAY, MAP, ROW -// -// This file has multiple C++ type definitions for each of these logical types. -// These logical definitions each serve slightly different purposes. -// These type sets are: -// - TypeKind -// - Type (RowType, BigIntType, ect.) -// - Templated Types (Row, Map, ...) -// C++ templated classes. Never instantiated, used to pass limited type -// information into template parameters. - -// Simple enum with type category. +/// Velox type system supports a small set of SQL-compatible composeable types: +/// BOOLEAN, TINYINT, SMALLINT, INTEGER, BIGINT, REAL, DOUBLE, VARCHAR, +/// VARBINARY, TIMESTAMP, DATE, INTERVAL_DAY_TIME, ARRAY, MAP, ROW +/// +/// This file has multiple C++ type definitions for each of these logical types. +/// These logical definitions each serve slightly different purposes. +/// These type sets are: +/// - TypeKind +/// - Type (RowType, BigIntType, ect.) +/// - Templated Types (Row, Map, ...) +/// C++ templated classes. Never instantiated, used to pass limited type +/// information into template parameters. + +/// Simple enum with type category. enum class TypeKind : int8_t { BOOLEAN = 0, TINYINT = 1, @@ -88,11 +88,11 @@ enum class TypeKind : int8_t { INVALID = 36 }; -// Returns the typekind represented by the `name`. Throws if no match found. +/// Returns the typekind represented by the `name`. Throws if no match found. TypeKind mapNameToTypeKind(const std::string& name); -// Returns the typekind represented by the `name` and std::nullopt if no -// match found. +/// Returns the typekind represented by the `name` and std::nullopt if no +/// match found. std::optional tryMapNameToTypeKind(const std::string& name); std::string mapTypeKindToName(const TypeKind& typeKind); @@ -434,18 +434,18 @@ struct TypeFactory; return this->kind() == TypeKind::KIND; \ } -// Abstract class hierarchy. Instances of these classes carry full -// information about types, including for example field names. -// Can be instantiated by factory methods, like INTEGER() -// or MAP(INTEGER(), BIGINT()). -// Instances of these classes form a tree, and are immutable. -// For example, MAP> will form a tree like: -// -// MapType -// / \ -// IntegerType ArrayType -// | -// BigintType +/// Abstract class hierarchy. Instances of these classes carry full +/// information about types, including for example field names. +/// Can be instantiated by factory methods, like INTEGER() +/// or MAP(INTEGER(), BIGINT()). +/// Instances of these classes form a tree, and are immutable. +/// For example, MAP> will form a tree like: +/// +/// MapType +/// / \ +/// IntegerType ArrayType +/// | +/// BigintType class Type : public Tree>, public velox::ISerializable { public: @@ -457,9 +457,9 @@ class Type : public Tree>, virtual ~Type() = default; - // this convenience method makes pattern matching easier. Rather than having - // to know the implementation type up front, just use as (for - // example) to dynamically cast to the appropriate type. + /// This convenience method makes pattern matching easier. Rather than having + /// to know the implementation type up front, just use as (for + /// example) to dynamically cast to the appropriate type. template const typename TypeTraits::ImplType& as() const { return dynamic_cast::ImplType&>(*this); @@ -471,16 +471,16 @@ class Type : public Tree>, virtual std::string toString() const = 0; - // Types are weakly matched. - // Examples: Two RowTypes are equivalent if the children types are equivalent, - // but the children names could be different. Two OpaqueTypes are equivalent - // if the typeKind matches, but the typeIndex could be different. + /// Types are weakly matched. + /// Examples: Two RowTypes are equivalent if the children types are + /// equivalent, but the children names could be different. Two OpaqueTypes are + /// equivalent if the typeKind matches, but the typeIndex could be different. virtual bool equivalent(const Type& other) const = 0; - // Types are strongly matched. - // Examples: Two RowTypes are == if the children types and the children names - // are same. Two OpaqueTypes are == if the typeKind and the typeIndex are - // same. Same as equivalent for most types except for Row, Opaque types. + /// Types are strongly matched. + /// Examples: Two RowTypes are == if the children types and the children names + /// are same. Two OpaqueTypes are == if the typeKind and the typeIndex are + /// same. Same as equivalent for most types except for Row, Opaque types. virtual bool operator==(const Type& other) const { return this->equivalent(other); } @@ -497,17 +497,17 @@ class Type : public Tree>, virtual bool isFixedWidth() const = 0; - // Used in FixedSizeArrayType to return the width constraint of the type. + /// Used in FixedSizeArrayType to return the width constraint of the type. virtual size_type fixedElementsWidth() const { throw std::invalid_argument{"unimplemented"}; } static std::shared_ptr create(const folly::dynamic& obj); - // recursive kind hashing (uses only typeKind) + /// Recursive kind hashing (uses only TypeKind). size_t hashKind() const; - // recursive kind match (uses only typeKind) + /// Recursive kind match (uses only TypeKind). bool kindEquals(const std::shared_ptr& other) const; template @@ -723,13 +723,13 @@ class ArrayType : public TypeBase { std::shared_ptr child_; }; -// FixedSizeArrayType implements an Array that is constrained to -// always be a fixed size (width). When passing this type on the wire, -// a FixedSizeArrayType may change into a general variable width array -// as Presto/Spark do not have a notion of fixed size array. -// -// Anywhere an ArrayType can be used, a FixedSizeArrayType can be -// used. +/// FixedSizeArrayType implements an Array that is constrained to +/// always be a fixed size (width). When passing this type on the wire, +/// a FixedSizeArrayType may change into a general variable width array +/// as Presto/Spark do not have a notion of fixed size array. +/// +/// Anywhere an ArrayType can be used, a FixedSizeArrayType can be +/// used. class FixedSizeArrayType : public ArrayType { public: explicit FixedSizeArrayType(size_type len, std::shared_ptr child); @@ -841,8 +841,8 @@ inline RowTypePtr asRowType(const TypePtr& type) { return std::dynamic_pointer_cast(type); } -// Represents a lambda function. The children are the argument types -// followed by the return value type. +/// Represents a lambda function. The children are the argument types +/// followed by the return value type. class FunctionType : public TypeBase { public: FunctionType( @@ -909,34 +909,34 @@ class OpaqueType : public TypeBase { } folly::dynamic serialize() const override; - // In special cases specific OpaqueTypes might want to serialize additional - // metadata. In those cases we need to deserialize it back. Since - // OpaqueType::create() returns canonical type for T without metadata, we - // allow to create new instance here or return nullptr if the same one can be - // used. Note that it's about deserialization of type itself, DeserializeFunc - // above is about deserializing instances of the type. It's implemented as a - // virtual member instead of a standalone registry just for convenience. + /// In special cases specific OpaqueTypes might want to serialize additional + /// metadata. In those cases we need to deserialize it back. Since + /// OpaqueType::create() returns canonical type for T without metadata, we + /// allow to create new instance here or return nullptr if the same one can be + /// used. Note that it's about deserialization of type itself, DeserializeFunc + /// above is about deserializing instances of the type. It's implemented as a + /// virtual member instead of a standalone registry just for convenience. virtual std::shared_ptr deserializeExtra( const folly::dynamic& json) const; - // Function for converting std::shared_ptr into a string. Always returns - // non-nullptr function or throws if not function has been registered. + /// Function for converting std::shared_ptr into a string. Always returns + /// non-nullptr function or throws if not function has been registered. SerializeFunc getSerializeFunc() const; DeserializeFunc getDeserializeFunc() const; template FOLLY_NOINLINE static std::shared_ptr create() { - // static vars in templates are dangerous across DSOs, but it's just a - // performance optimization. Comparison looks at type_index anyway. + /// static vars in templates are dangerous across DSOs, but it's just a + /// performance optimization. Comparison looks at type_index anyway. static const auto instance = std::make_shared(std::type_index(typeid(Class))); return instance; } - // This function currently doesn't do synchronization neither with reads - // or writes, so it's caller's responsibility to not invoke it concurrently - // with other Velox code. Usually it'd be invoked at static initialization - // time. It can be changed in the future if it becomes a problem. + /// This function currently doesn't do synchronization neither with reads + /// or writes, so it's caller's responsibility to not invoke it concurrently + /// with other Velox code. Usually it'd be invoked at static initialization + /// time. It can be changed in the future if it becomes a problem. template FOLLY_NOINLINE static void registerSerialization( const std::string& persistentName, @@ -986,11 +986,11 @@ using VarbinaryType = ScalarType; using DateType = ScalarType; using IntervalDayTimeType = ScalarType; -// Used as T for SimpleVector subclasses that wrap another vector when -// the wrapped vector is of a complex type. Applies to -// DictionaryVector, SequenceVector and ConstantVector. This must have -// a size different from any of the scalar data type sizes to enable -// run time checking with 'elementSize_'. +/// Used as T for SimpleVector subclasses that wrap another vector when +/// the wrapped vector is of a complex type. Applies to +/// DictionaryVector, SequenceVector and ConstantVector. This must have +/// a size different from any of the scalar data type sizes to enable +/// run time checking with 'elementSize_'. struct ComplexType { TypePtr create() { VELOX_NYI(); @@ -1846,7 +1846,7 @@ class FormatValue { facebook::velox::TypeKind type_; }; -// Prints all types derived from `velox::Type`. +/// Prints all types derived from `velox::Type`. template class FormatValue< std::shared_ptr,