1010
1111#pragma once
1212
13- // AbstractExpression Definition
13+ #include " optimizer/abstract_node_expression.h"
14+ #include " optimizer/abstract_node.h"
1415#include " expression/abstract_expression.h"
1516#include " expression/conjunction_expression.h"
1617#include " expression/comparison_expression.h"
2223namespace peloton {
2324namespace optimizer {
2425
25- // (TODO): rethink the AbsExpr_Container/Expression approach in comparion to abstract
26- // Most of the core rule/optimizer code relies on the concept of an Operator /
27- // OperatorExpression and the interface that the two functions respectively expose .
26+ // AbsExpr_Container and AbsExpr_Expression provides and serves an analogous purpose
27+ // to Operator and OperatorExpression. Each AbsExpr_Container wraps a single
28+ // AbstractExpression node with the children placed inside the AbsExpr_Expression .
2829//
29- // The annoying part is that an AbstractExpression blends together an Operator
30- // and OperatorExpression. Second part, the AbstractExpression does not export the
31- // correct interface that the rest of the system depends on.
32- //
33- // As an extreme level of simplification (sort of hacky), an AbsExpr_Container is
34- // analogous to Operator and wraps a single AbstractExpression node. AbsExpr_Expression
35- // is analogous to OperatorExpression.
36- //
37- // AbsExpr_Container does *not* handle memory correctly w.r.t internal instantiations
38- // from Rule transformation. This is since Peloton itself mixes unique_ptrs and
39- // hands out raw pointers which makes adding a shared_ptr here extremely problematic.
40- // terrier uses only shared_ptr when dealing with AbstractExpression trees.
41-
42- class AbsExpr_Container {
30+ // This is done to export the correct interface from the wrapped AbstractExpression
31+ // to the rest of the core rule/optimizer code/logic.
32+ class AbsExpr_Container : public AbstractNode {
4333 public:
44- AbsExpr_Container ();
34+ // Default constructors
35+ AbsExpr_Container () = default ;
36+ AbsExpr_Container (const AbsExpr_Container &other):
37+ AbstractNode () {
38+ expr = other.expr ;
39+ }
4540
46- AbsExpr_Container (const expression::AbstractExpression *expr) {
47- node = expr;
41+ AbsExpr_Container (std::shared_ptr<expression::AbstractExpression> expr_) {
42+ expr = expr_;
43+ }
44+
45+ OpType GetOpType () const {
46+ return OpType::Undefined;
4847 }
4948
5049 // Return operator type
51- ExpressionType GetType () const {
50+ ExpressionType GetExpType () const {
5251 if (IsDefined ()) {
53- return node ->GetExpressionType ();
52+ return expr ->GetExpressionType ();
5453 }
5554 return ExpressionType::INVALID;
5655 }
5756
58- const expression::AbstractExpression *GetExpr () const {
59- return node;
57+ std::shared_ptr<expression::AbstractExpression> GetExpr () const {
58+ return expr;
59+ }
60+
61+ // Dummy Accept
62+ void Accept (OperatorVisitor *v) const {
63+ (void )v;
64+ PELOTON_ASSERT (0 );
6065 }
6166
6267 // Operator contains Logical node
@@ -71,38 +76,39 @@ class AbsExpr_Container {
7176
7277 std::string GetName () const {
7378 if (IsDefined ()) {
74- return node ->GetExpressionName ();
79+ return expr ->GetExpressionName ();
7580 }
7681
7782 return " Undefined" ;
7883 }
7984
8085 hash_t Hash () const {
8186 if (IsDefined ()) {
82- return node ->Hash ();
87+ return expr ->Hash ();
8388 }
8489 return 0 ;
8590 }
8691
92+ bool operator ==(const AbstractNode &r) {
93+ if (r.GetExpType () != ExpressionType::INVALID) {
94+ const AbsExpr_Container &cnt = dynamic_cast <const AbsExpr_Container&>(r);
95+ return (*this == cnt);
96+ }
97+
98+ return false ;
99+ }
100+
87101 bool operator ==(const AbsExpr_Container &r) {
88102 if (IsDefined () && r.IsDefined ()) {
89- // (TODO): need a better way to determine deep equality
90-
91- // NOTE:
92- // Without proper equality determinations, the groups will
93- // not be assigned correctly. Arguably, terrier does this
94- // better because a blind ExactlyEquals on different types
95- // of ConstantValueExpression under Peloton will crash!
96-
97- // For now, just return (false).
98- // I don't anticipate this will affect correctness, just
99- // performance, since duplicate trees will have to evaluated
100- // over and over again, rather than being able to "borrow"
101- // a previous tree's rewrite.
102- //
103- // Probably not worth to create a "validator" since porting
104- // this to terrier anyways (?). == does not check Value
105- // so it's broken. ExactlyEqual requires precondition checking.
103+ // TODO(): proper equality check when migrate to terrier
104+ // Equality check relies on performing the following:
105+ // - Check each node's ExpressionType
106+ // - Check other parameters for a given node
107+ // We believe that in terrier so long as the AbstractExpression
108+ // are children-less, operator== provides sufficient checking.
109+ // The reason behind why the children-less guarantee is required,
110+ // is that the "real" children are actually tracked by the
111+ // AbsExpr_Expression class.
106112 return false ;
107113 } else if (!IsDefined () && !r.IsDefined ()) {
108114 return true ;
@@ -112,72 +118,59 @@ class AbsExpr_Container {
112118
113119 // Operator contains physical or logical operator node
114120 bool IsDefined () const {
115- return node != nullptr ;
116- }
117-
118- // (TODO): fix memory management once go to terrier
119- expression::AbstractExpression *Rebuild (std::vector<expression::AbstractExpression*> children) {
120- switch (GetType ()) {
121- case ExpressionType::COMPARE_EQUAL:
122- case ExpressionType::COMPARE_NOTEQUAL:
123- case ExpressionType::COMPARE_LESSTHAN:
124- case ExpressionType::COMPARE_GREATERTHAN:
125- case ExpressionType::COMPARE_LESSTHANOREQUALTO:
126- case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
127- case ExpressionType::COMPARE_LIKE:
128- case ExpressionType::COMPARE_NOTLIKE:
129- case ExpressionType::COMPARE_IN:
130- case ExpressionType::COMPARE_DISTINCT_FROM: {
131- PELOTON_ASSERT (children.size () == 2 );
132- return new expression::ComparisonExpression (GetType (), children[0 ], children[1 ]);
133- }
134- case ExpressionType::CONJUNCTION_AND:
135- case ExpressionType::CONJUNCTION_OR: {
136- PELOTON_ASSERT (children.size () == 2 );
137- return new expression::ConjunctionExpression (GetType (), children[0 ], children[1 ]);
138- }
139- case ExpressionType::VALUE_CONSTANT: {
140- PELOTON_ASSERT (children.size () == 0 );
141- auto cve = static_cast <const expression::ConstantValueExpression*>(node);
142- return new expression::ConstantValueExpression (cve->GetValue ());
143- }
144- default : {
145- int type = static_cast <int >(GetType ());
146- LOG_ERROR (" Unimplemented Rebuild() for %d found" , type);
147- return nullptr ;
148- }
149- }
121+ return expr != nullptr ;
150122 }
151123
124+ // TODO(): Function should use std::shared_ptr when migrate to terrier
125+ expression::AbstractExpression *CopyWithChildren (std::vector<expression::AbstractExpression*> children);
126+
152127 private:
153- const expression::AbstractExpression *node;
128+ // Internal wrapped AbstractExpression
129+ std::shared_ptr<expression::AbstractExpression> expr;
154130};
155131
156- class AbsExpr_Expression {
132+
133+ class AbsExpr_Expression : public AbstractNodeExpression {
157134 public:
158- AbsExpr_Expression (AbsExpr_Container op): op(op) {};
135+ AbsExpr_Expression (std::shared_ptr<AbstractNode> n) {
136+ std::shared_ptr<AbsExpr_Container> cnt = std::dynamic_pointer_cast<AbsExpr_Container>(n);
137+ PELOTON_ASSERT (cnt != nullptr );
138+
139+ node = n;
140+ }
159141
160- void PushChild (std::shared_ptr<AbsExpr_Expression> op) {
142+ // Disallow copy and move constructor
143+ DISALLOW_COPY_AND_MOVE (AbsExpr_Expression);
144+
145+ void PushChild (std::shared_ptr<AbstractNodeExpression> op) {
161146 children.push_back (op);
162147 }
163148
164149 void PopChild () {
165150 children.pop_back ();
166151 }
167152
168- const std::vector<std::shared_ptr<AbsExpr_Expression >> &Children () const {
153+ const std::vector<std::shared_ptr<AbstractNodeExpression >> &Children () const {
169154 return children;
170155 }
171156
172- const AbsExpr_Container &Op () const {
173- return op;
157+ const std::shared_ptr<AbstractNode> Node () const {
158+ // Integrity constraint
159+ std::shared_ptr<AbsExpr_Container> cnt = std::dynamic_pointer_cast<AbsExpr_Container>(node);
160+ PELOTON_ASSERT (cnt != nullptr );
161+
162+ return node;
163+ }
164+
165+ const std::string GetInfo () const {
166+ // TODO(): create proper info statement?
167+ return " " ;
174168 }
175169
176170 private:
177- AbsExpr_Container op ;
178- std::vector<std::shared_ptr<AbsExpr_Expression >> children;
171+ std::shared_ptr<AbstractNode> node ;
172+ std::vector<std::shared_ptr<AbstractNodeExpression >> children;
179173};
180174
181175} // namespace optimizer
182176} // namespace peloton
183-
0 commit comments