Skip to content

Commit 2a7fe82

Browse files
Improvements to filter pushdown into columns shards (#18807)
2 parents 4eedc60 + 169396f commit 2a7fe82

File tree

17 files changed

+399
-55
lines changed

17 files changed

+399
-55
lines changed

.github/config/muted_ya.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ydb/core/kqp/ut/cost KqpCost.OlapWriteRow
2121
ydb/core/kqp/ut/olap KqpDecimalColumnShard.TestAggregation
2222
ydb/core/kqp/ut/olap KqpDecimalColumnShard.TestFilterCompare
2323
ydb/core/kqp/ut/olap KqpOlapJson.BloomIndexesVariants
24+
ydb/core/kqp/ut/olap KqpOlapDelete.DeleteWithDiffrentTypesPKColumns-isStream
2425
ydb/core/kqp/ut/olap KqpOlapSysView.StatsSysViewBytesColumnActualization
2526
ydb/core/kqp/ut/olap KqpOlapSysView.StatsSysViewBytesDictActualization
2627
ydb/core/kqp/ut/olap KqpOlapSysView.StatsSysViewBytesDictStatActualization

ydb/core/kqp/compile_service/kqp_compile_actor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ void ApplyServiceConfig(TKikimrConfiguration& kqpConfig, const TTableServiceConf
650650
kqpConfig.DefaultCostBasedOptimizationLevel = serviceConfig.GetDefaultCostBasedOptimizationLevel();
651651
kqpConfig.DefaultEnableShuffleElimination = serviceConfig.GetDefaultEnableShuffleElimination();
652652
kqpConfig.EnableConstantFolding = serviceConfig.GetEnableConstantFolding();
653+
kqpConfig.EnableFoldUdfs = serviceConfig.GetEnableFoldUdfs();
653654
kqpConfig.SetDefaultEnabledSpillingNodes(serviceConfig.GetEnableSpillingNodes());
654655
kqpConfig.EnableSnapshotIsolationRW = serviceConfig.GetEnableSnapshotIsolationRW();
655656
kqpConfig.EnableSpilling = serviceConfig.GetEnableQueryServiceSpilling();

ydb/core/kqp/compile_service/kqp_compile_service.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ class TKqpCompileService : public TActorBootstrapped<TKqpCompileService> {
309309

310310
ui64 defaultCostBasedOptimizationLevel = TableServiceConfig.GetDefaultCostBasedOptimizationLevel();
311311
bool enableConstantFolding = TableServiceConfig.GetEnableConstantFolding();
312+
bool enableFoldUdfs = TableServiceConfig.GetEnableFoldUdfs();
312313

313314
bool defaultEnableShuffleElimination = TableServiceConfig.GetDefaultEnableShuffleElimination();
314315

@@ -342,6 +343,7 @@ class TKqpCompileService : public TActorBootstrapped<TKqpCompileService> {
342343
TableServiceConfig.GetEnableSpillingNodes() != enableSpillingNodes ||
343344
TableServiceConfig.GetDefaultCostBasedOptimizationLevel() != defaultCostBasedOptimizationLevel ||
344345
TableServiceConfig.GetEnableConstantFolding() != enableConstantFolding ||
346+
TableServiceConfig.GetEnableFoldUdfs() != enableFoldUdfs ||
345347
TableServiceConfig.GetEnableAstCache() != enableAstCache ||
346348
TableServiceConfig.GetEnableImplicitQueryParameterTypes() != enableImplicitQueryParameterTypes ||
347349
TableServiceConfig.GetEnablePgConstsToParams() != enablePgConstsToParams ||

ydb/core/kqp/opt/kqp_constant_folding_transformer.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace {
1414
* Traverse a lambda and create a mapping from nodes to nodes wrapped in EvaluateExpr callable
1515
* We check for literals specifically, since they shouldn't be evaluated
1616
*/
17-
void ExtractConstantExprs(const TExprNode::TPtr& input, TNodeOnNodeOwnedMap& replaces, TExprContext& ctx) {
17+
void ExtractConstantExprs(const TExprNode::TPtr& input, TNodeOnNodeOwnedMap& replaces, TExprContext& ctx, bool foldUdfs = true) {
1818
if (TCoLambda::Match(input.Get())) {
1919
auto lambda = TExprBase(input).Cast<TCoLambda>();
2020
return ExtractConstantExprs(lambda.Body().Ptr(), replaces, ctx);
@@ -24,7 +24,7 @@ namespace {
2424
return;
2525
}
2626

27-
if (IsConstantExpr(input) && !input->IsCallable("PgConst")) {
27+
if (IsConstantExpr(input, foldUdfs) && !input->IsCallable("PgConst")) {
2828
TNodeOnNodeOwnedMap deepClones;
2929
auto inputClone = ctx.DeepCopy(*input, ctx, deepClones, false, true, true);
3030

@@ -64,6 +64,8 @@ IGraphTransformer::TStatus TKqpConstantFoldingTransformer::DoTransform(TExprNode
6464
return IGraphTransformer::TStatus::Ok;
6565
}
6666

67+
bool foldUdfs = Config->EnableFoldUdfs;
68+
6769
TNodeOnNodeOwnedMap replaces;
6870

6971
VisitExpr(input, [&](const TExprNode::TPtr& node) {
@@ -78,7 +80,7 @@ IGraphTransformer::TStatus TKqpConstantFoldingTransformer::DoTransform(TExprNode
7880
return true;
7981
}
8082

81-
ExtractConstantExprs(flatmap.Lambda().Body().Ptr(), replaces, ctx);
83+
ExtractConstantExprs(flatmap.Lambda().Body().Ptr(), replaces, ctx, foldUdfs);
8284

8385
return replaces.empty();
8486
}

ydb/core/kqp/opt/physical/kqp_opt_phy.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ class TKqpPhysicalOptTransformer : public TOptimizeTransformerBase {
126126
AddHandler(1, &TKqpWriteConstraint::Match, HNDL(BuildWriteConstraint<true>));
127127
AddHandler(1, &TKqpWriteConstraint::Match, HNDL(BuildWriteConstraint<true>));
128128
AddHandler(1, &TKqpReadOlapTableRanges::Match, HNDL(AddColumnForEmptyColumnsOlapRead));
129-
130-
129+
131130
AddHandler(2, &TDqStage::Match, HNDL(RewriteKqpReadTable));
132131
AddHandler(2, &TDqStage::Match, HNDL(RewriteKqpLookupTable));
133132
AddHandler(2, &TKqlUpsertRows::Match, HNDL(RewriteReturningUpsert));

ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,11 @@ TFilterOpsLevels PredicatePushdown(const TExprBase& predicate, const TExprNode&
700700
return YqlApplyPushdown(predicate, argument, ctx);
701701
}
702702

703-
std::pair<TVector<TOLAPPredicateNode>, TVector<TOLAPPredicateNode>> SplitForPartialPushdown(const TOLAPPredicateNode& predicateTree)
703+
std::pair<TVector<TOLAPPredicateNode>, TVector<TOLAPPredicateNode>> SplitForPartialPushdown(const TOLAPPredicateNode& predicateTree, bool allowApply)
704704
{
705-
if (predicateTree.CanBePushed) {
705+
bool canBePushed = (predicateTree.CanBePushed || predicateTree.CanBePushedApply && allowApply);
706+
707+
if (canBePushed) {
706708
return {{predicateTree}, {}};
707709
}
708710

@@ -717,7 +719,8 @@ std::pair<TVector<TOLAPPredicateNode>, TVector<TOLAPPredicateNode>> SplitForPart
717719
TVector<TOLAPPredicateNode> pushable;
718720
TVector<TOLAPPredicateNode> remaining;
719721
for (const auto& predicate : predicateTree.Children) {
720-
if (predicate.CanBePushed && !isFoundNotStrictOp) {
722+
canBePushed = (predicate.CanBePushed || predicate.CanBePushedApply && allowApply);
723+
if (canBePushed && !isFoundNotStrictOp) {
721724
pushable.emplace_back(predicate);
722725
} else {
723726
if (!IsStrict(predicate.ExprNode)) {
@@ -768,7 +771,7 @@ TExprBase KqpPushOlapFilter(TExprBase node, TExprContext& ctx, const TKqpOptimiz
768771
CollectPredicates(predicate, predicateTree, &lambdaArg, read.Process().Body(), false);
769772
YQL_ENSURE(predicateTree.IsValid(), "Collected OLAP predicates are invalid");
770773

771-
auto [pushable, remaining] = SplitForPartialPushdown(predicateTree);
774+
auto [pushable, remaining] = SplitForPartialPushdown(predicateTree, false);
772775
TVector<TFilterOpsLevels> pushedPredicates;
773776
for (const auto& p: pushable) {
774777
pushedPredicates.emplace_back(PredicatePushdown(TExprBase(p.ExprNode), lambdaArg, ctx, node.Pos()));
@@ -795,10 +798,19 @@ TExprBase KqpPushOlapFilter(TExprBase node, TExprContext& ctx, const TKqpOptimiz
795798
TOLAPPredicateNode predicateTree;
796799
predicateTree.ExprNode = predicate.Ptr();
797800
CollectPredicates(predicate, predicateTree, &lambdaArg, read.Process().Body(), true);
801+
798802
YQL_ENSURE(predicateTree.IsValid(), "Collected OLAP predicates are invalid");
799-
auto [pushableWithApply, remaining] = SplitForPartialPushdown(predicateTree);
800-
for (const auto& p: pushableWithApply) {
801-
pushedPredicates.emplace_back(PredicatePushdown(TExprBase(p.ExprNode), lambdaArg, ctx, node.Pos()));
803+
auto [pushable, remaining] = SplitForPartialPushdown(predicateTree, true);
804+
for (const auto& p: pushable) {
805+
if (p.CanBePushed) {
806+
auto pred = PredicatePushdown(TExprBase(p.ExprNode), lambdaArg, ctx, node.Pos());
807+
pushedPredicates.emplace_back(pred);
808+
}
809+
else {
810+
auto expr = YqlApplyPushdown(TExprBase(p.ExprNode), lambdaArg, ctx);
811+
TFilterOpsLevels pred(expr);
812+
pushedPredicates.emplace_back(pred);
813+
}
802814
}
803815
remainingAfterApply.insert(remainingAfterApply.end(), remaining.begin(), remaining.end());
804816
}

ydb/core/kqp/opt/physical/predicate_collector.cpp

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <ydb/core/formats/arrow/ssa_runtime_version.h>
44
#include <yql/essentials/core/yql_opt_utils.h>
55
#include <yql/essentials/core/yql_expr_optimize.h>
6+
#include <yql/essentials/utils/log/log.h>
67

78
namespace NKikimr::NKqp::NOpt {
89

@@ -28,24 +29,28 @@ bool IsSupportedDataType(const TCoDataCtor& node, bool allowOlapApply) {
2829
node.Maybe<TCoUint32>() ||
2930
node.Maybe<TCoUint64>() ||
3031
node.Maybe<TCoUtf8>() ||
31-
node.Maybe<TCoString>()) {
32-
return true;
33-
}
34-
35-
if (node.Maybe<TCoTimestamp>()) {
32+
node.Maybe<TCoString>()
33+
) {
3634
return true;
3735
}
3836

3937
if (allowOlapApply) {
40-
if (node.Maybe<TCoDate32>() || node.Maybe<TCoDatetime64>() || node.Maybe<TCoTimestamp64>() || node.Maybe<TCoInterval64>()) {
38+
if (node.Maybe<TCoDate>() ||
39+
node.Maybe<TCoDate32>() ||
40+
node.Maybe<TCoDatetime>() ||
41+
node.Maybe<TCoDatetime64>() ||
42+
node.Maybe<TCoTimestamp>() ||
43+
node.Maybe<TCoTimestamp64>() ||
44+
node.Maybe<TCoInterval>() ||
45+
node.Maybe<TCoInterval64>()) {
4146
return true;
4247
}
4348
}
4449

4550
return false;
4651
}
4752

48-
bool IsSupportedCast(const TCoSafeCast& cast) {
53+
bool IsSupportedCast(const TCoSafeCast& cast, bool allowOlapApply=false) {
4954
auto maybeDataType = cast.Type().Maybe<TCoDataType>();
5055
if (!maybeDataType) {
5156
if (const auto maybeOptionalType = cast.Type().Maybe<TCoOptionalType>()) {
@@ -54,6 +59,10 @@ bool IsSupportedCast(const TCoSafeCast& cast) {
5459
}
5560
YQL_ENSURE(maybeDataType.IsValid());
5661

62+
if (allowOlapApply) {
63+
return true;
64+
}
65+
5766
const auto dataType = maybeDataType.Cast();
5867
if (dataType.Type().Value() == "Int32") { // TODO: Support any numeric casts.
5968
return cast.Value().Maybe<TCoString>() || cast.Value().Maybe<TCoUtf8>();
@@ -87,21 +96,25 @@ bool IsMemberColumn(const TExprBase& node, const TExprNode* lambdaArg) {
8796
}
8897

8998
bool IsGoodTypeForArithmeticPushdown(const TTypeAnnotationNode& type, bool allowOlapApply) {
90-
const auto fatures = NUdf::GetDataTypeInfo(RemoveOptionality(type).Cast<TDataExprType>()->GetSlot()).Features;
91-
return NUdf::EDataTypeFeatures::NumericType & fatures
92-
|| (allowOlapApply && (NUdf::EDataTypeFeatures::BigDateType & fatures) && !(NUdf::EDataTypeFeatures::TzDateType & fatures));
99+
const auto features = NUdf::GetDataTypeInfo(RemoveOptionality(type).Cast<TDataExprType>()->GetSlot()).Features;
100+
return NUdf::EDataTypeFeatures::NumericType & features
101+
|| (allowOlapApply && ((NUdf::EDataTypeFeatures::BigDateType |
102+
NUdf::EDataTypeFeatures::DateType |
103+
NUdf::EDataTypeFeatures::TimeIntervalType) & features) && !(NUdf::EDataTypeFeatures::TzDateType & features));
93104
}
94105

95106
bool IsGoodTypeForComparsionPushdown(const TTypeAnnotationNode& type, bool allowOlapApply) {
96-
const auto fatures = NUdf::GetDataTypeInfo(RemoveOptionality(type).Cast<TDataExprType>()->GetSlot()).Features;
97-
return (NUdf::EDataTypeFeatures::CanCompare & fatures)
98-
&& (((NUdf::EDataTypeFeatures::NumericType | NUdf::EDataTypeFeatures::StringType) & fatures) ||
99-
(allowOlapApply && (NUdf::EDataTypeFeatures::BigDateType & fatures) && !(NUdf::EDataTypeFeatures::TzDateType & fatures)));
107+
const auto features = NUdf::GetDataTypeInfo(RemoveOptionality(type).Cast<TDataExprType>()->GetSlot()).Features;
108+
return (NUdf::EDataTypeFeatures::CanCompare & features)
109+
&& (((NUdf::EDataTypeFeatures::NumericType | NUdf::EDataTypeFeatures::StringType) & features) ||
110+
(allowOlapApply && ((NUdf::EDataTypeFeatures::BigDateType |
111+
NUdf::EDataTypeFeatures::DateType |
112+
NUdf::EDataTypeFeatures::TimeIntervalType) & features) && !(NUdf::EDataTypeFeatures::TzDateType & features)));
100113
}
101114

102115
[[maybe_unused]]
103116
bool AbstractTreeCanBePushed(const TExprBase& expr, const TExprNode* ) {
104-
if (!expr.Ref().IsCallable({"Apply", "NamedApply", "IfPresent", "Visit"})) {
117+
if (!expr.Ref().IsCallable({"Apply", "Coalesce", "NamedApply", "IfPresent", "Visit"})) {
105118
return false;
106119
}
107120

@@ -139,6 +152,14 @@ bool AbstractTreeCanBePushed(const TExprBase& expr, const TExprNode* ) {
139152
return true;
140153
}
141154

155+
bool IfPresentCanBePushed(const TCoIfPresent& ifPresent, const TExprNode* lambdaArg, bool allowOlapApply) {
156+
157+
Y_UNUSED(ifPresent);
158+
Y_UNUSED(lambdaArg);
159+
160+
return allowOlapApply;
161+
}
162+
142163
bool CheckExpressionNodeForPushdown(const TExprBase& node, const TExprNode* lambdaArg, bool allowOlapApply) {
143164
if (allowOlapApply) {
144165
if (node.Maybe<TCoJust>() || node.Maybe<TCoCoalesce>()) {
@@ -154,7 +175,7 @@ bool CheckExpressionNodeForPushdown(const TExprBase& node, const TExprNode* lamb
154175
}
155176

156177
if (const auto maybeSafeCast = node.Maybe<TCoSafeCast>()) {
157-
return IsSupportedCast(maybeSafeCast.Cast());
178+
return IsSupportedCast(maybeSafeCast.Cast(), allowOlapApply);
158179
} else if (const auto maybeData = node.Maybe<TCoDataCtor>()) {
159180
return IsSupportedDataType(maybeData.Cast(), allowOlapApply);
160181
} else if (const auto maybeMember = node.Maybe<TCoMember>()) {
@@ -174,6 +195,9 @@ bool CheckExpressionNodeForPushdown(const TExprBase& node, const TExprNode* lamb
174195
}
175196

176197
if (allowOlapApply) {
198+
if (const auto maybeIfPresent = node.Maybe<TCoIfPresent>()) {
199+
return IfPresentCanBePushed(maybeIfPresent.Cast(), lambdaArg, allowOlapApply);
200+
}
177201
return AbstractTreeCanBePushed(node, lambdaArg);
178202
}
179203

@@ -208,8 +232,9 @@ bool IsGoodTypesForPushdownCompare(const TTypeAnnotationNode& typeOne, const TTy
208232
}
209233
return true;
210234
}
211-
case ETypeAnnotationKind::Data:
235+
case ETypeAnnotationKind::Data: {
212236
return IsGoodTypeForComparsionPushdown(typeOne, allowOlapApply) && IsGoodTypeForComparsionPushdown(typeTwo, allowOlapApply);
237+
}
213238
default:
214239
break;
215240
}
@@ -327,6 +352,8 @@ bool CoalesceCanBePushed(const TCoCoalesce& coalesce, const TExprNode* lambdaArg
327352
return SafeCastCanBePushed(maybeFlatmap.Cast(), lambdaArg, allowOlapApply);
328353
} else if (const auto maybeJsonExists = predicate.Maybe<TCoJsonExists>()) {
329354
return JsonExistsCanBePushed(maybeJsonExists.Cast(), lambdaArg);
355+
} else if (const auto maybeIfPresent = predicate.Maybe<TCoIfPresent>()) {
356+
return IfPresentCanBePushed(maybeIfPresent.Cast(), lambdaArg, allowOlapApply);
330357
}
331358

332359
return false;
@@ -339,39 +366,49 @@ bool ExistsCanBePushed(const TCoExists& exists, const TExprNode* lambdaArg) {
339366
void CollectChildrenPredicates(const TExprNode& opNode, TOLAPPredicateNode& predicateTree, const TExprNode* lambdaArg, const TExprBase& lambdaBody, bool allowOlapApply) {
340367
predicateTree.Children.reserve(opNode.ChildrenSize());
341368
predicateTree.CanBePushed = true;
369+
predicateTree.CanBePushedApply = true;
370+
342371
for (const auto& childNodePtr: opNode.Children()) {
343372
TOLAPPredicateNode child;
344373
child.ExprNode = childNodePtr;
345-
if (const auto maybeCtor = TMaybeNode<TCoDataCtor>(child.ExprNode))
346-
child.CanBePushed = IsSupportedDataType(maybeCtor.Cast(), allowOlapApply);
374+
if (const auto maybeCtor = TMaybeNode<TCoDataCtor>(child.ExprNode)) {
375+
child.CanBePushed = IsSupportedDataType(maybeCtor.Cast(), false);
376+
child.CanBePushedApply = IsSupportedDataType(maybeCtor.Cast(), true);
377+
}
347378
else
348379
CollectPredicates(TExprBase(child.ExprNode), child, lambdaArg, lambdaBody, allowOlapApply);
349380
predicateTree.Children.emplace_back(child);
350381
predicateTree.CanBePushed &= child.CanBePushed;
382+
predicateTree.CanBePushedApply &= child.CanBePushedApply;
351383
}
352384
}
353385

354386
} // namespace
355387

356388
void CollectPredicates(const TExprBase& predicate, TOLAPPredicateNode& predicateTree, const TExprNode* lambdaArg, const TExprBase& lambdaBody, bool allowOlapApply) {
357389
if (predicate.Maybe<TCoNot>() || predicate.Maybe<TCoAnd>() || predicate.Maybe<TCoOr>() || predicate.Maybe<TCoXor>()) {
358-
return CollectChildrenPredicates(predicate.Ref(), predicateTree, lambdaArg, lambdaBody, allowOlapApply);
390+
CollectChildrenPredicates(predicate.Ref(), predicateTree, lambdaArg, lambdaBody, allowOlapApply);
359391
} else if (const auto maybeCoalesce = predicate.Maybe<TCoCoalesce>()) {
360-
predicateTree.CanBePushed = CoalesceCanBePushed(maybeCoalesce.Cast(), lambdaArg, lambdaBody, allowOlapApply);
392+
predicateTree.CanBePushed = CoalesceCanBePushed(maybeCoalesce.Cast(), lambdaArg, lambdaBody, false);
393+
predicateTree.CanBePushedApply = CoalesceCanBePushed(maybeCoalesce.Cast(), lambdaArg, lambdaBody, true);
361394
} else if (const auto maybeCompare = predicate.Maybe<TCoCompare>()) {
362-
predicateTree.CanBePushed = CompareCanBePushed(maybeCompare.Cast(), lambdaArg, lambdaBody, allowOlapApply);
395+
predicateTree.CanBePushed = CompareCanBePushed(maybeCompare.Cast(), lambdaArg, lambdaBody, false);
396+
predicateTree.CanBePushedApply = CompareCanBePushed(maybeCompare.Cast(), lambdaArg, lambdaBody, true);
363397
} else if (const auto maybeExists = predicate.Maybe<TCoExists>()) {
364398
predicateTree.CanBePushed = ExistsCanBePushed(maybeExists.Cast(), lambdaArg);
399+
predicateTree.CanBePushedApply = predicateTree.CanBePushed;
365400
} else if (const auto maybeJsonExists = predicate.Maybe<TCoJsonExists>()) {
366401
predicateTree.CanBePushed = JsonExistsCanBePushed(maybeJsonExists.Cast(), lambdaArg);
402+
predicateTree.CanBePushedApply = predicateTree.CanBePushed;
367403
}
368-
if (predicateTree.CanBePushed) {
369-
return;
370-
} else if (allowOlapApply){
404+
405+
if (allowOlapApply && !predicateTree.CanBePushedApply){
371406
if (predicate.Maybe<TCoIf>() || predicate.Maybe<TCoJust>() || predicate.Maybe<TCoCoalesce>()) {
372-
return CollectChildrenPredicates(predicate.Ref(), predicateTree, lambdaArg, lambdaBody, allowOlapApply);
407+
CollectChildrenPredicates(predicate.Ref(), predicateTree, lambdaArg, lambdaBody, true);
408+
}
409+
if (!predicateTree.CanBePushedApply) {
410+
predicateTree.CanBePushedApply = AbstractTreeCanBePushed(predicate, lambdaArg);
373411
}
374-
predicateTree.CanBePushed = AbstractTreeCanBePushed(predicate, lambdaArg);
375412
}
376413
}
377414
} //namespace NKikimr::NKqp::NOpt

ydb/core/kqp/opt/physical/predicate_collector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct TOLAPPredicateNode {
99
TExprNode::TPtr ExprNode;
1010
std::vector<TOLAPPredicateNode> Children;
1111
bool CanBePushed = false;
12+
bool CanBePushedApply = false;
1213

1314
bool IsValid() const {
1415
return ExprNode && std::all_of(Children.cbegin(), Children.cend(), std::bind(&TOLAPPredicateNode::IsValid, std::placeholders::_1));

ydb/core/kqp/provider/yql_kikimr_settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ struct TKikimrConfiguration : public TKikimrSettings, public NCommon::TSettingDi
178178
bool EnableSpilling = true;
179179
ui32 DefaultCostBasedOptimizationLevel = 4;
180180
bool EnableConstantFolding = true;
181+
bool EnableFoldUdfs = true;
181182
ui64 DefaultEnableSpillingNodes = 0;
182183
bool EnableAntlr4Parser = false;
183184
bool EnableSnapshotIsolationRW = false;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SELECT *
2+
FROM `/Root/S` as S
3+
WHERE S.payload2 = String::HexDecode("54");

0 commit comments

Comments
 (0)