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

Commit 5caae6d

Browse files
committed
Ported equivalent transforms and other rules onto AbstractNodes
1 parent 721323c commit 5caae6d

39 files changed

+2191
-668
lines changed

src/include/common/internal_types.h

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
//===----------------------------------------------------------------------===//
2-
//
3-
// Peloton
4-
//
5-
// internal_types.h
6-
//
7-
// Identification: src/include/common/internal_types.h
8-
//
9-
// Copyright (c) 2015-2018, Carnegie Mellon University Database Group
10-
//
11-
//===----------------------------------------------------------------------===//
12-
131
//===----------------------------------------------------------------------===//
142
//
153
// Peloton
@@ -258,7 +246,12 @@ enum class ExpressionType {
258246
// -----------------------------
259247
// Miscellaneous
260248
// -----------------------------
261-
CAST = 600
249+
CAST = 600,
250+
251+
// -----------------------------
252+
// Rewriter-specific identifier
253+
// -----------------------------
254+
GROUP_MARKER = 721
262255
};
263256

264257
// When short_str is true, return a short version of ExpressionType string
@@ -1384,8 +1377,21 @@ enum class RuleType : uint32_t {
13841377
PULL_FILTER_THROUGH_AGGREGATION,
13851378

13861379
// AST rewrite rules (logical -> logical)
1387-
// Removes ConstantValueExpression = ConstantValueExpression
1388-
COMP_EQUALITY_ELIMINATION,
1380+
// Removes ConstantValue =/!=/</>/<=/>= ConstantValue
1381+
CONSTANT_COMPARE_EQUAL,
1382+
CONSTANT_COMPARE_NOTEQUAL,
1383+
CONSTANT_COMPARE_LESSTHAN,
1384+
CONSTANT_COMPARE_GREATERTHAN,
1385+
CONSTANT_COMPARE_LESSTHANOREQUALTO,
1386+
CONSTANT_COMPARE_GREATERTHANOREQUALTO,
1387+
1388+
// Logical equivalent
1389+
EQUIV_AND,
1390+
EQUIV_OR,
1391+
EQUIV_COMPARE_EQUAL,
1392+
1393+
TV_EQUALITY_WITH_TWO_CV, // (A.B = x) AND (A.B = y) where x/y are constant
1394+
TRANSITIVE_CLOSURE_CONSTANT, // (A.B = x) AND (A.B = C.D)
13891395

13901396
// Place holder to generate number of rules compile time
13911397
NUM_RULES

src/include/expression/abstract_expression.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,24 @@ class AbstractExpression : public Printable {
111111
children_[index].reset(expr);
112112
}
113113

114+
void ClearChildren() {
115+
// The rewriter copies the AbstractExpression presented to the rewriter.
116+
// This function is used by the rewriter to properly wipe all the children
117+
// of AbstractExpression once the AbstractExpression tree has been converted
118+
// to the intermediary AbsExpr_Container/Expression tree.
119+
//
120+
// This function should only be invoked on copied AbstractExpressions and
121+
// never on original ones passed into the [rewriter] otherwise we would
122+
// violate immutable properties. We do not believe this function is strictly
123+
// necessary in terrier, however this function does serve some usefulness.
124+
//
125+
// This allows us to reduce our memory footprint while also providing better
126+
// implementation constraints within the rewriter (i.e: the rewriter should
127+
// not be trying to operate directly on AbstractExpression but rather on the
128+
// intermediary representation).
129+
children_.clear();
130+
}
131+
114132
void SetExpressionType(ExpressionType type) { exp_type_ = type; }
115133

116134
//////////////////////////////////////////////////////////////////////////////
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Peloton
4+
//
5+
// group_marker_expression.h
6+
//
7+
// Identification: src/include/expression/group_marker_expression.h
8+
//
9+
// Copyright (c) 2015-2018, Carnegie Mellon University Database Group
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#pragma once
14+
15+
#include "expression/abstract_expression.h"
16+
#include "optimizer/group_expression.h"
17+
#include "util/hash_util.h"
18+
19+
namespace peloton {
20+
21+
namespace executor {
22+
class ExecutorContext;
23+
} // namespace executor
24+
25+
namespace expression {
26+
27+
//===----------------------------------------------------------------------===//
28+
// GroupMarkerExpression
29+
//===----------------------------------------------------------------------===//
30+
31+
class GroupMarkerExpression : public AbstractExpression {
32+
public:
33+
GroupMarkerExpression(optimizer::GroupID group_id) :
34+
AbstractExpression(ExpressionType::GROUP_MARKER),
35+
group_id_(group_id) {};
36+
37+
optimizer::GroupID GetGroupID() { return group_id_; }
38+
39+
AbstractExpression *Copy() const override {
40+
return new GroupMarkerExpression(group_id_);
41+
}
42+
43+
type::Value Evaluate(const AbstractTuple *tuple1,
44+
const AbstractTuple *tuple2,
45+
executor::ExecutorContext *context) const {
46+
(void)tuple1;
47+
(void)tuple2;
48+
(void)context;
49+
PELOTON_ASSERT(0);
50+
}
51+
52+
void Accept(SqlNodeVisitor *) {
53+
PELOTON_ASSERT(0);
54+
}
55+
56+
protected:
57+
optimizer::GroupID group_id_;
58+
59+
GroupMarkerExpression(const GroupMarkerExpression &other)
60+
: AbstractExpression(other), group_id_(other.group_id_) {}
61+
};
62+
63+
} // namespace expression
64+
} // namespace peloton

src/include/optimizer/absexpr_expression.h

Lines changed: 82 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
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"
@@ -22,41 +23,45 @@
2223
namespace peloton {
2324
namespace 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-

src/include/optimizer/abstract_node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ enum class OpType {
8383
class OperatorVisitor;
8484

8585
struct AbstractNode {
86+
AbstractNode() {}
8687
AbstractNode(std::shared_ptr<AbstractNode> node) : node(node) {}
8788

8889
~AbstractNode() {}

0 commit comments

Comments
 (0)