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

Commit 1be43be

Browse files
committed
Enabled rewriting of a single rule (constant = constant), check tests.
Possibly annoying problems w.r.t Peloton/terrier: (1) Use of unique_ptr/raw pointer as opposed to shared_ptr in AbstractExpression (2) AbstractExpression equality comparison method Additional components needed: - Dynamic/template/strategy rule evaluation (particularly comparison) - Repeated/multi-level application of rules - Layer to convert from memo -> AbstractExpression - Some refactoring w.r.t templated code - Better AbsExpr_Container/Expression indirection layer (intended to present a similar interface exposed by Operator/OperatorExpression relied upon by core logic) - Proper memory management strategy (tightly coupled to problem #1)
1 parent dec8194 commit 1be43be

File tree

15 files changed

+744
-12
lines changed

15 files changed

+744
-12
lines changed

src/include/common/internal_types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,10 @@ enum class RuleType : uint32_t {
13831383
PULL_FILTER_THROUGH_MARK_JOIN,
13841384
PULL_FILTER_THROUGH_AGGREGATION,
13851385

1386+
// AST rewrite rules (logical -> logical)
1387+
// Removes ConstantValueExpression = ConstantValueExpression
1388+
COMP_EQUALITY_ELIMINATION,
1389+
13861390
// Place holder to generate number of rules compile time
13871391
NUM_RULES
13881392

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Peloton
4+
//
5+
// absexpr_expression.h
6+
//
7+
// Identification: src/include/optimizer/absexpr_expression.h
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#pragma once
12+
13+
// AbstractExpression Definition
14+
#include "expression/abstract_expression.h"
15+
16+
#include <memory>
17+
#include <vector>
18+
19+
namespace peloton {
20+
namespace optimizer {
21+
22+
// (TODO): rethink the AbsExpr_Container/Expression approach in comparion to abstract
23+
// Most of the core rule/optimizer code relies on the concept of an Operator /
24+
// OperatorExpression and the interface that the two functions respectively expose.
25+
//
26+
// The annoying part is that an AbstractExpression blends together an Operator
27+
// and OperatorExpression. Second part, the AbstractExpression does not export the
28+
// correct interface that the rest of the system depends on.
29+
//
30+
// As an extreme level of simplification (sort of hacky), an AbsExpr_Container is
31+
// analogous to Operator and wraps a single AbstractExpression node. AbsExpr_Expression
32+
// is analogous to OperatorExpression.
33+
//
34+
// AbsExpr_Container does *not* handle memory correctly w.r.t internal instantiations
35+
// from Rule transformation. This is since Peloton itself mixes unique_ptrs and
36+
// hands out raw pointers which makes adding a shared_ptr here extremely problematic.
37+
// terrier uses only shared_ptr when dealing with AbstractExpression trees.
38+
39+
class AbsExpr_Container {
40+
public:
41+
AbsExpr_Container();
42+
43+
AbsExpr_Container(const expression::AbstractExpression *expr) {
44+
node = expr;
45+
}
46+
47+
// Return operator type
48+
ExpressionType GetType() const {
49+
if (IsDefined()) {
50+
return node->GetExpressionType();
51+
}
52+
return ExpressionType::INVALID;
53+
}
54+
55+
const expression::AbstractExpression *GetExpr() const {
56+
return node;
57+
}
58+
59+
// Operator contains Logical node
60+
bool IsLogical() const {
61+
return true;
62+
}
63+
64+
// Operator contains Physical node
65+
bool IsPhysical() const {
66+
return false;
67+
}
68+
69+
std::string GetName() const {
70+
if (IsDefined()) {
71+
return node->GetExpressionName();
72+
}
73+
74+
return "Undefined";
75+
}
76+
77+
hash_t Hash() const {
78+
if (IsDefined()) {
79+
return node->Hash();
80+
}
81+
return 0;
82+
}
83+
84+
bool operator==(const AbsExpr_Container &r) {
85+
if (IsDefined() && r.IsDefined()) {
86+
// (TODO): need a better way to determine deep equality
87+
88+
// NOTE:
89+
// Without proper equality determinations, the groups will
90+
// not be assigned correctly. Arguably, terrier does this
91+
// better because a blind ExactlyEquals on different types
92+
// of ConstantValueExpression under Peloton will crash!
93+
94+
// For now, just return (false).
95+
// I don't anticipate this will affect correctness, just
96+
// performance, since duplicate trees will have to evaluated
97+
// over and over again, rather than being able to "borrow"
98+
// a previous tree's rewrite.
99+
//
100+
// Probably not worth to create a "validator" since porting
101+
// this to terrier anyways (?). == does not check Value
102+
// so it's broken. ExactlyEqual requires precondition checking.
103+
return false;
104+
} else if (!IsDefined() && !r.IsDefined()) {
105+
return true;
106+
}
107+
return false;
108+
}
109+
110+
// Operator contains physical or logical operator node
111+
bool IsDefined() const {
112+
return node != nullptr;
113+
}
114+
115+
private:
116+
const expression::AbstractExpression *node;
117+
};
118+
119+
class AbsExpr_Expression {
120+
public:
121+
AbsExpr_Expression(AbsExpr_Container op): op(op) {};
122+
123+
void PushChild(std::shared_ptr<AbsExpr_Expression> op) {
124+
children.push_back(op);
125+
}
126+
127+
void PopChild() {
128+
children.pop_back();
129+
}
130+
131+
const std::vector<std::shared_ptr<AbsExpr_Expression>> &Children() const {
132+
return children;
133+
}
134+
135+
const AbsExpr_Container &Op() const {
136+
return op;
137+
}
138+
139+
private:
140+
AbsExpr_Container op;
141+
std::vector<std::shared_ptr<AbsExpr_Expression>> children;
142+
};
143+
144+
} // namespace optimizer
145+
} // namespace peloton
146+

src/include/optimizer/rewriter.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Peloton
4+
//
5+
// rewriter.h
6+
//
7+
// Identification: src/include/optimizer/rewriter.h
8+
//
9+
// Copyright (c) 2015-2018, Carnegie Mellon University Database Group
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#pragma once
14+
15+
#include <memory>
16+
17+
#include "expression/abstract_expression.h"
18+
#include "optimizer/optimizer_metadata.h"
19+
#include "optimizer/optimizer_task_pool.h"
20+
#include "optimizer/absexpr_expression.h"
21+
22+
namespace peloton {
23+
namespace optimizer {
24+
25+
class Rewriter {
26+
27+
public:
28+
Rewriter(const Rewriter &) = delete;
29+
Rewriter &operator=(const Rewriter &) = delete;
30+
Rewriter(Rewriter &&) = delete;
31+
Rewriter &operator=(Rewriter &&) = delete;
32+
33+
Rewriter();
34+
35+
expression::AbstractExpression* RewriteExpression(const expression::AbstractExpression *expr);
36+
void Reset();
37+
38+
OptimizerMetadata<AbsExpr_Container,ExpressionType,AbsExpr_Expression> &GetMetadata() { return metadata_; }
39+
40+
std::shared_ptr<AbsExpr_Expression> ConvertToAbsExpr(const expression::AbstractExpression *expr);
41+
42+
private:
43+
void ExecuteTaskStack(OptimizerTaskStack<AbsExpr_Container,ExpressionType,AbsExpr_Expression> &task_stack);
44+
void RewriteLoop(int root_group_id);
45+
std::shared_ptr<GroupExpression<AbsExpr_Container,ExpressionType,AbsExpr_Expression>> ConvertTree(const expression::AbstractExpression *expr);
46+
OptimizerMetadata<AbsExpr_Container,ExpressionType,AbsExpr_Expression> metadata_;
47+
};
48+
49+
} // namespace optimizer
50+
} // namespace peloton

src/include/optimizer/rule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ struct RuleWithPromise {
113113

114114
enum class RewriteRuleSetName : uint32_t {
115115
PREDICATE_PUSH_DOWN = 0,
116-
UNNEST_SUBQUERY
116+
UNNEST_SUBQUERY,
117+
COMPARATOR_ELIMINATION
117118
};
118119

119120
/**

src/include/optimizer/rule_rewrite.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Peloton
4+
//
5+
// rule_rewrite.h
6+
//
7+
// Identification: src/include/optimizer/rule_rewrite.h
8+
//
9+
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#pragma once
14+
15+
#include "optimizer/rule.h"
16+
#include "optimizer/absexpr_expression.h"
17+
18+
#include <memory>
19+
20+
namespace peloton {
21+
namespace optimizer {
22+
23+
class ComparatorElimination: public Rule<AbsExpr_Container,ExpressionType,AbsExpr_Expression> {
24+
public:
25+
ComparatorElimination();
26+
27+
int Promise(GroupExpression<AbsExpr_Container,ExpressionType,AbsExpr_Expression> *group_expr,
28+
OptimizeContext<AbsExpr_Container,ExpressionType,AbsExpr_Expression> *context) const override;
29+
30+
bool Check(std::shared_ptr<AbsExpr_Expression> plan,
31+
OptimizeContext<AbsExpr_Container,ExpressionType,AbsExpr_Expression> *context) const override;
32+
33+
void Transform(std::shared_ptr<AbsExpr_Expression> input,
34+
std::vector<std::shared_ptr<AbsExpr_Expression>> &transformed,
35+
OptimizeContext<AbsExpr_Container,ExpressionType,AbsExpr_Expression> *context) const override;
36+
};
37+
} // namespace optimizer
38+
} // namespace peloton

src/optimizer/binding.cpp

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "common/logger.h"
1616
#include "optimizer/operator_visitor.h"
1717
#include "optimizer/optimizer.h"
18+
#include "optimizer/absexpr_expression.h"
1819

1920
namespace peloton {
2021
namespace optimizer {
@@ -38,9 +39,41 @@ GroupBindingIterator<Node,OperatorType,OperatorExpr>::GroupBindingIterator(
3839

3940
template <class Node, class OperatorType, class OperatorExpr>
4041
bool GroupBindingIterator<Node,OperatorType,OperatorExpr>::HasNext() {
42+
//(TODO): refactor this and specialization to reduce duplicated code
43+
if (current_iterator_) {
44+
// Check if still have bindings in current item
45+
if (!current_iterator_->HasNext()) {
46+
current_iterator_.reset(nullptr);
47+
current_item_index_++;
48+
}
49+
}
50+
51+
if (current_iterator_ == nullptr) {
52+
// Keep checking item iterators until we find a match
53+
while (current_item_index_ < num_group_items_) {
54+
current_iterator_.reset(new GroupExprBindingIterator<Node,OperatorType,OperatorExpr>(
55+
this->memo_,
56+
target_group_->GetLogicalExpressions()[current_item_index_].get(),
57+
pattern_));
58+
59+
if (current_iterator_->HasNext()) {
60+
break;
61+
}
62+
63+
current_iterator_.reset(nullptr);
64+
current_item_index_++;
65+
}
66+
}
67+
68+
std::cout << "Is there a group bind: " << (current_iterator_ != nullptr) << "\n";
69+
return current_iterator_ != nullptr;
70+
}
71+
72+
// Specialization
73+
template <>
74+
bool GroupBindingIterator<Operator,OpType,OperatorExpression>::HasNext() {
4175
LOG_TRACE("HasNext");
4276

43-
//(TODO): GroupBindingIterator::HasNext() probably needs specialization
4477
if (pattern_->Type() == OpType::Leaf) {
4578
return current_item_index_ == 0;
4679
}
@@ -56,7 +89,7 @@ bool GroupBindingIterator<Node,OperatorType,OperatorExpr>::HasNext() {
5689
if (current_iterator_ == nullptr) {
5790
// Keep checking item iterators until we find a match
5891
while (current_item_index_ < num_group_items_) {
59-
current_iterator_.reset(new GroupExprBindingIterator<Node,OperatorType,OperatorExpr>(
92+
current_iterator_.reset(new GroupExprBindingIterator<Operator,OpType,OperatorExpression>(
6093
this->memo_,
6194
target_group_->GetLogicalExpressions()[current_item_index_].get(),
6295
pattern_));
@@ -75,10 +108,16 @@ bool GroupBindingIterator<Node,OperatorType,OperatorExpr>::HasNext() {
75108

76109
template <class Node, class OperatorType, class OperatorExpr>
77110
std::shared_ptr<OperatorExpr> GroupBindingIterator<Node,OperatorType,OperatorExpr>::Next() {
78-
//(TODO): GroupBindingIterator::Next() probably needs specialization
111+
std::cout << "Fetching next iterator\n";
112+
return current_iterator_->Next();
113+
}
114+
115+
// Specialization
116+
template <>
117+
std::shared_ptr<OperatorExpression> GroupBindingIterator<Operator,OpType,OperatorExpression>::Next() {
79118
if (pattern_->Type() == OpType::Leaf) {
80119
current_item_index_ = num_group_items_;
81-
return std::make_shared<OperatorExpr>(LeafOperator::make(group_id_));
120+
return std::make_shared<OperatorExpression>(LeafOperator::make(group_id_));
82121
}
83122
return current_iterator_->Next();
84123
}
@@ -189,5 +228,8 @@ std::shared_ptr<OperatorExpr> GroupExprBindingIterator<Node,OperatorType,Operato
189228
template class GroupBindingIterator<Operator,OpType,OperatorExpression>;
190229
template class GroupExprBindingIterator<Operator,OpType,OperatorExpression>;
191230

231+
template class GroupBindingIterator<AbsExpr_Container,ExpressionType,AbsExpr_Expression>;
232+
template class GroupExprBindingIterator<AbsExpr_Container,ExpressionType,AbsExpr_Expression>;
233+
192234
} // namespace optimizer
193235
} // namespace peloton

src/optimizer/group.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "optimizer/group.h"
1414
#include "optimizer/operator_expression.h"
15+
#include "optimizer/absexpr_expression.h"
1516

1617
#include "common/logger.h"
1718

@@ -171,6 +172,7 @@ bool Group<Node, OperatorType, OperatorExpr>::HasColumnStats(std::string column_
171172

172173
// Explicitly instantiate
173174
template class Group<Operator,OpType,OperatorExpression>;
175+
template class Group<AbsExpr_Container,ExpressionType,AbsExpr_Expression>;
174176

175177
} // namespace optimizer
176178
} // namespace peloton

src/optimizer/group_expression.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "common/internal_types.h"
14+
#include "optimizer/absexpr_expression.h"
1415
#include "optimizer/group_expression.h"
1516
#include "optimizer/group.h"
1617
#include "optimizer/rule.h"
@@ -112,6 +113,7 @@ bool GroupExpression<Node,OperatorType,OperatorExpr>::HasRuleExplored(Rule<Node,
112113

113114
// Explicitly instantiate to prevent linker errors
114115
template class GroupExpression<Operator,OpType,OperatorExpression>;
116+
template class GroupExpression<AbsExpr_Container,ExpressionType,AbsExpr_Expression>;
115117

116118
} // namespace optimizer
117119
} // namespace peloton

0 commit comments

Comments
 (0)