diff --git a/velox/functions/prestosql/TypeOf.cpp b/velox/functions/prestosql/TypeOf.cpp index f2a16af5ac2ff..9c4659921e932 100644 --- a/velox/functions/prestosql/TypeOf.cpp +++ b/velox/functions/prestosql/TypeOf.cpp @@ -18,6 +18,7 @@ #include "velox/functions/prestosql/types/IPAddressType.h" #include "velox/functions/prestosql/types/IPPrefixType.h" #include "velox/functions/prestosql/types/JsonType.h" +#include "velox/functions/prestosql/types/TDigestType.h" #include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h" #include "velox/functions/prestosql/types/UuidType.h" @@ -80,6 +81,9 @@ std::string typeName(const TypePtr& type) { if (isHyperLogLogType(type)) { return "HyperLogLog"; } + if (isTDigestType(type)) { + return "TDigest"; + } return "varbinary"; case TypeKind::TIMESTAMP: return "timestamp"; diff --git a/velox/functions/prestosql/tests/CMakeLists.txt b/velox/functions/prestosql/tests/CMakeLists.txt index 477cf20937694..ce0a9304b1f7c 100644 --- a/velox/functions/prestosql/tests/CMakeLists.txt +++ b/velox/functions/prestosql/tests/CMakeLists.txt @@ -100,6 +100,7 @@ add_executable( TransformValuesTest.cpp TrimFunctionsTest.cpp TypeOfTest.cpp + TDigestCastTest.cpp URLFunctionsTest.cpp UuidFunctionsTest.cpp WidthBucketArrayTest.cpp diff --git a/velox/functions/prestosql/tests/TDigestCastTest.cpp b/velox/functions/prestosql/tests/TDigestCastTest.cpp new file mode 100644 index 0000000000000..42da507d6e615 --- /dev/null +++ b/velox/functions/prestosql/tests/TDigestCastTest.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "velox/functions/prestosql/tests/CastBaseTest.h" +#include "velox/functions/prestosql/types/TDigestType.h" + +using namespace facebook::velox; + +class TDigestCastTest : public functions::test::CastBaseTest {}; + +TEST_F(TDigestCastTest, toTDigest) { + testCast( + VARBINARY(), + TDIGEST(), + {"aaa"_sv, ""_sv, std::nullopt}, + {"aaa"_sv, ""_sv, std::nullopt}); + testCast( + VARBINARY(), + TDIGEST(), + {std::nullopt, std::nullopt, std::nullopt, std::nullopt}, + {std::nullopt, std::nullopt, std::nullopt, std::nullopt}); +} + +TEST_F(TDigestCastTest, fromTDigest) { + testCast( + TDIGEST(), + VARBINARY(), + {"aaa"_sv, ""_sv, std::nullopt}, + {"aaa"_sv, ""_sv, std::nullopt}); + testCast( + TDIGEST(), + VARBINARY(), + {std::nullopt, std::nullopt, std::nullopt, std::nullopt}, + {std::nullopt, std::nullopt, std::nullopt, std::nullopt}); +} diff --git a/velox/functions/prestosql/tests/TypeOfTest.cpp b/velox/functions/prestosql/tests/TypeOfTest.cpp index 6921fc171bb22..c35afb48e4e5d 100644 --- a/velox/functions/prestosql/tests/TypeOfTest.cpp +++ b/velox/functions/prestosql/tests/TypeOfTest.cpp @@ -17,6 +17,7 @@ #include "velox/functions/prestosql/tests/utils/FunctionBaseTest.h" #include "velox/functions/prestosql/types/HyperLogLogType.h" #include "velox/functions/prestosql/types/JsonType.h" +#include "velox/functions/prestosql/types/TDigestType.h" #include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h" namespace facebook::velox::functions { @@ -56,6 +57,8 @@ TEST_F(TypeOfTest, basic) { EXPECT_EQ("HyperLogLog", typeOf(HYPERLOGLOG())); + EXPECT_EQ("TDigest", typeOf(TDIGEST())); + EXPECT_EQ("unknown", typeOf(UNKNOWN())); EXPECT_EQ("array(integer)", typeOf(ARRAY(INTEGER()))); diff --git a/velox/functions/prestosql/types/CMakeLists.txt b/velox/functions/prestosql/types/CMakeLists.txt index f096568ff6d60..4f5b027abae5f 100644 --- a/velox/functions/prestosql/types/CMakeLists.txt +++ b/velox/functions/prestosql/types/CMakeLists.txt @@ -15,6 +15,7 @@ velox_add_library( velox_presto_types HyperLogLogType.cpp JsonType.cpp + TDigestType.cpp TimestampWithTimeZoneType.cpp UuidType.cpp IPAddressType.cpp diff --git a/velox/functions/prestosql/types/TDigestType.cpp b/velox/functions/prestosql/types/TDigestType.cpp new file mode 100644 index 0000000000000..309295352ebd0 --- /dev/null +++ b/velox/functions/prestosql/types/TDigestType.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "velox/functions/prestosql/types/TDigestType.h" + +namespace facebook::velox { + +void registerTDigestType() { + registerCustomType("tdigest", std::make_unique()); +} + +} // namespace facebook::velox diff --git a/velox/functions/prestosql/types/TDigestType.h b/velox/functions/prestosql/types/TDigestType.h new file mode 100644 index 0000000000000..97fd1a3f0dce8 --- /dev/null +++ b/velox/functions/prestosql/types/TDigestType.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "velox/type/SimpleFunctionApi.h" +#include "velox/type/Type.h" +#include "velox/vector/VectorTypeUtils.h" + +namespace facebook::velox { + +class TDigestType : public VarbinaryType { + TDigestType() = default; + + public: + static const std::shared_ptr& get() { + static const std::shared_ptr instance = + std::shared_ptr(new TDigestType()); + + return instance; + } + + bool equivalent(const Type& other) const override { + // Pointer comparison works since this type is a singleton. + return this == &other; + } + + const char* name() const override { + return "TDIGEST"; + } + + std::string toString() const override { + return name(); + } + + folly::dynamic serialize() const override { + folly::dynamic obj = folly::dynamic::object; + obj["name"] = "Type"; + obj["type"] = name(); + return obj; + } +}; + +inline bool isTDigestType(const TypePtr& type) { + // Pointer comparison works since this type is a singleton. + return TDigestType::get() == type; +} + +inline std::shared_ptr TDIGEST() { + return TDigestType::get(); +} + +// Type to use for inputs and outputs of simple functions, e.g. +// arg_type and out_type. +struct TDigestT { + using type = Varbinary; + static constexpr const char* typeName = "tdigest"; +}; + +using TDigest = CustomType; + +class TDigestTypeFactories : public CustomTypeFactories { + public: + TypePtr getType() const override { + return TDIGEST(); + } + + // TDigest should be treated as Varbinary during type castings. + exec::CastOperatorPtr getCastOperator() const override { + return nullptr; + } + + AbstractInputGeneratorPtr getInputGenerator( + const InputGeneratorConfig& /*config*/) const override { + return nullptr; + } +}; + +void registerTDigestType(); + +} // namespace facebook::velox diff --git a/velox/functions/prestosql/types/tests/TDigestTypeTest.cpp b/velox/functions/prestosql/types/tests/TDigestTypeTest.cpp new file mode 100644 index 0000000000000..ab55b00d9b718 --- /dev/null +++ b/velox/functions/prestosql/types/tests/TDigestTypeTest.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "velox/functions/prestosql/types/TDigestType.h" +#include "velox/functions/prestosql/types/tests/TypeTestBase.h" + +namespace facebook::velox::test { + +class TDigestTypeTest : public testing::Test, public TypeTestBase { + public: + TDigestTypeTest() { + registerTDigestType(); + } +}; + +TEST_F(TDigestTypeTest, basic) { + ASSERT_STREQ(TDIGEST()->name(), "TDIGEST"); + ASSERT_STREQ(TDIGEST()->kindName(), "VARBINARY"); + ASSERT_TRUE(TDIGEST()->parameters().empty()); + ASSERT_EQ(TDIGEST()->toString(), "TDIGEST"); + + ASSERT_TRUE(hasType("TDIGEST")); + ASSERT_EQ(*getType("TDIGEST", {}), *TDIGEST()); +} + +TEST_F(TDigestTypeTest, serde) { + testTypeSerde(TDIGEST()); +} +} // namespace facebook::velox::test