-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1898 from kuzudb/reorg-projection-planner
Re-organize projection planner
- Loading branch information
Showing
14 changed files
with
223 additions
and
206 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#include "planner/logical_plan/logical_operator/logical_aggregate.h" | ||
#include "planner/query_planner.h" | ||
|
||
namespace kuzu { | ||
namespace planner { | ||
|
||
void QueryPlanner::appendAggregate(const expression_vector& expressionsToGroupBy, | ||
const expression_vector& expressionsToAggregate, LogicalPlan& plan) { | ||
auto aggregate = make_shared<LogicalAggregate>( | ||
expressionsToGroupBy, expressionsToAggregate, plan.getLastOperator()); | ||
appendFlattens(aggregate->getGroupsPosToFlattenForGroupBy(), plan); | ||
aggregate->setChild(0, plan.getLastOperator()); | ||
appendFlattens(aggregate->getGroupsPosToFlattenForAggregate(), plan); | ||
aggregate->setChild(0, plan.getLastOperator()); | ||
aggregate->computeFactorizedSchema(); | ||
plan.setLastOperator(std::move(aggregate)); | ||
} | ||
|
||
} // namespace planner | ||
} // namespace kuzu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#include "planner/logical_plan/logical_operator/logical_limit.h" | ||
#include "planner/query_planner.h" | ||
|
||
namespace kuzu { | ||
namespace planner { | ||
|
||
void QueryPlanner::appendLimit(uint64_t limitNumber, LogicalPlan& plan) { | ||
auto limit = make_shared<LogicalLimit>(limitNumber, plan.getLastOperator()); | ||
appendFlattens(limit->getGroupsPosToFlatten(), plan); | ||
limit->setChild(0, plan.getLastOperator()); | ||
limit->computeFactorizedSchema(); | ||
plan.setCardinality(limitNumber); | ||
plan.setLastOperator(std::move(limit)); | ||
} | ||
|
||
} // namespace planner | ||
} // namespace kuzu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#include "planner/logical_plan/logical_operator/logical_multiplcity_reducer.h" | ||
#include "planner/query_planner.h" | ||
|
||
namespace kuzu { | ||
namespace planner { | ||
|
||
void QueryPlanner::appendMultiplicityReducer(LogicalPlan& plan) { | ||
auto multiplicityReducer = make_shared<LogicalMultiplicityReducer>(plan.getLastOperator()); | ||
multiplicityReducer->computeFactorizedSchema(); | ||
plan.setLastOperator(std::move(multiplicityReducer)); | ||
} | ||
|
||
} // namespace planner | ||
} // namespace kuzu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#include "planner/logical_plan/logical_operator/logical_order_by.h" | ||
#include "planner/query_planner.h" | ||
|
||
namespace kuzu { | ||
namespace planner { | ||
|
||
void QueryPlanner::appendOrderBy( | ||
const expression_vector& expressions, const std::vector<bool>& isAscOrders, LogicalPlan& plan) { | ||
auto orderBy = make_shared<LogicalOrderBy>(expressions, isAscOrders, plan.getLastOperator()); | ||
appendFlattens(orderBy->getGroupsPosToFlatten(), plan); | ||
orderBy->setChild(0, plan.getLastOperator()); | ||
orderBy->computeFactorizedSchema(); | ||
plan.setLastOperator(std::move(orderBy)); | ||
} | ||
|
||
} // namespace planner | ||
} // namespace kuzu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include "planner/logical_plan/logical_operator/flatten_resolver.h" | ||
#include "planner/logical_plan/logical_operator/logical_projection.h" | ||
#include "planner/query_planner.h" | ||
|
||
namespace kuzu { | ||
namespace planner { | ||
|
||
void QueryPlanner::appendProjection( | ||
const expression_vector& expressionsToProject, LogicalPlan& plan) { | ||
for (auto& expression : expressionsToProject) { | ||
planSubqueryIfNecessary(expression, plan); | ||
} | ||
for (auto& expression : expressionsToProject) { | ||
auto dependentGroupsPos = plan.getSchema()->getDependentGroupsPos(expression); | ||
auto groupsPosToFlatten = factorization::FlattenAllButOne::getGroupsPosToFlatten( | ||
dependentGroupsPos, plan.getSchema()); | ||
appendFlattens(groupsPosToFlatten, plan); | ||
} | ||
auto projection = make_shared<LogicalProjection>(expressionsToProject, plan.getLastOperator()); | ||
projection->computeFactorizedSchema(); | ||
plan.setLastOperator(std::move(projection)); | ||
} | ||
|
||
} // namespace planner | ||
} // namespace kuzu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#include "planner/logical_plan/logical_operator/logical_skip.h" | ||
#include "planner/query_planner.h" | ||
|
||
namespace kuzu { | ||
namespace planner { | ||
|
||
void QueryPlanner::appendSkip(uint64_t skipNumber, LogicalPlan& plan) { | ||
auto skip = make_shared<LogicalSkip>(skipNumber, plan.getLastOperator()); | ||
appendFlattens(skip->getGroupsPosToFlatten(), plan); | ||
skip->setChild(0, plan.getLastOperator()); | ||
skip->computeFactorizedSchema(); | ||
plan.setCardinality(plan.getCardinality() - skipNumber); | ||
plan.setLastOperator(std::move(skip)); | ||
} | ||
|
||
} // namespace planner | ||
} // namespace kuzu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#include "binder/expression_visitor.h" | ||
#include "planner/query_planner.h" | ||
|
||
namespace kuzu { | ||
namespace planner { | ||
|
||
void QueryPlanner::planProjectionBody(const BoundProjectionBody& projectionBody, | ||
const std::vector<std::unique_ptr<LogicalPlan>>& plans) { | ||
for (auto& plan : plans) { | ||
planProjectionBody(projectionBody, *plan); | ||
} | ||
} | ||
|
||
void QueryPlanner::planProjectionBody( | ||
const BoundProjectionBody& projectionBody, LogicalPlan& plan) { | ||
if (plan.isEmpty()) { // e.g. RETURN 1, COUNT(2) | ||
appendDummyScan(plan); | ||
} | ||
// NOTE: As a temporary solution, we rewrite variables in WITH clause as all properties in scope | ||
// during planning stage. The purpose is to avoid reading unnecessary properties for WITH. | ||
// E.g. MATCH (a) WITH a RETURN a.age -> MATCH (a) WITH a.age RETURN a.age | ||
// This rewrite should be removed once we add an optimizer that can remove unnecessary columns. | ||
auto expressionsToProject = projectionBody.getProjectionExpressions(); | ||
auto expressionsToAggregate = projectionBody.getAggregateExpressions(); | ||
auto expressionsToGroupBy = projectionBody.getGroupByExpressions(); | ||
if (!expressionsToAggregate.empty()) { | ||
planAggregate(expressionsToAggregate, expressionsToGroupBy, plan); | ||
} | ||
if (projectionBody.hasOrderByExpressions()) { | ||
planOrderBy(expressionsToProject, projectionBody.getOrderByExpressions(), | ||
projectionBody.getSortingOrders(), plan); | ||
} | ||
appendProjection(expressionsToProject, plan); | ||
if (projectionBody.getIsDistinct()) { | ||
appendDistinct(expressionsToProject, plan); | ||
} | ||
if (projectionBody.hasSkipOrLimit()) { | ||
appendMultiplicityReducer(plan); | ||
if (projectionBody.hasSkip()) { | ||
appendSkip(projectionBody.getSkipNumber(), plan); | ||
} | ||
if (projectionBody.hasLimit()) { | ||
appendLimit(projectionBody.getLimitNumber(), plan); | ||
} | ||
} | ||
} | ||
|
||
void QueryPlanner::planAggregate(const expression_vector& expressionsToAggregate, | ||
const expression_vector& expressionsToGroupBy, LogicalPlan& plan) { | ||
assert(!expressionsToAggregate.empty()); | ||
expression_vector expressionsToProject; | ||
for (auto& expressionToAggregate : expressionsToAggregate) { | ||
if (ExpressionChildrenCollector::collectChildren(*expressionToAggregate) | ||
.empty()) { // skip COUNT(*) | ||
continue; | ||
} | ||
expressionsToProject.push_back(expressionToAggregate->getChild(0)); | ||
} | ||
for (auto& expressionToGroupBy : expressionsToGroupBy) { | ||
expressionsToProject.push_back(expressionToGroupBy); | ||
} | ||
appendProjection(expressionsToProject, plan); | ||
appendAggregate(expressionsToGroupBy, expressionsToAggregate, plan); | ||
} | ||
|
||
void QueryPlanner::planOrderBy(const binder::expression_vector& expressionsToProject, | ||
const binder::expression_vector& expressionsToOrderBy, const std::vector<bool>& isAscOrders, | ||
kuzu::planner::LogicalPlan& plan) { | ||
auto expressionsToProjectBeforeOrderBy = expressionsToProject; | ||
auto expressionsToProjectSet = | ||
expression_set{expressionsToProject.begin(), expressionsToProject.end()}; | ||
for (auto& expression : expressionsToOrderBy) { | ||
if (!expressionsToProjectSet.contains(expression)) { | ||
expressionsToProjectBeforeOrderBy.push_back(expression); | ||
} | ||
} | ||
appendProjection(expressionsToProjectBeforeOrderBy, plan); | ||
appendOrderBy(expressionsToOrderBy, isAscOrders, plan); | ||
} | ||
|
||
} // namespace planner | ||
} // namespace kuzu |
Oops, something went wrong.