10
10
11
11
#pragma once
12
12
13
- // AbstractExpression Definition
13
+ #include " optimizer/abstract_node_expression.h"
14
+ #include " optimizer/abstract_node.h"
14
15
#include " expression/abstract_expression.h"
15
16
#include " expression/conjunction_expression.h"
16
17
#include " expression/comparison_expression.h"
22
23
namespace peloton {
23
24
namespace optimizer {
24
25
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 .
28
29
//
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 {
43
33
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
+ }
45
40
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;
48
47
}
49
48
50
49
// Return operator type
51
- ExpressionType GetType () const {
50
+ ExpressionType GetExpType () const {
52
51
if (IsDefined ()) {
53
- return node ->GetExpressionType ();
52
+ return expr ->GetExpressionType ();
54
53
}
55
54
return ExpressionType::INVALID;
56
55
}
57
56
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 );
60
65
}
61
66
62
67
// Operator contains Logical node
@@ -71,38 +76,39 @@ class AbsExpr_Container {
71
76
72
77
std::string GetName () const {
73
78
if (IsDefined ()) {
74
- return node ->GetExpressionName ();
79
+ return expr ->GetExpressionName ();
75
80
}
76
81
77
82
return " Undefined" ;
78
83
}
79
84
80
85
hash_t Hash () const {
81
86
if (IsDefined ()) {
82
- return node ->Hash ();
87
+ return expr ->Hash ();
83
88
}
84
89
return 0 ;
85
90
}
86
91
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
+
87
101
bool operator ==(const AbsExpr_Container &r) {
88
102
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.
106
112
return false ;
107
113
} else if (!IsDefined () && !r.IsDefined ()) {
108
114
return true ;
@@ -112,72 +118,59 @@ class AbsExpr_Container {
112
118
113
119
// Operator contains physical or logical operator node
114
120
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 ;
150
122
}
151
123
124
+ // TODO(): Function should use std::shared_ptr when migrate to terrier
125
+ expression::AbstractExpression *CopyWithChildren (std::vector<expression::AbstractExpression*> children);
126
+
152
127
private:
153
- const expression::AbstractExpression *node;
128
+ // Internal wrapped AbstractExpression
129
+ std::shared_ptr<expression::AbstractExpression> expr;
154
130
};
155
131
156
- class AbsExpr_Expression {
132
+
133
+ class AbsExpr_Expression : public AbstractNodeExpression {
157
134
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
+ }
159
141
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) {
161
146
children.push_back (op);
162
147
}
163
148
164
149
void PopChild () {
165
150
children.pop_back ();
166
151
}
167
152
168
- const std::vector<std::shared_ptr<AbsExpr_Expression >> &Children () const {
153
+ const std::vector<std::shared_ptr<AbstractNodeExpression >> &Children () const {
169
154
return children;
170
155
}
171
156
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 " " ;
174
168
}
175
169
176
170
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;
179
173
};
180
174
181
175
} // namespace optimizer
182
176
} // namespace peloton
183
-
0 commit comments