Skip to content

Commit 4ff3894

Browse files
committed
pretty extract for optionals
1 parent 3ec5e4c commit 4ff3894

File tree

1 file changed

+33
-40
lines changed

1 file changed

+33
-40
lines changed

ydb/core/kqp/common/result_set_format/ut/kqp_formats_ut_helpers.cpp

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -180,54 +180,47 @@ NUdf::TUnboxedValue ExtractUnboxedValue(const std::shared_ptr<arrow::Array>& arr
180180
NUdf::TUnboxedValue ExtractUnboxedValue(const std::shared_ptr<arrow::Array>& array, ui64 row,
181181
const NMiniKQL::TOptionalType* optionalType, const NMiniKQL::THolderFactory& holderFactory)
182182
{
183-
auto innerOptionalType = SkipTaggedType(optionalType->GetItemType());
184-
if (NeedWrapByExternalOptional(innerOptionalType)) {
185-
YQL_ENSURE(array->type_id() == arrow::Type::STRUCT, "Unexpected array type");
186-
187-
auto innerArray = array;
188-
auto innerType = static_cast<const NMiniKQL::TType*>(optionalType);
189-
int depth = 0;
190-
191-
while (innerArray->type_id() == arrow::Type::STRUCT) {
192-
auto structArray = static_pointer_cast<arrow::StructArray>(innerArray);
193-
YQL_ENSURE(structArray->num_fields() == 1, "Unexpected count of fields");
194-
195-
if (structArray->IsNull(row)) {
196-
NUdf::TUnboxedValue value;
197-
for (int i = 0; i < depth; ++i) {
198-
value = value.MakeOptional();
199-
}
200-
return value;
201-
}
183+
auto innerType = SkipTaggedType(optionalType->GetItemType());
184+
ui32 depth = 1;
202185

203-
innerType = SkipTaggedType(static_cast<const NMiniKQL::TOptionalType*>(innerType)->GetItemType());
204-
innerArray = structArray->field(0);
205-
++depth;
206-
}
186+
while (innerType->IsOptional()) {
187+
innerType = SkipTaggedType(static_cast<const NMiniKQL::TOptionalType*>(innerType)->GetItemType());
188+
++depth;
189+
}
207190

208-
if (innerType->IsOptional()) { // depth + 1 == count of structs for types with validity bitmaps
209-
innerType = SkipTaggedType(static_cast<const NMiniKQL::TOptionalType*>(innerType)->GetItemType());
210-
++depth;
211-
}
191+
// For types without native validity bitmap (e.g., Variant, Null) we need to wrap them in an additional struct layer
192+
// Furthermore, other singular types (e.g., Void, EmptyList, EmptyDict) also need to wrap (from YQL-15332)
193+
// Thus, the depth == 2 for Optional<Variant<T, F, ...>> type
194+
if (NeedWrapByExternalOptional(innerType)) {
195+
++depth;
196+
}
212197

213-
auto wrap = NeedWrapByExternalOptional(innerType);
214-
auto isNull = innerArray->IsNull(row);
198+
auto innerArray = array;
199+
NUdf::TUnboxedValue value;
215200

216-
NUdf::TUnboxedValue value;
217-
if (wrap || !isNull) {
218-
value = NFormats::ExtractUnboxedValue(innerArray, row, innerType, holderFactory);
219-
}
201+
for (ui32 i = 1; i < depth; ++i) {
202+
YQL_ENSURE(innerArray->type_id() == arrow::Type::STRUCT, "Unexpected array type");
203+
auto structArray = static_pointer_cast<arrow::StructArray>(innerArray);
204+
YQL_ENSURE(structArray->num_fields() == 1, "Unexpected count of fields");
220205

221-
if (wrap || isNull) {
222-
--depth;
206+
if (structArray->IsNull(row)) {
207+
for (ui32 j = 1; j < i; ++j) {
208+
value = value.MakeOptional();
209+
}
210+
return value;
223211
}
224212

225-
for (int i = 0; i < depth; ++i) {
226-
value = value.MakeOptional();
227-
}
228-
return value;
213+
innerArray = structArray->field(0);
214+
}
215+
216+
if (!innerArray->IsNull(row)) {
217+
value = NFormats::ExtractUnboxedValue(innerArray, row, innerType, holderFactory);
229218
}
230-
return NFormats::ExtractUnboxedValue(array, row, innerOptionalType, holderFactory).Release().MakeOptional();
219+
220+
for (ui32 i = 1; i < depth; ++i) {
221+
value = value.MakeOptional();
222+
}
223+
return value;
231224
}
232225

233226
NUdf::TUnboxedValue ExtractUnboxedValue(const std::shared_ptr<arrow::Array>& array, ui64 row,

0 commit comments

Comments
 (0)