Skip to content

Commit 78c8f61

Browse files
authored
feat(p3): Add top N and optimizer rule (#434)
Add sort, topN
1 parent a9e80b8 commit 78c8f61

File tree

7 files changed

+43
-6
lines changed

7 files changed

+43
-6
lines changed

src/execution/fmt_impl.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#include <type_traits>
2-
#include "execution/plans/sort_plan.h"
32
#include "fmt/format.h"
43
#include "fmt/ranges.h"
54

65
#include "common/util/string_util.h"
76
#include "execution/expressions/abstract_expression.h"
87
#include "execution/plans/abstract_plan.h"
98
#include "execution/plans/aggregation_plan.h"
9+
#include "execution/plans/limit_plan.h"
1010
#include "execution/plans/projection_plan.h"
11+
#include "execution/plans/sort_plan.h"
12+
#include "execution/plans/topn_plan.h"
1113

1214
namespace bustub {
1315

@@ -40,4 +42,10 @@ auto SortPlanNode::PlanNodeToString() const -> std::string {
4042
return fmt::format("Sort {{ order_bys={} }}", order_bys_);
4143
}
4244

45+
auto LimitPlanNode::PlanNodeToString() const -> std::string { return fmt::format("Limit {{ limit={} }}", limit_); }
46+
47+
auto TopNPlanNode::PlanNodeToString() const -> std::string {
48+
return fmt::format("TopN {{ n={}, order_bys={}}}", n_, order_bys_);
49+
}
50+
4351
} // namespace bustub

src/include/execution/plans/limit_plan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class LimitPlanNode : public AbstractPlanNode {
4848
BUSTUB_PLAN_NODE_CLONE_WITH_CHILDREN(LimitPlanNode);
4949

5050
protected:
51-
auto PlanNodeToString() const -> std::string override { return fmt::format("Limit {{ limit={} }}", limit_); }
51+
auto PlanNodeToString() const -> std::string override;
5252

5353
private:
5454
/** The limit */

src/include/execution/plans/topn_plan.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
#include <memory>
1616
#include <string>
1717
#include <utility>
18+
#include <vector>
1819

20+
#include "binder/bound_order_by.h"
1921
#include "catalog/catalog.h"
2022
#include "execution/expressions/abstract_expression.h"
2123
#include "execution/plans/abstract_plan.h"
@@ -33,11 +35,19 @@ class TopNPlanNode : public AbstractPlanNode {
3335
* @param output The output schema of this topN plan node
3436
* @param child The child plan node
3537
*/
36-
TopNPlanNode(SchemaRef output, AbstractPlanNodeRef child) : AbstractPlanNode(std::move(output), {std::move(child)}) {}
38+
TopNPlanNode(SchemaRef output, AbstractPlanNodeRef child,
39+
std::vector<std::pair<OrderByType, AbstractExpressionRef>> order_bys, std::size_t n)
40+
: AbstractPlanNode(std::move(output), {std::move(child)}), order_bys_(std::move(order_bys)), n_{n} {}
3741

3842
/** @return The type of the plan node */
3943
auto GetType() const -> PlanType override { return PlanType::TopN; }
4044

45+
/** @return The N (limit) */
46+
auto GetN() const -> size_t { return n_; }
47+
48+
/** @return Get order by expressions */
49+
auto GetOrderBy() const -> const std::vector<std::pair<OrderByType, AbstractExpressionRef>> & { return order_bys_; }
50+
4151
/** @return The child plan node */
4252
auto GetChildPlan() const -> AbstractPlanNodeRef {
4353
BUSTUB_ASSERT(GetChildren().size() == 1, "TopN should have exactly one child plan.");
@@ -47,9 +57,11 @@ class TopNPlanNode : public AbstractPlanNode {
4757
BUSTUB_PLAN_NODE_CLONE_WITH_CHILDREN(TopNPlanNode);
4858

4959
protected:
50-
auto PlanNodeToString() const -> std::string override { return fmt::format("TopN {{ }}"); }
60+
auto PlanNodeToString() const -> std::string override;
5161

5262
private:
63+
std::vector<std::pair<OrderByType, AbstractExpressionRef>> order_bys_;
64+
std::size_t n_;
5365
};
5466

5567
} // namespace bustub

src/include/optimizer/optimizer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ class Optimizer {
7474
auto MatchIndex(const std::string &table_name, uint32_t index_key_idx)
7575
-> std::optional<std::tuple<index_oid_t, std::string>>;
7676

77+
/**
78+
* @brief optimize sort + limit as top N
79+
*/
80+
auto OptimizeSortLimitAsTopN(const AbstractPlanNodeRef &plan) -> AbstractPlanNodeRef;
81+
7782
/** Catalog will be used during the planning process. USERS SHOULD ENSURE IT OUTLIVES
7883
* OPTIMIZER, otherwise it's a dangling reference.
7984
*/

src/optimizer/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ add_library(
66
nlj_as_hash_join.cpp
77
nlj_as_index_join.cpp
88
optimizer.cpp
9-
order_by_index_scan.cpp)
9+
order_by_index_scan.cpp
10+
sort_limit_as_topn.cpp)
1011

1112
set(ALL_OBJECT_FILES
1213
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:bustub_optimizer>

src/optimizer/optimizer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ auto Optimizer::Optimize(const AbstractPlanNodeRef &plan) -> AbstractPlanNodeRef
99
auto p3 = OptimizeNLJAsIndexJoin(p2);
1010
auto p4 = OptimizeNLJAsHashJoin(p3);
1111
auto p5 = OptimizeOrderByAsIndexScan(p4);
12-
return p5;
12+
auto p6 = OptimizeSortLimitAsTopN(p5);
13+
return p6;
1314
}
1415

1516
} // namespace bustub

src/optimizer/sort_limit_as_topn.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include "optimizer/optimizer.h"
2+
3+
namespace bustub {
4+
5+
auto Optimizer::OptimizeSortLimitAsTopN(const AbstractPlanNodeRef &plan) -> AbstractPlanNodeRef {
6+
// TODO(student): implement sort + limit -> top N optimizer rule
7+
return plan;
8+
}
9+
10+
} // namespace bustub

0 commit comments

Comments
 (0)