Skip to content
This repository was archived by the owner on Sep 27, 2019. It is now read-only.

Commit e4deb72

Browse files
author
Erik Sargent
committed
Non-null column rules & tests added, as well as mix tests for comparator elimination & short circuiting
1 parent a82f2a4 commit e4deb72

File tree

9 files changed

+308
-6
lines changed

9 files changed

+308
-6
lines changed

src/include/common/internal_types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,10 @@ enum class RuleType : uint32_t {
13971397
AND_SHORT_CIRCUIT, // (FALSE AND B)
13981398
OR_SHORT_CIRCUIT, // (TRUE OR B)
13991399

1400+
// Catalog-based NULL/NON-NULL rules
1401+
NULL_LOOKUP_ON_NOT_NULL_COLUMN,
1402+
NOT_NULL_LOOKUP_ON_NOT_NULL_COLUMN,
1403+
14001404
// Place holder to generate number of rules compile time
14011405
NUM_RULES
14021406

src/include/expression/tuple_value_expression.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ class TupleValueExpression : public AbstractExpression {
7979
tuple_idx_ = tuple_idx;
8080
}
8181

82+
inline void SetIsNotNull(bool is_not_null) {
83+
is_not_null_ = is_not_null;
84+
}
85+
8286
/**
8387
* @brief Attribute binding
8488
* @param binding_contexts
@@ -94,7 +98,9 @@ class TupleValueExpression : public AbstractExpression {
9498
}
9599

96100
AbstractExpression *Copy() const override {
97-
return new TupleValueExpression(*this);
101+
TupleValueExpression *t = new TupleValueExpression(*this);
102+
t->SetIsNotNull(GetIsNotNull());
103+
return t;
98104
}
99105

100106
virtual bool operator==(const AbstractExpression &rhs) const override {
@@ -116,6 +122,8 @@ class TupleValueExpression : public AbstractExpression {
116122
if ((table_name_.empty() xor other.table_name_.empty()) ||
117123
col_name_.empty() xor other.col_name_.empty())
118124
return false;
125+
if (GetIsNotNull() != other.GetIsNotNull())
126+
return false;
119127
bool res = bound_obj_id_ == other.bound_obj_id_;
120128
if (!table_name_.empty() && !other.table_name_.empty())
121129
res = table_name_ == other.table_name_ && res;
@@ -151,6 +159,8 @@ class TupleValueExpression : public AbstractExpression {
151159

152160
bool GetIsBound() const { return is_bound_; }
153161

162+
bool GetIsNotNull() const { return is_not_null_; }
163+
154164
const std::tuple<oid_t, oid_t, oid_t> &GetBoundOid() const {
155165
return bound_obj_id_;
156166
}
@@ -196,6 +206,7 @@ class TupleValueExpression : public AbstractExpression {
196206
int tuple_idx_;
197207
std::string table_name_;
198208
std::string col_name_;
209+
bool is_not_null_ = false;
199210

200211
const planner::AttributeInfo *ai_;
201212
};

src/include/optimizer/rule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ enum class RewriteRuleSetName : uint32_t {
117117
COMPARATOR_ELIMINATION,
118118
EQUIVALENT_TRANSFORM,
119119
TRANSITIVE_TRANSFORM,
120-
BOOLEAN_SHORT_CIRCUIT
120+
BOOLEAN_SHORT_CIRCUIT,
121+
NULL_LOOKUP
121122
};
122123

123124
/**

src/include/optimizer/rule_rewrite.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,28 @@ class OrShortCircuit: public Rule<AbsExpr_Container,ExpressionType,AbsExpr_Expre
9696
OptimizeContextTemplate *context) const override;
9797
};
9898

99+
class NullLookupOnNotNullColumn: public Rule<AbsExpr_Container,ExpressionType,AbsExpr_Expression> {
100+
public:
101+
NullLookupOnNotNullColumn();
102+
103+
int Promise(GroupExprTemplate *group_expr, OptimizeContextTemplate *context) const override;
104+
bool Check(std::shared_ptr<AbsExpr_Expression> plan, OptimizeContextTemplate *context) const override;
105+
void Transform(std::shared_ptr<AbsExpr_Expression> input,
106+
std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
107+
OptimizeContextTemplate *context) const override;
108+
};
109+
110+
class NotNullLookupOnNotNullColumn: public Rule<AbsExpr_Container,ExpressionType,AbsExpr_Expression> {
111+
public:
112+
NotNullLookupOnNotNullColumn();
113+
114+
int Promise(GroupExprTemplate *group_expr, OptimizeContextTemplate *context) const override;
115+
bool Check(std::shared_ptr<AbsExpr_Expression> plan, OptimizeContextTemplate *context) const override;
116+
void Transform(std::shared_ptr<AbsExpr_Expression> input,
117+
std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
118+
OptimizeContextTemplate *context) const override;
119+
};
120+
121+
99122
} // namespace optimizer
100123
} // namespace peloton

src/optimizer/binding.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212

1313
#include "optimizer/binding.h"
1414

15+
#include <memory>
16+
1517
#include "common/logger.h"
1618
#include "optimizer/operator_visitor.h"
1719
#include "optimizer/optimizer.h"
1820
#include "optimizer/absexpr_expression.h"
1921
#include "expression/group_marker_expression.h"
22+
#include "expression/abstract_expression.h"
23+
#include "expression/tuple_value_expression.h"
2024

2125
namespace peloton {
2226
namespace optimizer {
@@ -134,6 +138,7 @@ GroupExprBindingIterator<Node,OperatorType,OperatorExpr>::GroupExprBindingIterat
134138
first_(true),
135139
has_next_(false),
136140
current_binding_(std::make_shared<OperatorExpr>(gexpr->Op())) {
141+
// First check to make sure that types of pattern & expression match
137142
if (gexpr->Op().GetType() != pattern->Type()) {
138143
return;
139144
}

src/optimizer/rewriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,11 @@ void Rewriter::RewriteLoop(int root_group_id) {
6666
metadata_.SetTaskPool(task_stack.get());
6767

6868
// Perform rewrite first
69+
task_stack->Push(new TopDownRewriteTemplate(root_group_id, root_context, RewriteRuleSetName::BOOLEAN_SHORT_CIRCUIT));
6970
task_stack->Push(new BottomUpRewriteTemplate(root_group_id, root_context, RewriteRuleSetName::TRANSITIVE_TRANSFORM, false));
7071
task_stack->Push(new BottomUpRewriteTemplate(root_group_id, root_context, RewriteRuleSetName::COMPARATOR_ELIMINATION, false));
7172

73+
task_stack->Push(new BottomUpRewriteTemplate(root_group_id, root_context, RewriteRuleSetName::NULL_LOOKUP, false));
7274
auto equiv_task = new TopDownRewriteTemplate(root_group_id, root_context, RewriteRuleSetName::EQUIVALENT_TRANSFORM);
7375
equiv_task->SetReplaceOnTransform(false); // generate equivalent
7476
task_stack->Push(equiv_task);

src/optimizer/rule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ RuleSet<AbsExpr_Container,ExpressionType,AbsExpr_Expression>::RuleSet() {
9191

9292
AddRewriteRule(RewriteRuleSetName::BOOLEAN_SHORT_CIRCUIT, new AndShortCircuit());
9393
AddRewriteRule(RewriteRuleSetName::BOOLEAN_SHORT_CIRCUIT, new OrShortCircuit());
94+
95+
AddRewriteRule(RewriteRuleSetName::NULL_LOOKUP, new NullLookupOnNotNullColumn());
96+
AddRewriteRule(RewriteRuleSetName::NULL_LOOKUP, new NotNullLookupOnNotNullColumn());
9497
}
9598

9699
template <>

src/optimizer/rule_rewrite.cpp

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,6 @@ void AndShortCircuit::Transform(std::shared_ptr<AbsExpr_Expression> input,
431431
(void)context;
432432
(void)transformed;
433433

434-
LOG_DEBUG("Transforming AND!");
435-
436434
// Asserting guarantees provided by the GroupExprBindingIterator
437435
// Structure: (FALSE AND <any expression>)
438436
PELOTON_ASSERT(input->Children().size() == 2);
@@ -485,8 +483,6 @@ void OrShortCircuit::Transform(std::shared_ptr<AbsExpr_Expression> input,
485483
(void)context;
486484
(void)transformed;
487485

488-
LOG_DEBUG("Transforming OR!");
489-
490486
// Asserting guarantees provided by the GroupExprBindingIterator
491487
// Structure: (TRUE OR <any expression>)
492488
PELOTON_ASSERT(input->Children().size() == 2);
@@ -509,5 +505,104 @@ void OrShortCircuit::Transform(std::shared_ptr<AbsExpr_Expression> input,
509505
}
510506

511507

508+
NullLookupOnNotNullColumn::NullLookupOnNotNullColumn() {
509+
type_ = RuleType::NULL_LOOKUP_ON_NOT_NULL_COLUMN;
510+
511+
// Structure: [T.X IS NULL]
512+
match_pattern = std::make_shared<Pattern<ExpressionType>>(ExpressionType::OPERATOR_IS_NULL);
513+
auto child = std::make_shared<Pattern<ExpressionType>>(ExpressionType::VALUE_TUPLE);
514+
515+
match_pattern->AddChild(child);
516+
}
517+
518+
int NullLookupOnNotNullColumn::Promise(GroupExprTemplate *group_expr, OptimizeContextTemplate *context) const {
519+
(void)group_expr;
520+
(void)context;
521+
return static_cast<int>(RulePriority::HIGH);
522+
}
523+
524+
bool NullLookupOnNotNullColumn::Check(std::shared_ptr<AbsExpr_Expression> plan, OptimizeContextTemplate *context) const {
525+
(void)plan;
526+
(void)context;
527+
return true;
528+
}
529+
530+
void NullLookupOnNotNullColumn::Transform(std::shared_ptr<AbsExpr_Expression> input,
531+
std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
532+
OptimizeContextTemplate *context) const {
533+
(void)context;
534+
(void)transformed;
535+
536+
// Asserting guarantees provided by the GroupExprBindingIterator
537+
// Structure: (TRUE OR <any expression>)
538+
PELOTON_ASSERT(input->Children().size() == 1);
539+
PELOTON_ASSERT(input->Op().GetType() == ExpressionType::OPERATOR_IS_NULL);
540+
541+
std::shared_ptr<AbsExpr_Expression> child = input->Children()[0];
542+
PELOTON_ASSERT(child->Children().size() == 0);
543+
PELOTON_ASSERT(child->Op().GetType() == ExpressionType::VALUE_TUPLE);
544+
545+
std::shared_ptr<expression::TupleValueExpression> tuple_expr = std::dynamic_pointer_cast<expression::TupleValueExpression>(child->Op().GetExpr());
546+
547+
// Only transform into [FALSE] if the tuple value expression is specifically non-NULL,
548+
// otherwise do nothing
549+
if (tuple_expr->GetIsNotNull()) {
550+
type::Value val_false = type::ValueFactory::GetBooleanValue(false);
551+
std::shared_ptr<expression::ConstantValueExpression> false_expr = std::make_shared<expression::ConstantValueExpression>(val_false);
552+
std::shared_ptr<AbsExpr_Expression> false_container = std::make_shared<AbsExpr_Expression>(AbsExpr_Container(false_expr));
553+
transformed.push_back(false_container);
554+
}
555+
}
556+
557+
558+
NotNullLookupOnNotNullColumn::NotNullLookupOnNotNullColumn() {
559+
type_ = RuleType::NOT_NULL_LOOKUP_ON_NOT_NULL_COLUMN;
560+
561+
// Structure: [T.X IS NOT NULL]
562+
match_pattern = std::make_shared<Pattern<ExpressionType>>(ExpressionType::OPERATOR_IS_NOT_NULL);
563+
auto child = std::make_shared<Pattern<ExpressionType>>(ExpressionType::VALUE_TUPLE);
564+
565+
match_pattern->AddChild(child);
566+
}
567+
568+
int NotNullLookupOnNotNullColumn::Promise(GroupExprTemplate *group_expr, OptimizeContextTemplate *context) const {
569+
(void)group_expr;
570+
(void)context;
571+
return static_cast<int>(RulePriority::HIGH);
572+
}
573+
574+
bool NotNullLookupOnNotNullColumn::Check(std::shared_ptr<AbsExpr_Expression> plan, OptimizeContextTemplate *context) const {
575+
(void)plan;
576+
(void)context;
577+
return true;
578+
}
579+
580+
void NotNullLookupOnNotNullColumn::Transform(std::shared_ptr<AbsExpr_Expression> input,
581+
std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
582+
OptimizeContextTemplate *context) const {
583+
(void)context;
584+
(void)transformed;
585+
586+
// Asserting guarantees provided by the GroupExprBindingIterator
587+
// Structure: (TRUE OR <any expression>)
588+
PELOTON_ASSERT(input->Children().size() == 1);
589+
PELOTON_ASSERT(input->Op().GetType() == ExpressionType::OPERATOR_IS_NOT_NULL);
590+
591+
std::shared_ptr<AbsExpr_Expression> child = input->Children()[0];
592+
PELOTON_ASSERT(child->Children().size() == 0);
593+
PELOTON_ASSERT(child->Op().GetType() == ExpressionType::VALUE_TUPLE);
594+
595+
std::shared_ptr<expression::TupleValueExpression> tuple_expr = std::dynamic_pointer_cast<expression::TupleValueExpression>(child->Op().GetExpr());
596+
597+
// Only transform into [TRUE] if the tuple value expression is specifically non-NULL,
598+
// otherwise do nothing
599+
if (tuple_expr->GetIsNotNull()) {
600+
type::Value val_true = type::ValueFactory::GetBooleanValue(true);
601+
std::shared_ptr<expression::ConstantValueExpression> true_expr = std::make_shared<expression::ConstantValueExpression>(val_true);
602+
std::shared_ptr<AbsExpr_Expression> true_container = std::make_shared<AbsExpr_Expression>(AbsExpr_Container(true_expr));
603+
transformed.push_back(true_container);
604+
}
605+
}
606+
512607
} // namespace optimizer
513608
} // namespace peloton

0 commit comments

Comments
 (0)