Skip to content

Commit 4bd07a7

Browse files
pedroerpmeta-codesync[bot]
authored andcommitted
fix(variant): Variant string conversion logic on creation (#15855)
Summary: Pull Request resolved: #15855 Fixing two issues with variant creation: - Variant::create() was relying on implicit conversion from StringView into std::string. It also did not support construction with std::string_view. Adding overloads to make them explicit. - Variant::typeWithCustomComparison() was also relying on implicit conversion. Making the conversion explicit. Reviewed By: mbasmanova Differential Revision: D89753870 fbshipit-source-id: 932417f82b115bfcb6314f46d00315ec75f30322
1 parent 3d614a1 commit 4bd07a7

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

velox/type/Variant.h

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ struct VariantTypeTraits<
138138
KIND,
139139
usesCustomComparison,
140140
std::enable_if_t<
141-
TypeTraits<KIND>::isPrimitiveType && KIND != TypeKind::VARCHAR &&
142-
KIND != TypeKind::VARBINARY,
141+
TypeTraits<KIND>::isPrimitiveType && !is_string_kind(KIND),
143142
void>> {
144143
using native_type = typename TypeTraits<KIND>::NativeType;
145144
using stored_type =
@@ -151,9 +150,7 @@ template <TypeKind KIND, bool usesCustomComparison>
151150
struct VariantTypeTraits<
152151
KIND,
153152
usesCustomComparison,
154-
std::enable_if_t<
155-
KIND == TypeKind::VARCHAR || KIND == TypeKind::VARBINARY,
156-
void>> {
153+
std::enable_if_t<is_string_kind(KIND), void>> {
157154
using native_type = std::string_view;
158155
using stored_type =
159156
TypeStorage<scalar_stored_type<KIND>, KIND, usesCustomComparison>;
@@ -338,7 +335,25 @@ class Variant {
338335
return Variant{
339336
KIND,
340337
new typename detail::VariantTypeTraits<KIND, false>::stored_type{
341-
std::move(v)}};
338+
std::move(v)},
339+
};
340+
}
341+
342+
// Explicit specializations for other non-deep copied string types.
343+
template <TypeKind KIND>
344+
static std::enable_if_t<is_string_kind(KIND), Variant> create(StringView v) {
345+
return create<KIND>(std::string(v));
346+
}
347+
348+
template <TypeKind KIND>
349+
static std::enable_if_t<is_string_kind(KIND), Variant> create(
350+
std::string_view v) {
351+
return create<KIND>(std::string(v));
352+
}
353+
354+
template <TypeKind KIND>
355+
static std::enable_if_t<is_string_kind(KIND), Variant> create(const char* v) {
356+
return create<KIND>(std::string(v));
342357
}
343358

344359
/// Creates a non-null Variant by deducing the TypeKind from the C++ template
@@ -489,10 +504,11 @@ class Variant {
489504
static Variant typeWithCustomComparison(
490505
typename TypeTraits<KIND>::NativeType input,
491506
const TypePtr& type) {
507+
using variant_traits = detail::VariantTypeTraits<KIND, true>;
492508
return {
493509
KIND,
494-
new typename detail::VariantTypeTraits<KIND, true>::stored_type{
495-
input,
510+
new typename variant_traits::stored_type{
511+
typename variant_traits::value_type{std::move(input)},
496512
std::dynamic_pointer_cast<
497513
const CanProvideCustomComparisonType<KIND>>(type)},
498514
true};

velox/type/tests/VariantTest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,15 @@ TEST(VariantCreateTest, varcharType) {
113113
auto unicodeVariant = Variant::create<TypeKind::VARCHAR>(unicodeStr);
114114
EXPECT_EQ(unicodeVariant.value<TypeKind::VARCHAR>(), unicodeStr);
115115

116+
// Other string types.
117+
auto stdStringViewVariant =
118+
Variant::create<TypeKind::VARCHAR>(std::string_view(longStr));
119+
EXPECT_EQ(stdStringViewVariant.value<TypeKind::VARCHAR>(), longStr);
120+
121+
auto stringViewVariant =
122+
Variant::create<TypeKind::VARCHAR>(StringView(longStr));
123+
EXPECT_EQ(stringViewVariant.value<TypeKind::VARCHAR>(), longStr);
124+
116125
// Test move semantics
117126
std::string moveStr = "Move me!";
118127
auto moveVariant = Variant::create<TypeKind::VARCHAR>(std::move(moveStr));
@@ -136,6 +145,15 @@ TEST(VariantCreateTest, varbinaryType) {
136145
auto largeVariant = Variant::create<TypeKind::VARBINARY>(largeBinary);
137146
EXPECT_EQ(largeVariant.value<TypeKind::VARBINARY>(), largeBinary);
138147

148+
// Other string types.
149+
auto stdStringViewVariant =
150+
Variant::create<TypeKind::VARBINARY>(std::string_view(simpleBinary));
151+
EXPECT_EQ(stdStringViewVariant.value<TypeKind::VARBINARY>(), simpleBinary);
152+
153+
auto stringViewVariant =
154+
Variant::create<TypeKind::VARBINARY>(StringView(simpleBinary));
155+
EXPECT_EQ(stringViewVariant.value<TypeKind::VARBINARY>(), simpleBinary);
156+
139157
// Test move semantics.
140158
std::string moveBinary = "Move binary!";
141159
auto moveVariant =

0 commit comments

Comments
 (0)