@@ -325,18 +325,18 @@ std::vector<TExprBase> GetComparisonNodes(const TExprBase& node) {
325
325
return res;
326
326
}
327
327
328
- bool IsMemberColumn (const TCoMember& member, const TExprNode* lambdaArg) {
329
- return member.Struct ().Raw () == lambdaArg;
328
+ bool IsMemberColumn (const TCoMember& member, const TExprBase& lambdaArg) {
329
+ return member.Struct ().Raw () == lambdaArg. Raw () ;
330
330
}
331
331
332
- bool IsMemberColumn (const TExprBase& node, const TExprNode* lambdaArg) {
332
+ bool IsMemberColumn (const TExprBase& node, const TExprBase& lambdaArg) {
333
333
if (auto member = node.Maybe <TCoMember>()) {
334
334
return IsMemberColumn (member.Cast (), lambdaArg);
335
335
}
336
336
return false ;
337
337
}
338
338
339
- bool CheckExpressionNodeForPushdown (const TExprBase& node, const TExprNode* lambdaArg, const TSettings& settings) {
339
+ bool CheckExpressionNodeForPushdown (const TExprBase& node, const TExprBase& lambdaArg, const TExprBase& lambdaBody , const TSettings& settings) {
340
340
if (auto maybeSafeCast = node.Maybe <TCoSafeCast>()) {
341
341
return IsSupportedCast (maybeSafeCast.Cast (), settings);
342
342
} else if (auto maybeData = node.Maybe <TCoDataCtor>()) {
@@ -358,17 +358,40 @@ bool CheckExpressionNodeForPushdown(const TExprBase& node, const TExprNode* lamb
358
358
} else if (settings.IsEnabled (TSettings::EFeatureFlag::ParameterExpression) && node.Maybe <TCoParameter>()) {
359
359
return true ;
360
360
} else if (const auto op = node.Maybe <TCoUnaryArithmetic>(); op && settings.IsEnabled (TSettings::EFeatureFlag::UnaryOperators)) {
361
- return CheckExpressionNodeForPushdown (op.Cast ().Arg (), lambdaArg, settings);
361
+ return CheckExpressionNodeForPushdown (op.Cast ().Arg (), lambdaArg, lambdaBody, settings);
362
362
} else if (const auto op = node.Maybe <TCoBinaryArithmetic>(); op && settings.IsEnabled (TSettings::EFeatureFlag::ArithmeticalExpressions)) {
363
363
if (!settings.IsEnabled (TSettings::EFeatureFlag::DivisionExpressions) && (op.Maybe <TCoDiv>() || op.Maybe <TCoMod>())) {
364
364
return false ;
365
365
}
366
- return CheckExpressionNodeForPushdown (op.Cast ().Left (), lambdaArg, settings) && CheckExpressionNodeForPushdown (op.Cast ().Right (), lambdaArg, settings);
366
+ return CheckExpressionNodeForPushdown (op.Cast ().Left (), lambdaArg, lambdaBody, settings) && CheckExpressionNodeForPushdown (op.Cast ().Right (), lambdaArg, lambdaBody, settings);
367
+ } else if (settings.IsEnabled (TSettings::EFeatureFlag::JustPassthroughOperators) && (node.Maybe <TCoCoalesce>() || node.Maybe <TCoJust>())) {
368
+ for (const auto & childNodePtr : node.Ref ().Children ()) {
369
+ if (!CheckExpressionNodeForPushdown (TExprBase (childNodePtr), lambdaArg, lambdaBody, settings)) {
370
+ return false ;
371
+ }
372
+ }
373
+ return true ;
374
+ } else if (auto maybeIf = node.Maybe <TCoIf>()) {
375
+ if (!settings.IsEnabled (TSettings::EFeatureFlag::JustPassthroughOperators)) {
376
+ return false ;
377
+ }
378
+
379
+ const auto & sqlIf = maybeIf.Cast ();
380
+ const auto & predicate = sqlIf.Predicate ();
381
+
382
+ // Check if predicate pushdown
383
+ TPredicateNode ifPredicate (predicate);
384
+ CollectPredicates (TExprBase (predicate), ifPredicate, lambdaArg, lambdaBody, settings);
385
+
386
+ // Check if expressions pushdown
387
+ return ifPredicate.CanBePushed
388
+ && CheckExpressionNodeForPushdown (sqlIf.ThenValue (), lambdaArg, lambdaBody, settings)
389
+ && CheckExpressionNodeForPushdown (sqlIf.ElseValue (), lambdaArg, lambdaBody, settings);
367
390
}
368
391
return false ;
369
392
}
370
393
371
- bool CheckComparisonParametersForPushdown (const TCoCompare& compare, const TExprNode* lambdaArg, const TExprBase& input, const TSettings& settings) {
394
+ bool CheckComparisonParametersForPushdown (const TCoCompare& compare, const TExprBase& lambdaArg, const TExprBase& input, const TSettings& settings) {
372
395
const TTypeAnnotationNode* inputType = input.Ptr ()->GetTypeAnn ();
373
396
switch (inputType->GetKind ()) {
374
397
case ETypeAnnotationKind::Flow:
@@ -396,7 +419,7 @@ bool CheckComparisonParametersForPushdown(const TCoCompare& compare, const TExpr
396
419
YQL_ENSURE (leftList.size () == rightList.size (), " Different sizes of lists in comparison!" );
397
420
398
421
for (size_t i = 0 ; i < leftList.size (); ++i) {
399
- if (!CheckExpressionNodeForPushdown (leftList[i], lambdaArg, settings) || !CheckExpressionNodeForPushdown (rightList[i], lambdaArg, settings)) {
422
+ if (!CheckExpressionNodeForPushdown (leftList[i], lambdaArg, input, settings) || !CheckExpressionNodeForPushdown (rightList[i], lambdaArg, input , settings)) {
400
423
return false ;
401
424
}
402
425
@@ -415,7 +438,7 @@ bool CheckComparisonParametersForPushdown(const TCoCompare& compare, const TExpr
415
438
return true ;
416
439
}
417
440
418
- bool CompareCanBePushed (const TCoCompare& compare, const TExprNode* lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
441
+ bool CompareCanBePushed (const TCoCompare& compare, const TExprBase& lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
419
442
if (!IsSupportedPredicate (compare, settings)) {
420
443
return false ;
421
444
}
@@ -427,11 +450,11 @@ bool CompareCanBePushed(const TCoCompare& compare, const TExprNode* lambdaArg, c
427
450
return true ;
428
451
}
429
452
430
- bool SqlInCanBePushed (const TCoSqlIn& sqlIn, const TExprNode* lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
453
+ bool SqlInCanBePushed (const TCoSqlIn& sqlIn, const TExprBase& lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
431
454
const TExprBase& expr = sqlIn.Collection ();
432
455
const TExprBase& lookup = sqlIn.Lookup ();
433
456
434
- if (!CheckExpressionNodeForPushdown (lookup, lambdaArg, settings)) {
457
+ if (!CheckExpressionNodeForPushdown (lookup, lambdaArg, lambdaBody, settings)) {
435
458
return false ;
436
459
}
437
460
@@ -446,7 +469,7 @@ bool SqlInCanBePushed(const TCoSqlIn& sqlIn, const TExprNode* lambdaArg, const T
446
469
447
470
const TTypeAnnotationNode* inputType = lambdaBody.Ptr ()->GetTypeAnn ();
448
471
for (auto & child : collection->Children ()) {
449
- if (!CheckExpressionNodeForPushdown (TExprBase (child), lambdaArg, settings)) {
472
+ if (!CheckExpressionNodeForPushdown (TExprBase (child), lambdaArg, lambdaBody, settings)) {
450
473
return false ;
451
474
}
452
475
@@ -459,14 +482,14 @@ bool SqlInCanBePushed(const TCoSqlIn& sqlIn, const TExprNode* lambdaArg, const T
459
482
return true ;
460
483
}
461
484
462
- bool IsDistinctCanBePushed (const TExprBase& predicate, const TExprNode* lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
485
+ bool IsDistinctCanBePushed (const TExprBase& predicate, const TExprBase& lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
463
486
if (predicate.Ref ().ChildrenSize () != 2 ) {
464
487
return false ;
465
488
}
466
489
auto expr1 = TExprBase (predicate.Ref ().Child (0 ));
467
490
auto expr2 = TExprBase (predicate.Ref ().Child (1 ));
468
- if (!CheckExpressionNodeForPushdown (expr1, lambdaArg, settings)
469
- || !CheckExpressionNodeForPushdown (expr2, lambdaArg, settings)) {
491
+ if (!CheckExpressionNodeForPushdown (expr1, lambdaArg, lambdaBody, settings)
492
+ || !CheckExpressionNodeForPushdown (expr2, lambdaArg, lambdaBody, settings)) {
470
493
return false ;
471
494
}
472
495
if (!settings.IsEnabled (TSettings::EFeatureFlag::DoNotCheckCompareArgumentsTypes)
@@ -476,7 +499,7 @@ bool IsDistinctCanBePushed(const TExprBase& predicate, const TExprNode* lambdaAr
476
499
return true ;
477
500
}
478
501
479
- bool SafeCastCanBePushed (const TCoFlatMap& flatmap, const TExprNode* lambdaArg, const TSettings& settings) {
502
+ bool SafeCastCanBePushed (const TCoFlatMap& flatmap, const TExprBase& lambdaArg, const TExprBase& lambdaBody , const TSettings& settings) {
480
503
/*
481
504
* There are three ways of comparison in following format:
482
505
*
@@ -497,7 +520,7 @@ bool SafeCastCanBePushed(const TCoFlatMap& flatmap, const TExprNode* lambdaArg,
497
520
YQL_ENSURE (leftList.size () == rightList.size (), " Different sizes of lists in comparison!" );
498
521
499
522
for (size_t i = 0 ; i < leftList.size (); ++i) {
500
- if (!CheckExpressionNodeForPushdown (leftList[i], lambdaArg, settings) || !CheckExpressionNodeForPushdown (rightList[i], lambdaArg, settings)) {
523
+ if (!CheckExpressionNodeForPushdown (leftList[i], lambdaArg, lambdaBody, settings) || !CheckExpressionNodeForPushdown (rightList[i], lambdaArg, lambdaBody , settings)) {
501
524
return false ;
502
525
}
503
526
}
@@ -520,7 +543,7 @@ bool SafeCastCanBePushed(const TCoFlatMap& flatmap, const TExprNode* lambdaArg,
520
543
return true ;
521
544
}
522
545
523
- bool JsonExistsCanBePushed (const TCoJsonExists& jsonExists, const TExprNode* lambdaArg) {
546
+ bool JsonExistsCanBePushed (const TCoJsonExists& jsonExists, const TExprBase& lambdaArg) {
524
547
auto maybeMember = jsonExists.Json ().Maybe <TCoMember>();
525
548
if (!maybeMember || !jsonExists.JsonPath ().Maybe <TCoUtf8>()) {
526
549
// Currently we support only simple columns in pushdown
@@ -532,7 +555,7 @@ bool JsonExistsCanBePushed(const TCoJsonExists& jsonExists, const TExprNode* lam
532
555
return true ;
533
556
}
534
557
535
- bool CoalesceCanBePushed (const TCoCoalesce& coalesce, const TExprNode* lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
558
+ bool CoalesceCanBePushed (const TCoCoalesce& coalesce, const TExprBase& lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
536
559
if (!coalesce.Value ().Maybe <TCoBool>()) {
537
560
return false ;
538
561
}
@@ -541,7 +564,7 @@ bool CoalesceCanBePushed(const TCoCoalesce& coalesce, const TExprNode* lambdaArg
541
564
if (auto maybeCompare = predicate.Maybe <TCoCompare>()) {
542
565
return CompareCanBePushed (maybeCompare.Cast (), lambdaArg, lambdaBody, settings);
543
566
} else if (auto maybeFlatmap = predicate.Maybe <TCoFlatMap>()) {
544
- return SafeCastCanBePushed (maybeFlatmap.Cast (), lambdaArg, settings);
567
+ return SafeCastCanBePushed (maybeFlatmap.Cast (), lambdaArg, lambdaBody, settings);
545
568
} else if (settings.IsEnabled (TSettings::EFeatureFlag::JsonExistsOperator) && predicate.Maybe <TCoJsonExists>()) {
546
569
auto jsonExists = predicate.Cast <TCoJsonExists>();
547
570
return JsonExistsCanBePushed (jsonExists, lambdaArg);
@@ -550,11 +573,67 @@ bool CoalesceCanBePushed(const TCoCoalesce& coalesce, const TExprNode* lambdaArg
550
573
return false ;
551
574
}
552
575
553
- bool ExistsCanBePushed (const TCoExists& exists, const TExprNode* lambdaArg) {
576
+ bool ExistsCanBePushed (const TCoExists& exists, const TExprBase& lambdaArg) {
554
577
return IsMemberColumn (exists.Optional (), lambdaArg);
555
578
}
556
579
557
- void CollectChildrenPredicates (const TExprNode& opNode, TPredicateNode& predicateTree, const TExprNode* lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
580
+ bool UdfCanBePushed (const TCoUdf& udf, const TExprNode::TListType& children, const TExprBase& lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
581
+ const TString functionName (udf.MethodName ());
582
+ if (!settings.IsEnabledFunction (functionName)) {
583
+ return false ;
584
+ }
585
+
586
+ if (functionName == " Re2.Grep" ) {
587
+ if (children.size () != 2 ) {
588
+ // Expected exactly one argument (first child of apply is callable)
589
+ return false ;
590
+ }
591
+
592
+ const auto & udfSettings = udf.Settings ();
593
+ if (udfSettings && !udfSettings.Cast ().Empty ()) {
594
+ // Expected empty udf settings
595
+ return false ;
596
+ }
597
+
598
+ const auto & maybeRunConfig = udf.RunConfigValue ();
599
+ if (!maybeRunConfig) {
600
+ // Expected non empty run config
601
+ return false ;
602
+ }
603
+ const auto & runConfig = maybeRunConfig.Cast ().Ref ();
604
+
605
+ if (runConfig.ChildrenSize () != 2 ) {
606
+ // Expected exactly two run config settings
607
+ return false ;
608
+ }
609
+ if (!TExprBase (runConfig.Child (1 )).Maybe <TCoNothing>()) {
610
+ // Expected empty regexp settings
611
+ return false ;
612
+ }
613
+
614
+ return CheckExpressionNodeForPushdown (TExprBase (runConfig.Child (0 )), lambdaArg, lambdaBody, settings);
615
+ }
616
+ return false ;
617
+ }
618
+
619
+ bool ApplyCanBePushed (const TCoApply& apply, const TExprBase& lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
620
+ // Check callable
621
+ if (auto udf = apply.Callable ().Maybe <TCoUdf>()) {
622
+ if (!UdfCanBePushed (udf.Cast (), apply.Ref ().ChildrenList (), lambdaArg, lambdaBody, settings)) {
623
+ return false ;
624
+ }
625
+ }
626
+
627
+ // Check arguments
628
+ for (size_t i = 1 ; i < apply.Ref ().ChildrenSize (); ++i) {
629
+ if (!CheckExpressionNodeForPushdown (TExprBase (apply.Ref ().Child (i)), lambdaArg, lambdaBody, settings)) {
630
+ return false ;
631
+ }
632
+ }
633
+ return true ;
634
+ }
635
+
636
+ void CollectChildrenPredicates (const TExprNode& opNode, TPredicateNode& predicateTree, const TExprBase& lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
558
637
predicateTree.Children .reserve (opNode.ChildrenSize ());
559
638
predicateTree.CanBePushed = true ;
560
639
for (const auto & childNodePtr: opNode.Children ()) {
@@ -569,13 +648,13 @@ void CollectChildrenPredicates(const TExprNode& opNode, TPredicateNode& predicat
569
648
}
570
649
}
571
650
572
- void CollectExpressionPredicate (TPredicateNode& predicateTree, const TCoMember& member, const TExprNode* lambdaArg) {
651
+ void CollectExpressionPredicate (TPredicateNode& predicateTree, const TCoMember& member, const TExprBase& lambdaArg) {
573
652
predicateTree.CanBePushed = IsMemberColumn (member, lambdaArg);
574
653
}
575
654
576
655
} // anonymous namespace end
577
656
578
- void CollectPredicates (const TExprBase& predicate, TPredicateNode& predicateTree, const TExprNode* lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
657
+ void CollectPredicates (const TExprBase& predicate, TPredicateNode& predicateTree, const TExprBase& lambdaArg, const TExprBase& lambdaBody, const TSettings& settings) {
579
658
if (predicate.Maybe <TCoCoalesce>()) {
580
659
if (settings.IsEnabled (TSettings::EFeatureFlag::JustPassthroughOperators))
581
660
CollectChildrenPredicates (predicate.Ref (), predicateTree, lambdaArg, lambdaBody, settings);
@@ -618,6 +697,8 @@ void CollectPredicates(const TExprBase& predicate, TPredicateNode& predicateTree
618
697
} else if (settings.IsEnabled (TSettings::EFeatureFlag::IsDistinctOperator) &&
619
698
(predicate.Ref ().IsCallable ({" IsNotDistinctFrom" , " IsDistinctFrom" }))) {
620
699
predicateTree.CanBePushed = IsDistinctCanBePushed (predicate, lambdaArg, lambdaBody, settings);
700
+ } else if (auto maybeApply = predicate.Maybe <TCoApply>()) {
701
+ predicateTree.CanBePushed = ApplyCanBePushed (maybeApply.Cast (), lambdaArg, lambdaBody, settings);
621
702
} else {
622
703
predicateTree.CanBePushed = false ;
623
704
}
0 commit comments