@@ -397,5 +397,213 @@ void TransitiveClosureConstantTransform::Transform(std::shared_ptr<AbsExpr_Expre
397
397
transformed.push_back (abs_expr);
398
398
}
399
399
400
+ // ===========================================================
401
+ //
402
+ // Boolean short-circuit related functions
403
+ //
404
+ // ===========================================================
405
+ AndShortCircuit::AndShortCircuit () {
406
+ type_ = RuleType::AND_SHORT_CIRCUIT;
407
+
408
+ // (FALSE AND <any expression>)
409
+ match_pattern = std::make_shared<Pattern<ExpressionType>>(ExpressionType::CONJUNCTION_AND);
410
+ auto left_child = std::make_shared<Pattern<ExpressionType>>(ExpressionType::VALUE_CONSTANT);
411
+ auto right_child = std::make_shared<Pattern<ExpressionType>>(ExpressionType::GROUP_MARKER);
412
+
413
+ match_pattern->AddChild (left_child);
414
+ match_pattern->AddChild (right_child);
415
+ }
416
+
417
+ int AndShortCircuit::Promise (GroupExprTemplate *group_expr, OptimizeContextTemplate *context) const {
418
+ (void )group_expr;
419
+ (void )context;
420
+ return static_cast <int >(RulePriority::HIGH);
421
+ }
422
+
423
+ bool AndShortCircuit::Check (std::shared_ptr<AbsExpr_Expression> plan, OptimizeContextTemplate *context) const {
424
+ (void )plan;
425
+ (void )context;
426
+ return true ;
427
+ }
428
+
429
+ void AndShortCircuit::Transform (std::shared_ptr<AbsExpr_Expression> input,
430
+ std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
431
+ OptimizeContextTemplate *context) const {
432
+ (void )context;
433
+ (void )transformed;
434
+
435
+ // Asserting guarantees provided by the GroupExprBindingIterator
436
+ // Structure: (FALSE AND <any expression>)
437
+ PELOTON_ASSERT (input->Children ().size () == 2 );
438
+ PELOTON_ASSERT (input->Op ().GetType () == ExpressionType::CONJUNCTION_AND);
439
+
440
+ std::shared_ptr<AbsExpr_Expression> left = input->Children ()[0 ];
441
+ PELOTON_ASSERT (left->Children ().size () == 0 );
442
+ PELOTON_ASSERT (left->Op ().GetType () == ExpressionType::VALUE_CONSTANT);
443
+
444
+ std::shared_ptr<expression::ConstantValueExpression> left_cv_expr = std::dynamic_pointer_cast<expression::ConstantValueExpression>(left->Op ().GetExpr ());
445
+ type::Value left_value = left_cv_expr->GetValue ();
446
+
447
+ // Only transform the expression if we're ANDing a FALSE boolean value
448
+ if (left_value.GetTypeId () == type::TypeId::BOOLEAN && left_value.IsFalse ()) {
449
+ type::Value val_false = type::ValueFactory::GetBooleanValue (false );
450
+ std::shared_ptr<expression::ConstantValueExpression> false_expr = std::make_shared<expression::ConstantValueExpression>(val_false);
451
+ std::shared_ptr<AbsExpr_Expression> false_container = std::make_shared<AbsExpr_Expression>(AbsExpr_Container (false_expr));
452
+ transformed.push_back (false_container);
453
+ }
454
+ }
455
+
456
+
457
+ OrShortCircuit::OrShortCircuit () {
458
+ type_ = RuleType::OR_SHORT_CIRCUIT;
459
+
460
+ // (FALSE AND <any expression>)
461
+ match_pattern = std::make_shared<Pattern<ExpressionType>>(ExpressionType::CONJUNCTION_OR);
462
+ auto left_child = std::make_shared<Pattern<ExpressionType>>(ExpressionType::VALUE_CONSTANT);
463
+ auto right_child = std::make_shared<Pattern<ExpressionType>>(ExpressionType::GROUP_MARKER);
464
+
465
+ match_pattern->AddChild (left_child);
466
+ match_pattern->AddChild (right_child);
467
+ }
468
+
469
+ int OrShortCircuit::Promise (GroupExprTemplate *group_expr, OptimizeContextTemplate *context) const {
470
+ (void )group_expr;
471
+ (void )context;
472
+ return static_cast <int >(RulePriority::HIGH);
473
+ }
474
+
475
+ bool OrShortCircuit::Check (std::shared_ptr<AbsExpr_Expression> plan, OptimizeContextTemplate *context) const {
476
+ (void )plan;
477
+ (void )context;
478
+ return true ;
479
+ }
480
+
481
+ void OrShortCircuit::Transform (std::shared_ptr<AbsExpr_Expression> input,
482
+ std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
483
+ OptimizeContextTemplate *context) const {
484
+ (void )context;
485
+ (void )transformed;
486
+
487
+ // Asserting guarantees provided by the GroupExprBindingIterator
488
+ // Structure: (TRUE OR <any expression>)
489
+ PELOTON_ASSERT (input->Children ().size () == 2 );
490
+ PELOTON_ASSERT (input->Op ().GetType () == ExpressionType::CONJUNCTION_OR);
491
+
492
+ std::shared_ptr<AbsExpr_Expression> left = input->Children ()[0 ];
493
+ PELOTON_ASSERT (left->Children ().size () == 0 );
494
+ PELOTON_ASSERT (left->Op ().GetType () == ExpressionType::VALUE_CONSTANT);
495
+
496
+ std::shared_ptr<expression::ConstantValueExpression> left_cv_expr = std::dynamic_pointer_cast<expression::ConstantValueExpression>(left->Op ().GetExpr ());
497
+ type::Value left_value = left_cv_expr->GetValue ();
498
+
499
+ // Only transform the expression if we're ANDing a TRUE boolean value
500
+ if (left_value.GetTypeId () == type::TypeId::BOOLEAN && left_value.IsTrue ()) {
501
+ type::Value val_true = type::ValueFactory::GetBooleanValue (true );
502
+ std::shared_ptr<expression::ConstantValueExpression> true_expr = std::make_shared<expression::ConstantValueExpression>(val_true);
503
+ std::shared_ptr<AbsExpr_Expression> true_container = std::make_shared<AbsExpr_Expression>(AbsExpr_Container (true_expr));
504
+ transformed.push_back (true_container);
505
+ }
506
+ }
507
+
508
+
509
+ NullLookupOnNotNullColumn::NullLookupOnNotNullColumn () {
510
+ type_ = RuleType::NULL_LOOKUP_ON_NOT_NULL_COLUMN;
511
+
512
+ // Structure: [T.X IS NULL]
513
+ match_pattern = std::make_shared<Pattern<ExpressionType>>(ExpressionType::OPERATOR_IS_NULL);
514
+ auto child = std::make_shared<Pattern<ExpressionType>>(ExpressionType::VALUE_TUPLE);
515
+
516
+ match_pattern->AddChild (child);
517
+ }
518
+
519
+ int NullLookupOnNotNullColumn::Promise (GroupExprTemplate *group_expr, OptimizeContextTemplate *context) const {
520
+ (void )group_expr;
521
+ (void )context;
522
+ return static_cast <int >(RulePriority::HIGH);
523
+ }
524
+
525
+ bool NullLookupOnNotNullColumn::Check (std::shared_ptr<AbsExpr_Expression> plan, OptimizeContextTemplate *context) const {
526
+ (void )plan;
527
+ (void )context;
528
+ return true ;
529
+ }
530
+
531
+ void NullLookupOnNotNullColumn::Transform (std::shared_ptr<AbsExpr_Expression> input,
532
+ std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
533
+ OptimizeContextTemplate *context) const {
534
+ (void )context;
535
+ (void )transformed;
536
+
537
+ // Asserting guarantees provided by the GroupExprBindingIterator
538
+ // Structure: (TRUE OR <any expression>)
539
+ PELOTON_ASSERT (input->Children ().size () == 1 );
540
+ PELOTON_ASSERT (input->Op ().GetType () == ExpressionType::OPERATOR_IS_NULL);
541
+
542
+ std::shared_ptr<AbsExpr_Expression> child = input->Children ()[0 ];
543
+ PELOTON_ASSERT (child->Children ().size () == 0 );
544
+ PELOTON_ASSERT (child->Op ().GetType () == ExpressionType::VALUE_TUPLE);
545
+
546
+ std::shared_ptr<expression::TupleValueExpression> tuple_expr = std::dynamic_pointer_cast<expression::TupleValueExpression>(child->Op ().GetExpr ());
547
+
548
+ // Only transform into [FALSE] if the tuple value expression is specifically non-NULL,
549
+ // otherwise do nothing
550
+ if (tuple_expr->GetIsNotNull ()) {
551
+ type::Value val_false = type::ValueFactory::GetBooleanValue (false );
552
+ std::shared_ptr<expression::ConstantValueExpression> false_expr = std::make_shared<expression::ConstantValueExpression>(val_false);
553
+ std::shared_ptr<AbsExpr_Expression> false_container = std::make_shared<AbsExpr_Expression>(AbsExpr_Container (false_expr));
554
+ transformed.push_back (false_container);
555
+ }
556
+ }
557
+
558
+
559
+ NotNullLookupOnNotNullColumn::NotNullLookupOnNotNullColumn () {
560
+ type_ = RuleType::NOT_NULL_LOOKUP_ON_NOT_NULL_COLUMN;
561
+
562
+ // Structure: [T.X IS NOT NULL]
563
+ match_pattern = std::make_shared<Pattern<ExpressionType>>(ExpressionType::OPERATOR_IS_NOT_NULL);
564
+ auto child = std::make_shared<Pattern<ExpressionType>>(ExpressionType::VALUE_TUPLE);
565
+
566
+ match_pattern->AddChild (child);
567
+ }
568
+
569
+ int NotNullLookupOnNotNullColumn::Promise (GroupExprTemplate *group_expr, OptimizeContextTemplate *context) const {
570
+ (void )group_expr;
571
+ (void )context;
572
+ return static_cast <int >(RulePriority::HIGH);
573
+ }
574
+
575
+ bool NotNullLookupOnNotNullColumn::Check (std::shared_ptr<AbsExpr_Expression> plan, OptimizeContextTemplate *context) const {
576
+ (void )plan;
577
+ (void )context;
578
+ return true ;
579
+ }
580
+
581
+ void NotNullLookupOnNotNullColumn::Transform (std::shared_ptr<AbsExpr_Expression> input,
582
+ std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
583
+ OptimizeContextTemplate *context) const {
584
+ (void )context;
585
+ (void )transformed;
586
+
587
+ // Asserting guarantees provided by the GroupExprBindingIterator
588
+ // Structure: (TRUE OR <any expression>)
589
+ PELOTON_ASSERT (input->Children ().size () == 1 );
590
+ PELOTON_ASSERT (input->Op ().GetType () == ExpressionType::OPERATOR_IS_NOT_NULL);
591
+
592
+ std::shared_ptr<AbsExpr_Expression> child = input->Children ()[0 ];
593
+ PELOTON_ASSERT (child->Children ().size () == 0 );
594
+ PELOTON_ASSERT (child->Op ().GetType () == ExpressionType::VALUE_TUPLE);
595
+
596
+ std::shared_ptr<expression::TupleValueExpression> tuple_expr = std::dynamic_pointer_cast<expression::TupleValueExpression>(child->Op ().GetExpr ());
597
+
598
+ // Only transform into [TRUE] if the tuple value expression is specifically non-NULL,
599
+ // otherwise do nothing
600
+ if (tuple_expr->GetIsNotNull ()) {
601
+ type::Value val_true = type::ValueFactory::GetBooleanValue (true );
602
+ std::shared_ptr<expression::ConstantValueExpression> true_expr = std::make_shared<expression::ConstantValueExpression>(val_true);
603
+ std::shared_ptr<AbsExpr_Expression> true_container = std::make_shared<AbsExpr_Expression>(AbsExpr_Container (true_expr));
604
+ transformed.push_back (true_container);
605
+ }
606
+ }
607
+
400
608
} // namespace optimizer
401
609
} // namespace peloton
0 commit comments