Skip to content

Commit 50aed29

Browse files
authored
YDB FQ: pushdown Decimal type (#26593)
1 parent 21a2666 commit 50aed29

File tree

5 files changed

+113
-2
lines changed

5 files changed

+113
-2
lines changed

ydb/library/yql/providers/common/pushdown/collection.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "collection.h"
22

33
#include <yql/essentials/core/yql_expr_type_annotation.h>
4-
#include <yql/essentials/utils/log/log.h>
54

65
#include <vector>
76

@@ -211,6 +210,9 @@ class TPredicateMarkup {
211210
if (Settings.IsEnabled(EFlag::StringTypes) && (node.Maybe<TCoUtf8>() || node.Maybe<TCoString>())) {
212211
return true;
213212
}
213+
if (Settings.IsEnabled(EFlag::DecimalCtor) && node.Maybe<TCoDecimal>()) {
214+
return true;
215+
}
214216
return false;
215217
}
216218

ydb/library/yql/providers/common/pushdown/settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct TSettings {
4545
IntervalCtor = 1 << 26,
4646
MinMax = 1 << 27,
4747
NonDeterministic = 1 << 28,
48+
DecimalCtor = 1 << 29,
4849
};
4950

5051
explicit TSettings(NLog::EComponent logComponent)

ydb/library/yql/providers/generic/provider/ut/pushdown/pushdown_ut.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,24 @@ struct TFakeGenericClient: public NConnector::IClient {
143143
PRIMITIVE_TYPE_COL("json_document", JSON_DOCUMENT);
144144
PRIMITIVE_TYPE_COL("dynumber", DYNUMBER);
145145

146+
// Add decimal columns
147+
{
148+
auto* col = schema.add_columns();
149+
col->set_name("col_decimal_precision10_scale0");
150+
auto* t = col->mutable_type();
151+
auto* decimalType = t->mutable_decimal_type();
152+
decimalType->set_precision(10);
153+
decimalType->set_scale(0);
154+
}
155+
{
156+
auto* col = schema.add_columns();
157+
col->set_name("col_decimal_precision4_scale2");
158+
auto* t = col->mutable_type();
159+
auto* decimalType = t->mutable_decimal_type();
160+
decimalType->set_precision(4);
161+
decimalType->set_scale(2);
162+
}
163+
146164
return NThreading::MakeFuture<NConnector::TDescribeTableAsyncResult::value_type>(std::move(result));
147165
}
148166

@@ -765,4 +783,69 @@ Y_UNIT_TEST_SUITE_F(PushdownTest, TPushdownFixture) {
765783
)proto"
766784
);
767785
}
786+
787+
Y_UNIT_TEST(DecimalPushdownPrecision10Scale0) {
788+
AssertFilter(
789+
R"ast(
790+
(==
791+
(Member $row '"col_decimal_precision10_scale0")
792+
(Decimal '"1" '"10" '"0")
793+
)
794+
)ast",
795+
R"proto(
796+
comparison {
797+
operation: EQ
798+
left_value {
799+
column: "col_decimal_precision10_scale0"
800+
}
801+
right_value {
802+
typed_value {
803+
type {
804+
decimal_type {
805+
precision: 10
806+
scale: 0
807+
}
808+
}
809+
value {
810+
bytes_value: "\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
811+
}
812+
}
813+
}
814+
}
815+
)proto"
816+
);
817+
}
818+
819+
Y_UNIT_TEST(DecimalPushdownPrecesion4Scale2) {
820+
// Test with negative decimal value with fractional part
821+
AssertFilter(
822+
R"ast(
823+
(==
824+
(Member $row '"col_decimal_precision4_scale2")
825+
(Decimal '"-22.22" '"4" '"2")
826+
)
827+
)ast",
828+
R"proto(
829+
comparison {
830+
operation: EQ
831+
left_value {
832+
column: "col_decimal_precision4_scale2"
833+
}
834+
right_value {
835+
typed_value {
836+
type {
837+
decimal_type {
838+
precision: 4
839+
scale: 2
840+
}
841+
}
842+
value {
843+
bytes_value: "R\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
844+
}
845+
}
846+
}
847+
}
848+
)proto"
849+
);
850+
}
768851
}

ydb/library/yql/providers/generic/provider/yql_generic_physical_opt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ namespace NYql {
3737
EFlag::LikeOperator |
3838
EFlag::JustPassthroughOperators | // To pushdown REGEXP over String column
3939
EFlag::FlatMapOverOptionals | // To pushdown REGEXP over Utf8 column
40-
EFlag::ToStringFromStringExpressions // To pushdown REGEXP over Utf8 column
40+
EFlag::ToStringFromStringExpressions | // To pushdown REGEXP over Utf8 column
41+
EFlag::DecimalType | EFlag::DecimalCtor
4142
);
4243
EnableFunction("Re2.Grep"); // For REGEXP pushdown
4344
}

ydb/library/yql/providers/generic/provider/yql_generic_predicate_pushdown.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,27 @@ namespace NYql {
227227
return SerializeExpression(lambda.Body(), dstProto->mutable_then_expression(), ctx, depth + 1);
228228
}
229229

230+
bool SerializeDecimal(const TCoDecimal& coDecimal, TExpression* proto, TSerializationContext& /*ctx*/, ui64 /*depth*/) {
231+
auto* protoTypedValue = proto->mutable_typed_value();
232+
auto* protoDecimalType = protoTypedValue->mutable_type()->mutable_decimal_type();
233+
234+
// extract precision and scale
235+
auto precision = FromString<ui32>(coDecimal.Precision().StringValue());
236+
auto scale = FromString<ui32>(coDecimal.Scale().StringValue());
237+
protoDecimalType->set_precision(precision);
238+
protoDecimalType->set_scale(scale);
239+
240+
// extract decimal value itself
241+
auto decimal = NDecimal::FromString(coDecimal.Cast<TCoDecimal>().Literal().Value(), precision, scale);
242+
static_assert(sizeof(decimal) == 16, "wrong TInt128 size");
243+
244+
// Set the bytes value with the 16 buffer containing the decimal value bytes
245+
protoTypedValue->mutable_value()->set_bytes_value(reinterpret_cast<char*>(&decimal), sizeof(decimal));
246+
247+
return true;
248+
}
249+
250+
230251
#define MATCH_ATOM(AtomType, ATOM_ENUM, proto_name, cpp_type) \
231252
if (auto atom = expression.Maybe<Y_CAT(TCo, AtomType)>()) { \
232253
auto* value = proto->mutable_typed_value(); \
@@ -300,6 +321,9 @@ namespace NYql {
300321
if (auto dependsOn = expression.Maybe<TCoDependsOn>()) {
301322
return SerializeExpression(dependsOn.Cast().Input(), proto, ctx, depth + 1);
302323
}
324+
if (auto decimal = expression.Maybe<TCoDecimal>()) {
325+
return SerializeDecimal(decimal.Cast(), proto, ctx, depth);
326+
}
303327

304328
// data
305329
MATCH_ATOM(Bool, BOOL, bool, bool);

0 commit comments

Comments
 (0)