From 77fe34d7187474796e7fbc337762ac02431974fc Mon Sep 17 00:00:00 2001 From: Masha Basmanova Date: Sat, 21 Mar 2026 15:43:00 -0700 Subject: [PATCH] feat: Add toPrestoTypeSql() for Presto SQL type formatting (#16876) Summary: Move toTypeSql() from velox/exec/fuzzer/PrestoSql (test utility) to velox/functions/prestosql/types/PrestoTypeSql so it can be used from production code. Rename to toPrestoTypeSql() to clarify dialect. Fix a number of issues in the original implementation: - Custom types (IPPREFIX, BINGTILE) were expanded into their underlying ROW structure instead of using type->name(). Use typeid check to detect custom types implemented on top of ARRAY, MAP, or ROW. - Parameterized types (TDIGEST(DOUBLE), DECIMAL(10, 2)) were not handled. Use type->parameters() to format them generically. - ROW field names with spaces or special characters were not quoted. Use std::quoted() with Presto SQL double-quote escaping. - Unnamed ROW fields produced extra spaces. Also add VELOX_DECLARE_ENUM_NAME for TypeParameterKind. Needed for SHOW CREATE TABLE support in Axiom. Reviewed By: xiaoxmeng Differential Revision: D97605331 --- velox/exec/fuzzer/PrestoQueryRunner.cpp | 3 +- velox/exec/fuzzer/PrestoSql.cpp | 39 +----- velox/exec/fuzzer/PrestoSql.h | 3 - velox/exec/fuzzer/tests/PrestoSqlTest.cpp | 41 ------ .../functions/prestosql/types/CMakeLists.txt | 2 + .../prestosql/types/PrestoTypeSql.cpp | 124 ++++++++++++++++++ .../functions/prestosql/types/PrestoTypeSql.h | 25 ++++ .../prestosql/types/tests/CMakeLists.txt | 1 + .../types/tests/PrestoTypeSqlTest.cpp | 107 +++++++++++++++ velox/type/Type.cpp | 16 +++ velox/type/Type.h | 2 + 11 files changed, 285 insertions(+), 78 deletions(-) create mode 100644 velox/functions/prestosql/types/PrestoTypeSql.cpp create mode 100644 velox/functions/prestosql/types/PrestoTypeSql.h create mode 100644 velox/functions/prestosql/types/tests/PrestoTypeSqlTest.cpp diff --git a/velox/exec/fuzzer/PrestoQueryRunner.cpp b/velox/exec/fuzzer/PrestoQueryRunner.cpp index 0abcc12f13c2..002bf05184da 100644 --- a/velox/exec/fuzzer/PrestoQueryRunner.cpp +++ b/velox/exec/fuzzer/PrestoQueryRunner.cpp @@ -40,6 +40,7 @@ #include "velox/functions/prestosql/types/IPPrefixType.h" #include "velox/functions/prestosql/types/JsonType.h" #include "velox/functions/prestosql/types/KHyperLogLogType.h" +#include "velox/functions/prestosql/types/PrestoTypeSql.h" #include "velox/functions/prestosql/types/QDigestType.h" #include "velox/functions/prestosql/types/SetDigestType.h" #include "velox/functions/prestosql/types/SfmSketchType.h" @@ -396,7 +397,7 @@ std::string PrestoQueryRunner::createTable( for (auto i = 0; i < inputType->size(); ++i) { appendComma(i, nullValues); nullValues << fmt::format( - "cast(null as {})", toTypeSql(inputType->childAt(i))); + "cast(null as {})", toPrestoTypeSql(inputType->childAt(i))); } execute(fmt::format("DROP TABLE IF EXISTS {}", name)); diff --git a/velox/exec/fuzzer/PrestoSql.cpp b/velox/exec/fuzzer/PrestoSql.cpp index 6b034ef89d18..b3a5806e8cc4 100644 --- a/velox/exec/fuzzer/PrestoSql.cpp +++ b/velox/exec/fuzzer/PrestoSql.cpp @@ -19,6 +19,7 @@ #include "velox/exec/fuzzer/PrestoQueryRunner.h" #include "velox/exec/fuzzer/ReferenceQueryRunner.h" #include "velox/functions/prestosql/types/JsonType.h" +#include "velox/functions/prestosql/types/PrestoTypeSql.h" #include "velox/vector/SimpleVector.h" namespace facebook::velox::exec::test { @@ -71,36 +72,6 @@ void appendComma(int32_t i, std::stringstream& sql) { } } -// Returns the SQL string of the given type. -std::string toTypeSql(const TypePtr& type) { - switch (type->kind()) { - case TypeKind::ARRAY: - return fmt::format("ARRAY({})", toTypeSql(type->childAt(0))); - case TypeKind::MAP: - return fmt::format( - "MAP({}, {})", - toTypeSql(type->childAt(0)), - toTypeSql(type->childAt(1))); - case TypeKind::ROW: { - const auto& rowType = type->asRow(); - std::stringstream sql; - sql << "ROW("; - for (auto i = 0; i < type->size(); ++i) { - appendComma(i, sql); - // TODO Field names may need to be quoted. - sql << rowType.nameOf(i) << " " << toTypeSql(type->childAt(i)); - } - sql << ")"; - return sql.str(); - } - default: - if (type->isPrimitiveType()) { - return type->toString(); - } - VELOX_UNSUPPORTED("Type is not supported: {}", type->toString()); - } -} - std::string toLambdaSql(const core::LambdaTypedExprPtr& lambda) { std::stringstream sql; const auto& signature = lambda->signature(); @@ -346,7 +317,7 @@ std::string toCastSql(const core::CastTypedExpr& cast) { sql << "cast("; } toCallInputsSql(cast.inputs(), sql); - sql << " as " << toTypeSql(cast.type()); + sql << " as " << facebook::velox::toPrestoTypeSql(cast.type()); sql << ")"; return sql.str(); } @@ -355,7 +326,9 @@ std::string toConcatSql(const core::ConcatTypedExpr& concat) { std::stringstream input; toCallInputsSql(concat.inputs(), input); return fmt::format( - "cast(row({}) as {})", input.str(), toTypeSql(concat.type())); + "cast(row({}) as {})", + input.str(), + facebook::velox::toPrestoTypeSql(concat.type())); } template @@ -381,7 +354,7 @@ std::string getConstantValue(const core::ConstantTypedExpr& expr) { std::string toConstantSql(const core::ConstantTypedExpr& constant) { const auto& type = constant.type(); - const auto typeSql = toTypeSql(type); + const auto typeSql = facebook::velox::toPrestoTypeSql(type); std::stringstream sql; if (constant.isNull()) { diff --git a/velox/exec/fuzzer/PrestoSql.h b/velox/exec/fuzzer/PrestoSql.h index 2acfaaa2df96..7fce82729c8b 100644 --- a/velox/exec/fuzzer/PrestoSql.h +++ b/velox/exec/fuzzer/PrestoSql.h @@ -23,9 +23,6 @@ namespace facebook::velox::exec::test { /// than 0. void appendComma(int32_t i, std::stringstream& sql); -/// Return the SQL string of type. -std::string toTypeSql(const TypePtr& type); - /// Converts input expressions into SQL string and appends to a given /// stringstream. void toCallInputsSql( diff --git a/velox/exec/fuzzer/tests/PrestoSqlTest.cpp b/velox/exec/fuzzer/tests/PrestoSqlTest.cpp index 1461d5f16cdd..76ec1f4288a7 100644 --- a/velox/exec/fuzzer/tests/PrestoSqlTest.cpp +++ b/velox/exec/fuzzer/tests/PrestoSqlTest.cpp @@ -18,51 +18,10 @@ #include "velox/common/base/tests/GTestUtils.h" #include "velox/exec/fuzzer/PrestoSql.h" -#include "velox/functions/prestosql/types/JsonType.h" -#include "velox/functions/prestosql/types/KHyperLogLogType.h" -#include "velox/functions/prestosql/types/QDigestType.h" -#include "velox/functions/prestosql/types/SetDigestType.h" -#include "velox/functions/prestosql/types/TDigestType.h" -#include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h" namespace facebook::velox::exec::test { namespace { -TEST(PrestoSqlTest, toTypeSql) { - EXPECT_EQ(toTypeSql(BOOLEAN()), "BOOLEAN"); - EXPECT_EQ(toTypeSql(TINYINT()), "TINYINT"); - EXPECT_EQ(toTypeSql(SMALLINT()), "SMALLINT"); - EXPECT_EQ(toTypeSql(INTEGER()), "INTEGER"); - EXPECT_EQ(toTypeSql(BIGINT()), "BIGINT"); - EXPECT_EQ(toTypeSql(REAL()), "REAL"); - EXPECT_EQ(toTypeSql(DOUBLE()), "DOUBLE"); - EXPECT_EQ(toTypeSql(VARCHAR()), "VARCHAR"); - EXPECT_EQ(toTypeSql(VARBINARY()), "VARBINARY"); - EXPECT_EQ(toTypeSql(TDIGEST(DOUBLE())), "TDIGEST(DOUBLE)"); - EXPECT_EQ(toTypeSql(TIMESTAMP()), "TIMESTAMP"); - EXPECT_EQ(toTypeSql(QDIGEST(DOUBLE())), "QDIGEST(DOUBLE)"); - EXPECT_EQ(toTypeSql(QDIGEST(BIGINT())), "QDIGEST(BIGINT)"); - EXPECT_EQ(toTypeSql(QDIGEST(REAL())), "QDIGEST(REAL)"); - EXPECT_EQ(toTypeSql(SETDIGEST()), "SETDIGEST"); - EXPECT_EQ(toTypeSql(KHYPERLOGLOG()), "KHYPERLOGLOG"); - EXPECT_EQ(toTypeSql(DATE()), "DATE"); - EXPECT_EQ(toTypeSql(TIMESTAMP_WITH_TIME_ZONE()), "TIMESTAMP WITH TIME ZONE"); - EXPECT_EQ(toTypeSql(ARRAY(BOOLEAN())), "ARRAY(BOOLEAN)"); - EXPECT_EQ(toTypeSql(MAP(BOOLEAN(), INTEGER())), "MAP(BOOLEAN, INTEGER)"); - EXPECT_EQ( - toTypeSql(ROW({{"a", BOOLEAN()}, {"b", INTEGER()}})), - "ROW(a BOOLEAN, b INTEGER)"); - EXPECT_EQ( - toTypeSql( - ROW({{"a_", BOOLEAN()}, {"b$", INTEGER()}, {"c d", INTEGER()}})), - "ROW(a_ BOOLEAN, b$ INTEGER, c d INTEGER)"); - EXPECT_EQ(toTypeSql(JSON()), "JSON"); - EXPECT_EQ(toTypeSql(UNKNOWN()), "UNKNOWN"); - VELOX_ASSERT_THROW( - toTypeSql(FUNCTION({INTEGER()}, INTEGER())), - "Type is not supported: FUNCTION"); -} - void toUnaryOperator( const std::string& operatorName, const std::string& expectedSql) { diff --git a/velox/functions/prestosql/types/CMakeLists.txt b/velox/functions/prestosql/types/CMakeLists.txt index 368652bf101e..21de9b0ab204 100644 --- a/velox/functions/prestosql/types/CMakeLists.txt +++ b/velox/functions/prestosql/types/CMakeLists.txt @@ -13,10 +13,12 @@ # limitations under the License. add_subdirectory(parser) + velox_add_library( velox_presto_types BigintEnumRegistration.cpp BigintEnumType.cpp + PrestoTypeSql.cpp BingTileRegistration.cpp BingTileType.cpp EnumTypeBase.cpp diff --git a/velox/functions/prestosql/types/PrestoTypeSql.cpp b/velox/functions/prestosql/types/PrestoTypeSql.cpp new file mode 100644 index 000000000000..5689a97f3783 --- /dev/null +++ b/velox/functions/prestosql/types/PrestoTypeSql.cpp @@ -0,0 +1,124 @@ +/* + * 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/PrestoTypeSql.h" + +#include +#include +#include +#include + +namespace facebook::velox { + +namespace { +bool isPlainArray(const Type& type) { + return type.isArray() && typeid(type) == typeid(ArrayType); +} + +bool isPlainMap(const Type& type) { + return type.isMap() && typeid(type) == typeid(MapType); +} + +bool isPlainRow(const Type& type) { + return type.isRow() && typeid(type) == typeid(RowType); +} + +// Returns true if a ROW field name needs quoting in Presto SQL. +// Field names that are not simple identifiers (letters, digits, underscores +// starting with a letter or underscore) must be quoted. +bool needsQuoting(const std::string& name) { + if (name.empty()) { + return false; + } + if (name[0] != '_' && !std::isalpha(name[0])) { + return true; + } + for (auto c : name) { + if (c != '_' && !std::isalnum(c)) { + return true; + } + } + return false; +} + +} // namespace + +std::string toPrestoTypeSql(const TypePtr& type) { + if (isPlainArray(*type)) { + return fmt::format("ARRAY({})", toPrestoTypeSql(type->childAt(0))); + } + + if (isPlainMap(*type)) { + return fmt::format( + "MAP({}, {})", + toPrestoTypeSql(type->childAt(0)), + toPrestoTypeSql(type->childAt(1))); + } + + if (isPlainRow(*type)) { + const auto& rowType = type->asRow(); + std::stringstream sql; + sql << "ROW("; + for (auto i = 0; i < type->size(); ++i) { + if (i > 0) { + sql << ", "; + } + const auto& name = rowType.nameOf(i); + if (!name.empty()) { + if (needsQuoting(name)) { + sql << std::quoted(name, '"', '"') << " "; + } else { + sql << name << " "; + } + } + sql << toPrestoTypeSql(type->childAt(i)); + } + sql << ")"; + return sql.str(); + } + + // Primitive types and custom types (e.g. IPPREFIX, BINGTILE). + // For parameterized types (e.g. TDIGEST(DOUBLE), DECIMAL(10, 2)), + // append parameters. + const auto& params = type->parameters(); + if (params.empty()) { + return type->name(); + } + + std::stringstream sql; + sql << type->name() << "("; + for (auto i = 0; i < params.size(); ++i) { + if (i > 0) { + sql << ", "; + } + switch (params[i].kind) { + case TypeParameterKind::kType: + sql << toPrestoTypeSql(params[i].type); + break; + case TypeParameterKind::kLongLiteral: + sql << params[i].longLiteral.value(); + break; + default: + VELOX_UNSUPPORTED( + "Unsupported type parameter kind: {}", + TypeParameterKindName::toName(params[i].kind)); + } + } + sql << ")"; + return sql.str(); +} + +} // namespace facebook::velox diff --git a/velox/functions/prestosql/types/PrestoTypeSql.h b/velox/functions/prestosql/types/PrestoTypeSql.h new file mode 100644 index 000000000000..3a82e8e94e4f --- /dev/null +++ b/velox/functions/prestosql/types/PrestoTypeSql.h @@ -0,0 +1,25 @@ +/* + * 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/Type.h" + +namespace facebook::velox { + +/// Returns the Presto SQL string representation of the given type. +std::string toPrestoTypeSql(const TypePtr& type); + +} // namespace facebook::velox diff --git a/velox/functions/prestosql/types/tests/CMakeLists.txt b/velox/functions/prestosql/types/tests/CMakeLists.txt index 7098b86e8b66..975b0fa33da6 100644 --- a/velox/functions/prestosql/types/tests/CMakeLists.txt +++ b/velox/functions/prestosql/types/tests/CMakeLists.txt @@ -27,6 +27,7 @@ add_executable( UuidTypeTest.cpp IPAddressTypeTest.cpp IPPrefixTypeTest.cpp + PrestoTypeSqlTest.cpp ) if(VELOX_ENABLE_GEO) diff --git a/velox/functions/prestosql/types/tests/PrestoTypeSqlTest.cpp b/velox/functions/prestosql/types/tests/PrestoTypeSqlTest.cpp new file mode 100644 index 000000000000..d1b7d907ae1a --- /dev/null +++ b/velox/functions/prestosql/types/tests/PrestoTypeSqlTest.cpp @@ -0,0 +1,107 @@ +/* + * 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 + +#include "velox/common/base/tests/GTestUtils.h" +#include "velox/functions/prestosql/types/BingTileType.h" +#include "velox/functions/prestosql/types/HyperLogLogType.h" +#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/KHyperLogLogType.h" +#include "velox/functions/prestosql/types/P4HyperLogLogType.h" +#include "velox/functions/prestosql/types/PrestoTypeSql.h" +#include "velox/functions/prestosql/types/QDigestType.h" +#include "velox/functions/prestosql/types/SetDigestType.h" +#include "velox/functions/prestosql/types/SfmSketchType.h" +#include "velox/functions/prestosql/types/TDigestType.h" +#include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h" +#include "velox/functions/prestosql/types/UuidType.h" + +namespace facebook::velox { +namespace { + +TEST(PrestoTypeSqlTest, primitive) { + EXPECT_EQ(toPrestoTypeSql(BOOLEAN()), "BOOLEAN"); + EXPECT_EQ(toPrestoTypeSql(TINYINT()), "TINYINT"); + EXPECT_EQ(toPrestoTypeSql(SMALLINT()), "SMALLINT"); + EXPECT_EQ(toPrestoTypeSql(INTEGER()), "INTEGER"); + EXPECT_EQ(toPrestoTypeSql(BIGINT()), "BIGINT"); + EXPECT_EQ(toPrestoTypeSql(REAL()), "REAL"); + EXPECT_EQ(toPrestoTypeSql(DOUBLE()), "DOUBLE"); + EXPECT_EQ(toPrestoTypeSql(VARCHAR()), "VARCHAR"); + EXPECT_EQ(toPrestoTypeSql(VARBINARY()), "VARBINARY"); + EXPECT_EQ(toPrestoTypeSql(TIMESTAMP()), "TIMESTAMP"); + EXPECT_EQ(toPrestoTypeSql(DATE()), "DATE"); + EXPECT_EQ(toPrestoTypeSql(UNKNOWN()), "UNKNOWN"); +} + +TEST(PrestoTypeSqlTest, custom) { + EXPECT_EQ( + toPrestoTypeSql(TIMESTAMP_WITH_TIME_ZONE()), "TIMESTAMP WITH TIME ZONE"); + EXPECT_EQ(toPrestoTypeSql(JSON()), "JSON"); + EXPECT_EQ(toPrestoTypeSql(HYPERLOGLOG()), "HYPERLOGLOG"); + EXPECT_EQ(toPrestoTypeSql(KHYPERLOGLOG()), "KHYPERLOGLOG"); + EXPECT_EQ(toPrestoTypeSql(P4HYPERLOGLOG()), "P4HYPERLOGLOG"); + EXPECT_EQ(toPrestoTypeSql(TDIGEST(DOUBLE())), "TDIGEST(DOUBLE)"); + EXPECT_EQ(toPrestoTypeSql(QDIGEST(DOUBLE())), "QDIGEST(DOUBLE)"); + EXPECT_EQ(toPrestoTypeSql(QDIGEST(BIGINT())), "QDIGEST(BIGINT)"); + EXPECT_EQ(toPrestoTypeSql(SETDIGEST()), "SETDIGEST"); + EXPECT_EQ(toPrestoTypeSql(SFMSKETCH()), "SFMSKETCH"); + EXPECT_EQ(toPrestoTypeSql(IPADDRESS()), "IPADDRESS"); + EXPECT_EQ(toPrestoTypeSql(IPPREFIX()), "IPPREFIX"); + EXPECT_EQ(toPrestoTypeSql(UUID()), "UUID"); + EXPECT_EQ(toPrestoTypeSql(BINGTILE()), "BINGTILE"); +} + +TEST(PrestoTypeSqlTest, complex) { + EXPECT_EQ(toPrestoTypeSql(ARRAY(BOOLEAN())), "ARRAY(BOOLEAN)"); + EXPECT_EQ(toPrestoTypeSql(ARRAY(ARRAY(INTEGER()))), "ARRAY(ARRAY(INTEGER))"); + EXPECT_EQ( + toPrestoTypeSql(MAP(BOOLEAN(), INTEGER())), "MAP(BOOLEAN, INTEGER)"); + EXPECT_EQ( + toPrestoTypeSql(MAP(VARCHAR(), ARRAY(BIGINT()))), + "MAP(VARCHAR, ARRAY(BIGINT))"); +} + +TEST(PrestoTypeSqlTest, row) { + EXPECT_EQ( + toPrestoTypeSql(ROW({{"a", BOOLEAN()}, {"b", INTEGER()}})), + "ROW(a BOOLEAN, b INTEGER)"); + EXPECT_EQ( + toPrestoTypeSql( + ROW({{"a_", BOOLEAN()}, {"b$", INTEGER()}, {"c d", INTEGER()}})), + "ROW(a_ BOOLEAN, \"b$\" INTEGER, \"c d\" INTEGER)"); + // Unnamed fields. + EXPECT_EQ( + toPrestoTypeSql(ROW({INTEGER(), BOOLEAN()})), "ROW(INTEGER, BOOLEAN)"); + // Field names that need quoting. + EXPECT_EQ( + toPrestoTypeSql(ROW( + {{"a with spaces", INTEGER()}, {"b with \"quotes\"", VARCHAR()}})), + "ROW(\"a with spaces\" INTEGER, \"b with \"\"quotes\"\"\" VARCHAR)"); + EXPECT_EQ(toPrestoTypeSql(ROW({{"123", INTEGER()}})), "ROW(\"123\" INTEGER)"); +} + +TEST(PrestoTypeSqlTest, decimal) { + EXPECT_EQ(toPrestoTypeSql(DECIMAL(10, 2)), "DECIMAL(10, 2)"); + EXPECT_EQ(toPrestoTypeSql(DECIMAL(38, 0)), "DECIMAL(38, 0)"); + EXPECT_EQ(toPrestoTypeSql(DECIMAL(3, 3)), "DECIMAL(3, 3)"); +} + +} // namespace +} // namespace facebook::velox diff --git a/velox/type/Type.cpp b/velox/type/Type.cpp index 107510c97b87..a3ccd9b10edc 100644 --- a/velox/type/Type.cpp +++ b/velox/type/Type.cpp @@ -1522,6 +1522,22 @@ const auto& timePrecisionNames() { VELOX_DEFINE_ENUM_NAME(TimePrecision, timePrecisionNames); +namespace { + +const auto& typeParameterKindNames() { + static const folly::F14FastMap kNames = { + {TypeParameterKind::kType, "kType"}, + {TypeParameterKind::kLongLiteral, "kLongLiteral"}, + {TypeParameterKind::kLongEnumLiteral, "kLongEnumLiteral"}, + {TypeParameterKind::kVarcharEnumLiteral, "kVarcharEnumLiteral"}, + }; + return kNames; +} + +} // namespace + +VELOX_DEFINE_ENUM_NAME(TypeParameterKind, typeParameterKindNames); + template folly::dynamic TimeType::serialize() const { folly::dynamic obj = folly::dynamic::object; diff --git a/velox/type/Type.h b/velox/type/Type.h index 909f7c3d88ad..c2bb634e5583 100644 --- a/velox/type/Type.h +++ b/velox/type/Type.h @@ -446,6 +446,8 @@ enum class TypeParameterKind { kVarcharEnumLiteral, }; +VELOX_DECLARE_ENUM_NAME(TypeParameterKind); + struct TypeParameter { const TypeParameterKind kind;