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

Commit 7d083d5

Browse files
author
GustavoAngulo
committed
Test case for predicate redistribution
1 parent 3601050 commit 7d083d5

File tree

2 files changed

+82
-110
lines changed

2 files changed

+82
-110
lines changed

src/optimizer/rule_impls.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,30 +96,36 @@ bool InnerJoinAssociativity::Check(std::shared_ptr<OperatorExpression> expr,
9696
void InnerJoinAssociativity::Transform(
9797
std::shared_ptr<OperatorExpression> input,
9898
std::vector<std::shared_ptr<OperatorExpression>> &transformed,
99-
UNUSED_ATTRIBUTE OptimizeContext *context) const {
99+
OptimizeContext *context) const {
100+
100101
// NOTE: Transforms (left JOIN middle) JOIN right -> left JOIN (middle JOIN
101102
// right) Variables are named accordingly to above transformation
102103
auto parent_join = input->Op().As<LogicalInnerJoin>();
103104
std::vector<std::shared_ptr<OperatorExpression>> children = input->Children();
105+
PL_ASSERT(children.size() == 2);
106+
PL_ASSERT(children[0]->Op().GetType() == OpType::InnerJoin);
107+
PL_ASSERT(children[0]->Children().size() == 2);
104108
auto child_join = children[0]->Op().As<LogicalInnerJoin>();
105109
auto left = children[0]->Children()[0];
106110
auto middle = children[0]->Children()[1];
107111
auto right = children[1];
108-
PL_ASSERT(children.size() == 2);
109-
PL_ASSERT(children[0]->Op().GetType() == OpType::InnerJoin);
110-
PL_ASSERT(children[0]->Children().size() == 2);
111112

112113
// Get Alias sets
113114
auto &memo = context->metadata->memo;
114-
auto middle_group_id =
115-
children[0]->Children()[1]->Op().As<LeafOperator>()->origin_group;
115+
116+
auto middle_group_id = children[0]->Children()[1]->Op().As<LeafOperator>()->origin_group;
116117
auto right_group_id = children[1]->Op().As<LeafOperator>()->origin_group;
117118

118119
const auto &middle_group_aliases_set =
119120
memo.GetGroupByID(middle_group_id)->GetTableAliases();
120121
const auto &right_group_aliases_set =
121122
memo.GetGroupByID(right_group_id)->GetTableAliases();
122123

124+
// Union Predicates into single alias set for new child join
125+
std::unordered_set<std::string> right_join_aliases_set;
126+
right_join_aliases_set.insert(middle_group_aliases_set.begin(), middle_group_aliases_set.end());
127+
right_join_aliases_set.insert(right_group_aliases_set.begin(), right_group_aliases_set.end());
128+
123129
// Redistribute predicates
124130
auto parent_join_predicates =
125131
std::vector<AnnotatedExpression>(parent_join->join_predicates);
@@ -135,12 +141,8 @@ void InnerJoinAssociativity::Transform(
135141
std::vector<AnnotatedExpression> new_child_join_predicates;
136142
std::vector<AnnotatedExpression> new_parent_join_predicates;
137143

138-
// TODO: This assumes that predicate pushdown has not occured yet, as it will
139-
// put all non-join predicates into parent join
140144
for (auto predicate : predicates) {
141-
// New child join predicate must contain middle and right group
142-
if (util::IsSubset(middle_group_aliases_set, predicate.table_alias_set) &&
143-
util::IsSubset(right_group_aliases_set, predicate.table_alias_set))
145+
if (util::IsSubset(right_join_aliases_set, predicate.table_alias_set))
144146
new_child_join_predicates.emplace_back(predicate);
145147
else
146148
new_parent_join_predicates.emplace_back(predicate);

test/optimizer/optimizer_rule_test.cpp

Lines changed: 69 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "executor/insert_executor.h"
2424
#include "executor/plan_executor.h"
2525
#include "executor/update_executor.h"
26+
#include "expression/abstract_expression.h"
27+
#include "expression/operator_expression.h"
2628
#include "optimizer/operator_expression.h"
2729
#include "optimizer/operators.h"
2830
#include "optimizer/optimizer.h"
@@ -36,6 +38,7 @@
3638
#include "sql/testing_sql_util.h"
3739
#include "type/value_factory.h"
3840

41+
3942
namespace peloton {
4043
namespace test {
4144

@@ -78,106 +81,73 @@ TEST_F(OptimizerRuleTests, SimpleCommutativeRuleTest) {
7881
EXPECT_EQ(output_join->Children()[1], left_get);
7982
}
8083

81-
TEST_F(OptimizerRuleTests, AssociativeRuleTest) {
82-
auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
83-
auto txn = txn_manager.BeginTransaction();
84-
catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
85-
txn_manager.CommitTransaction(txn);
86-
87-
TestingSQLUtil::ExecuteSQLQuery(
88-
"CREATE TABLE test1(a INT PRIMARY KEY, b INT, c INT);");
89-
TestingSQLUtil::ExecuteSQLQuery(
90-
"CREATE TABLE test2(a INT PRIMARY KEY, b INT, c INT);");
91-
TestingSQLUtil::ExecuteSQLQuery(
92-
"CREATE TABLE test3(a INT PRIMARY KEY, b INT, c INT);");
93-
94-
auto &peloton_parser = parser::PostgresParser::GetInstance();
95-
auto stmt =
96-
peloton_parser.BuildParseTree("SELECT * FROM test1, test2, test3");
97-
auto parse_tree = stmt->GetStatements().at(0).get();
98-
auto predicates = std::vector<expression::AbstractExpression *>();
99-
100-
optimizer::Optimizer optimizer;
101-
102-
// Push Associativity rule and execute tasks
103-
optimizer.metadata_.rule_set.transformation_rules_.clear();
104-
optimizer.metadata_.rule_set.transformation_rules_.emplace_back(
105-
new InnerJoinAssociativity());
106-
107-
txn = txn_manager.BeginTransaction();
108-
109-
auto bind_node_visitor =
110-
std::make_shared<binder::BindNodeVisitor>(txn, DEFAULT_DB_NAME);
111-
bind_node_visitor->BindNameToNode(parse_tree);
112-
113-
std::shared_ptr<GroupExpression> gexpr =
114-
optimizer.InsertQueryTree(parse_tree, txn);
115-
std::vector<GroupID> child_groups = {gexpr->GetGroupID()};
116-
117-
auto &memo = optimizer.metadata_.memo;
118-
std::shared_ptr<GroupExpression> head_gexpr =
119-
std::make_shared<GroupExpression>(Operator(), child_groups);
120-
121-
// Check plan is of structure (left JOIN middle) JOIN right
122-
// Check Parent join
123-
auto group_expr = GetSingleGroupExpression(memo, head_gexpr.get(), 0);
124-
EXPECT_EQ(OpType::InnerJoin, group_expr->Op().GetType());
125-
auto join_op = group_expr->Op().As<LogicalInnerJoin>();
126-
EXPECT_EQ(0, join_op->join_predicates.size());
127-
128-
// Check left join
129-
auto l_group_expr = GetSingleGroupExpression(memo, group_expr, 0);
130-
EXPECT_EQ(OpType::InnerJoin, l_group_expr->Op().GetType());
131-
auto left = GetSingleGroupExpression(memo, l_group_expr, 0);
132-
auto middle = GetSingleGroupExpression(memo, l_group_expr, 1);
133-
EXPECT_EQ(OpType::Get, left->Op().GetType());
134-
EXPECT_EQ(OpType::Get, middle->Op().GetType());
135-
136-
// Check right Get
137-
auto right = GetSingleGroupExpression(memo, group_expr, 1);
138-
EXPECT_EQ(OpType::Get, right->Op().GetType());
139-
140-
std::shared_ptr<OptimizeContext> root_context =
141-
std::make_shared<OptimizeContext>(&(optimizer.metadata_), nullptr);
142-
143-
auto task_stack =
144-
std::unique_ptr<OptimizerTaskStack>(new OptimizerTaskStack());
145-
optimizer.metadata_.SetTaskPool(task_stack.get());
146-
task_stack->Push(
147-
new ApplyRule(group_expr, new InnerJoinAssociativity, root_context));
148-
149-
while (!task_stack->Empty()) {
150-
auto task = task_stack->Pop();
151-
task->execute();
152-
}
84+
TEST_F(OptimizerRuleTests, SimpleAssociativeRuleTest) {
85+
86+
// (left JOIN middle) JOIN right
87+
// Build Operator Expression
88+
89+
// Setup Memo
90+
Optimizer optimizer;
91+
92+
auto left_get = std::make_shared<OperatorExpression>(LogicalGet::make(0, {}, nullptr, "test1"));
93+
auto middle_get = std::make_shared<OperatorExpression>(LogicalGet::make(0, {}, nullptr, "test2"));
94+
auto right_get = std::make_shared<OperatorExpression>(LogicalGet::make(0, {}, nullptr, "test3"));
95+
96+
auto left_get_group = optimizer.metadata_.memo.InsertExpression(optimizer.metadata_.MakeGroupExpression(left_get), true);
97+
auto middle_get_group = optimizer.metadata_.memo.InsertExpression(optimizer.metadata_.MakeGroupExpression(middle_get),true);
98+
auto right_get_group = optimizer.metadata_.memo.InsertExpression(optimizer.metadata_.MakeGroupExpression(right_get),true);
99+
100+
auto left_leaf = std::make_shared<OperatorExpression>(LeafOperator::make(left_get_group->GetGroupID()));
101+
auto middle_leaf = std::make_shared<OperatorExpression>(LeafOperator::make(middle_get_group->GetGroupID()));
102+
auto right_leaf = std::make_shared<OperatorExpression>(LeafOperator::make(right_get_group->GetGroupID()));
103+
104+
// Make Child Join
105+
std::vector<AnnotatedExpression> child_join_predicates;
106+
std::unordered_set<std::string> child_tables({"test1","test2"});
107+
auto dummy_expr = std::shared_ptr<expression::AbstractExpression>{
108+
new expression::OperatorExpression(ExpressionType::COMPARE_EQUAL, type::TypeId::INTEGER)};
109+
110+
AnnotatedExpression pred = {dummy_expr, child_tables};
111+
child_join_predicates.push_back(pred);
112+
113+
auto child_join = std::make_shared<OperatorExpression>(LogicalInnerJoin::make(child_join_predicates));
114+
child_join->PushChild(left_leaf);
115+
child_join->PushChild(middle_leaf);
116+
optimizer.metadata_.memo.InsertExpression(optimizer.metadata_.MakeGroupExpression(child_join), true);
117+
118+
// Make Parent join
119+
std::vector<AnnotatedExpression> parent_join_predicates;
120+
std::unordered_set<std::string> parent_tables({"test1","test3"});
121+
pred = {dummy_expr, parent_tables};
122+
parent_join_predicates.push_back(pred);
123+
124+
auto parent_join = std::make_shared<OperatorExpression>(LogicalInnerJoin::make(parent_join_predicates));
125+
parent_join->PushChild(child_join);
126+
parent_join->PushChild(right_leaf);
127+
128+
optimizer.metadata_.memo.InsertExpression(optimizer.metadata_.MakeGroupExpression(parent_join), true);
129+
OptimizeContext* root_context = new OptimizeContext(&(optimizer.metadata_), nullptr);
130+
LOG_DEBUG("Set up Memo");
131+
132+
// Setup rule
133+
InnerJoinAssociativity rule;
134+
135+
EXPECT_TRUE(rule.Check(parent_join, root_context));
136+
std::vector<std::shared_ptr<OperatorExpression>> outputs;
137+
rule.Transform(parent_join, outputs, root_context);
138+
EXPECT_EQ(1, outputs.size());
139+
140+
auto output_join = outputs[0];
141+
142+
EXPECT_EQ(left_leaf, output_join->Children()[0]);
143+
EXPECT_EQ(middle_leaf, output_join->Children()[1]->Children()[0]);
144+
EXPECT_EQ(right_leaf, output_join->Children()[1]->Children()[1]);
145+
146+
auto parent_join_op = output_join->Op().As<LogicalInnerJoin>();
147+
auto child_join_op = output_join->Children()[1]->Op().As<LogicalInnerJoin>();
148+
EXPECT_EQ(2, parent_join_op->join_predicates.size());
149+
EXPECT_EQ(0, child_join_op->join_predicates.size());
153150

154-
LOG_DEBUG("Executed all tasks");
155-
156-
// Check plan is now: left JOIN (middle JOIN right)
157-
// Check Parent join
158-
EXPECT_EQ(OpType::InnerJoin, group_expr->Op().GetType());
159-
join_op = group_expr->Op().As<LogicalInnerJoin>();
160-
EXPECT_EQ(0, join_op->join_predicates.size());
161-
EXPECT_EQ(2, group_expr->GetChildrenGroupsSize());
162-
LOG_DEBUG("Parent join: OK");
163-
164-
// Check left Get
165-
// TODO: Not sure why left is at index 1, but the (middle JOIN right) is at
166-
// index 0
167-
left = GetSingleGroupExpression(memo, group_expr, 1);
168-
EXPECT_EQ(OpType::Get, left->Op().GetType());
169-
LOG_DEBUG("Left Leaf: OK");
170-
171-
// Check (right JOIN right)
172-
auto r_group_expr = GetSingleGroupExpression(memo, group_expr, 0);
173-
EXPECT_EQ(OpType::InnerJoin, r_group_expr->Op().GetType());
174-
middle = GetSingleGroupExpression(memo, r_group_expr, 0);
175-
right = GetSingleGroupExpression(memo, r_group_expr, 1);
176-
EXPECT_EQ(OpType::Get, middle->Op().GetType());
177-
EXPECT_EQ(OpType::Get, right->Op().GetType());
178-
LOG_DEBUG("Right join: OK");
179-
180-
txn_manager.CommitTransaction(txn);
181151
}
182152

183153
} // namespace test

0 commit comments

Comments
 (0)