Skip to content

Commit

Permalink
123
Browse files Browse the repository at this point in the history
  • Loading branch information
bilibilifaker committed Mar 28, 2024
1 parent 325775a commit 62ff1b2
Show file tree
Hide file tree
Showing 226 changed files with 6,438 additions and 7,280 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set(BUSTUB_LIBS
bustub_execution
bustub_recovery
bustub_type
bustub_container_hash
bustub_container_disk_hash
bustub_storage_disk
bustub_storage_index
Expand Down
90 changes: 4 additions & 86 deletions src/binder/bind_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
#include "fmt/ranges.h"
#include "nodes/nodes.hpp"
#include "nodes/primnodes.hpp"
#include "nodes/value.hpp"
#include "pg_definitions.hpp"
#include "postgres_parser.hpp"
#include "type/type_id.h"
Expand All @@ -69,14 +68,6 @@ auto Binder::BindColumnDefinition(duckdb_libpgquery::PGColumnDef *cdef) -> Colum
return {colname, TypeId::INTEGER};
}

if (name == "double") {
return {colname, TypeId::DECIMAL};
}

if (name == "bool") {
return {colname, TypeId::BOOLEAN};
}

if (name == "varchar") {
auto exprs = BindExpressionList(cdef->typeName->typmods);
if (exprs.size() != 1) {
Expand All @@ -87,24 +78,13 @@ auto Binder::BindColumnDefinition(duckdb_libpgquery::PGColumnDef *cdef) -> Colum
return {colname, TypeId::VARCHAR, varchar_max_length};
}

if (name == "vector") {
auto exprs = BindExpressionList(cdef->typeName->typmods);
if (exprs.size() != 1) {
throw bustub::Exception("should specify vector length");
}
const auto &vector_length_val = dynamic_cast<const BoundConstant &>(*exprs[0]);
uint32_t vector_length = std::stoi(vector_length_val.ToString());
return {colname, TypeId::VECTOR, vector_length};
}

throw NotImplementedException(fmt::format("unsupported type: {}", name));
}

auto Binder::BindCreate(duckdb_libpgquery::PGCreateStmt *pg_stmt) -> std::unique_ptr<CreateStatement> {
auto table = std::string(pg_stmt->relation->relname);
auto columns = std::vector<Column>{};
size_t column_count = 0;
std::vector<std::string> pk;

for (auto c = pg_stmt->tableElts->head; c != nullptr; c = lnext(c)) {
auto node = reinterpret_cast<duckdb_libpgquery::PGNode *>(c->data.ptr_value);
Expand All @@ -113,44 +93,14 @@ auto Binder::BindCreate(duckdb_libpgquery::PGCreateStmt *pg_stmt) -> std::unique
auto cdef = reinterpret_cast<duckdb_libpgquery::PGColumnDef *>(c->data.ptr_value);
auto centry = BindColumnDefinition(cdef);
if (cdef->constraints != nullptr) {
for (auto constr = cdef->constraints->head; constr != nullptr; constr = constr->next) {
auto constraint = reinterpret_cast<duckdb_libpgquery::PGConstraint *>(constr->data.ptr_value);
switch (constraint->contype) {
case duckdb_libpgquery::PG_CONSTR_PRIMARY: {
if (!pk.empty()) {
throw NotImplementedException("cannot have two primary keys");
}
pk = {centry.GetName()};
break;
}
default:
throw NotImplementedException("unsupported constraint");
}
}
throw NotImplementedException("constraints not supported");
}
columns.push_back(std::move(centry));
column_count++;
break;
}
case duckdb_libpgquery::T_PGConstraint: {
for (auto con = c; con != nullptr; con = con->next) {
auto constraint = reinterpret_cast<duckdb_libpgquery::PGConstraint *>(con->data.ptr_value);
switch (constraint->contype) {
case duckdb_libpgquery::PG_CONSTR_PRIMARY: {
std::vector<std::string> columns;
for (auto kc = constraint->keys->head; kc != nullptr; kc = kc->next) {
columns.emplace_back(reinterpret_cast<duckdb_libpgquery::PGValue *>(kc->data.ptr_value)->val.str);
}
if (!pk.empty()) {
throw NotImplementedException("cannot have two primary keys");
}
pk = std::move(columns);
break;
}
default:
throw NotImplementedException("unsupported constraint");
}
}
throw NotImplementedException("constraints not supported");
break;
}
default:
Expand All @@ -162,56 +112,24 @@ auto Binder::BindCreate(duckdb_libpgquery::PGCreateStmt *pg_stmt) -> std::unique
throw bustub::Exception("should have at least 1 column");
}

return std::make_unique<CreateStatement>(std::move(table), std::move(columns), std::move(pk));
return std::make_unique<CreateStatement>(std::move(table), std::move(columns));
}

auto Binder::BindIndex(duckdb_libpgquery::PGIndexStmt *stmt) -> std::unique_ptr<IndexStatement> {
std::vector<std::unique_ptr<BoundColumnRef>> cols;
std::vector<std::string> col_options;
auto table = BindBaseTableRef(stmt->relation->relname, std::nullopt);

for (auto cell = stmt->indexParams->head; cell != nullptr; cell = cell->next) {
auto index_element = reinterpret_cast<duckdb_libpgquery::PGIndexElem *>(cell->data.ptr_value);
if (index_element->name != nullptr) {
auto column_ref = ResolveColumn(*table, std::vector{std::string(index_element->name)});
cols.emplace_back(std::make_unique<BoundColumnRef>(dynamic_cast<const BoundColumnRef &>(*column_ref)));
std::string opt;
if (index_element->opclass != nullptr) {
for (auto c = index_element->opclass->head; c != nullptr; c = lnext(c)) {
opt = reinterpret_cast<duckdb_libpgquery::PGValue *>(c->data.ptr_value)->val.str;
break;
}
}
col_options.emplace_back(opt);
} else {
throw NotImplementedException("create index by expr is not supported yet");
}
}

std::string index_type;

if (stmt->accessMethod != nullptr) {
index_type = stmt->accessMethod;
if (index_type == "art") {
index_type = "";
}
}

std::vector<std::pair<std::string, int>> options;

if (stmt->options != nullptr) {
for (auto c = stmt->options->head; c != nullptr; c = lnext(c)) {
auto def_elem = reinterpret_cast<duckdb_libpgquery::PGDefElem *>(c->data.ptr_value);
int val;
if (def_elem->arg != nullptr) {
val = reinterpret_cast<duckdb_libpgquery::PGValue *>(def_elem->arg)->val.ival;
}
options.emplace_back(def_elem->defname, val);
}
}

return std::make_unique<IndexStatement>(stmt->idxname, std::move(table), std::move(cols), std::move(index_type),
std::move(col_options), std::move(options));
return std::make_unique<IndexStatement>(stmt->idxname, std::move(table), std::move(cols));
}

} // namespace bustub
66 changes: 4 additions & 62 deletions src/binder/bind_select.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include <iterator>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "binder/binder.h"
#include "binder/bound_expression.h"
Expand All @@ -14,10 +13,8 @@
#include "binder/expressions/bound_binary_op.h"
#include "binder/expressions/bound_column_ref.h"
#include "binder/expressions/bound_constant.h"
#include "binder/expressions/bound_func_call.h"
#include "binder/expressions/bound_star.h"
#include "binder/expressions/bound_unary_op.h"
#include "binder/expressions/bound_window.h"
#include "binder/statement/explain_statement.h"
#include "binder/statement/select_statement.h"
#include "binder/table_ref/bound_base_table_ref.h"
Expand Down Expand Up @@ -405,8 +402,6 @@ auto Binder::BindSelectList(duckdb_libpgquery::PGList *list) -> std::vector<std:
std::vector<std::unique_ptr<BoundExpression>> exprs;
auto select_list = std::vector<std::unique_ptr<BoundExpression>>{};
bool is_select_star = false;
bool has_agg = false;
bool has_window_agg = false;

for (auto node = list->head; node != nullptr; node = lnext(node)) {
auto target = reinterpret_cast<duckdb_libpgquery::PGNode *>(node->data.ptr_value);
Expand All @@ -424,20 +419,10 @@ auto Binder::BindSelectList(duckdb_libpgquery::PGList *list) -> std::vector<std:
if (is_select_star) {
throw bustub::Exception("select * cannot have other expressions in list");
}
if (expr->HasAggregation()) {
has_agg = true;
}
if (expr->HasWindowFunction()) {
has_window_agg = true;
}
select_list.push_back(std::move(expr));
}
}

if (has_agg && has_window_agg) {
throw bustub::Exception("cannot have both normal agg and window agg in same query");
}

return select_list;
}

Expand Down Expand Up @@ -468,10 +453,6 @@ auto Binder::BindConstant(duckdb_libpgquery::PGAConst *node) -> std::unique_ptr<
BUSTUB_ENSURE(val.val.ival <= BUSTUB_INT32_MAX, "value out of range");
return std::make_unique<BoundConstant>(ValueFactory::GetIntegerValue(static_cast<int32_t>(val.val.ival)));
}
case duckdb_libpgquery::T_PGFloat: {
double parsed_val = std::stod(std::string(val.val.str));
return std::make_unique<BoundConstant>(ValueFactory::GetDecimalValue(parsed_val));
}
case duckdb_libpgquery::T_PGString: {
return std::make_unique<BoundConstant>(ValueFactory::GetVarcharValue(val.val.str));
}
Expand Down Expand Up @@ -526,34 +507,6 @@ auto Binder::BindStar(duckdb_libpgquery::PGAStar *node) -> std::unique_ptr<Bound
return std::make_unique<BoundStar>();
}

auto Binder::BindWindowExpression(std::string func_name, std::vector<std::unique_ptr<BoundExpression>> children,
duckdb_libpgquery::PGWindowDef *node) -> std::unique_ptr<BoundWindow> {
BUSTUB_ASSERT(node, "nullptr");
auto partition_by = std::vector<std::unique_ptr<BoundExpression>>{};
if (node->partitionClause != nullptr) {
partition_by = BindExpressionList(node->partitionClause);
}

auto sort = std::vector<std::unique_ptr<BoundOrderBy>>{};
if (node->orderClause != nullptr) {
sort = BindSort(node->orderClause);
}

std::optional<std::unique_ptr<BoundExpression>> start_offset;
if (node->startOffset != nullptr) {
start_offset = std::make_optional(BindExpression(node->startOffset));
}
std::optional<std::unique_ptr<BoundExpression>> end_offset;
if (node->endOffset != nullptr) {
end_offset = std::make_optional(BindExpression(node->endOffset));
}

auto window = std::make_unique<BoundWindow>(std::move(func_name), std::move(children), std::move(partition_by),
std::move(sort), std::move(start_offset), std::move(end_offset));
window = BindWindowFrame(node, std::move(window));
return window;
}

auto Binder::BindFuncCall(duckdb_libpgquery::PGFuncCall *root) -> std::unique_ptr<BoundExpression> {
BUSTUB_ASSERT(root, "nullptr");
auto name = root->funcname;
Expand All @@ -569,27 +522,16 @@ auto Binder::BindFuncCall(duckdb_libpgquery::PGFuncCall *root) -> std::unique_pt
}

if (function_name == "min" || function_name == "max" || function_name == "first" || function_name == "last" ||
function_name == "sum" || function_name == "count" || function_name == "rank" || function_name == "row_number") {
// Rewrite row_number()/count(*) to count_star().
if ((function_name == "count" && children.empty()) || function_name == "row_number") {
function_name == "sum" || function_name == "count") {
// Rewrite count(*) to count_star().
if (function_name == "count" && children.empty()) {
function_name = "count_star";
}

if (root->over != nullptr) {
if (root->agg_distinct) {
throw bustub::Exception("DISTINCT is not supported in window functions");
}

auto window = BindWindowExpression(function_name, std::move(children), root->over);
return window;
}

// Bind function as agg call.
return std::make_unique<BoundAggCall>(function_name, root->agg_distinct, std::move(children));
}

// In other cases, bind as func call.
return std::make_unique<BoundFuncCall>(function_name, std::move(children));
throw bustub::Exception(fmt::format("unsupported func call {}", function_name));
}

/**
Expand Down
14 changes: 0 additions & 14 deletions src/binder/bind_variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "binder/expressions/bound_constant.h"
#include "binder/statement/set_show_statement.h"
#include "common/exception.h"
#include "nodes/parsenodes.hpp"
namespace bustub {

auto Binder::BindVariableSet(duckdb_libpgquery::PGVariableSetStmt *stmt) -> std::unique_ptr<VariableSetStatement> {
Expand All @@ -24,17 +23,4 @@ auto Binder::BindVariableShow(duckdb_libpgquery::PGVariableShowStmt *stmt) -> st
return std::make_unique<VariableShowStatement>(stmt->name);
}

auto Binder::BindTransaction(duckdb_libpgquery::PGTransactionStmt *stmt) -> std::unique_ptr<TransactionStatement> {
switch (stmt->kind) {
case duckdb_libpgquery::PG_TRANS_STMT_COMMIT:
return std::make_unique<TransactionStatement>("commit");
case duckdb_libpgquery::PG_TRANS_STMT_ROLLBACK:
return std::make_unique<TransactionStatement>("abort");
case duckdb_libpgquery::PG_TRANS_STMT_BEGIN:
return std::make_unique<TransactionStatement>("begin");
default:
throw bustub::NotImplementedException("unsupported txn statement kind");
}
}

} // namespace bustub
37 changes: 0 additions & 37 deletions src/binder/fmt_impl.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
#include "binder/binder.h"
#include "binder/bound_expression.h"
#include "binder/bound_order_by.h"
#include "binder/expressions/bound_agg_call.h"
#include "binder/expressions/bound_constant.h"
#include "binder/expressions/bound_func_call.h"
#include "binder/expressions/bound_window.h"
#include "binder/statement/select_statement.h"
#include "binder/table_ref/bound_cte_ref.h"
#include "binder/table_ref/bound_expression_list_ref.h"
Expand All @@ -15,8 +10,6 @@

namespace bustub {

auto BoundFuncCall::ToString() const -> std::string { return fmt::format("{}({})", func_name_, args_); }

auto BoundAggCall::ToString() const -> std::string {
if (is_distinct_) {
return fmt::format("{}_distinct({})", func_name_, args_);
Expand All @@ -41,34 +34,4 @@ auto BoundSubqueryRef::ToString() const -> std::string {
StringUtil::IndentAllLines(subquery_->ToString(), 2, true), columns);
}

auto BoundWindow::ToString() const -> std::string {
std::vector<std::string> partition_by;
for (const auto &expr : partition_by_) {
partition_by.push_back(expr->ToString());
}

std::vector<std::string> order_bys;
for (const auto &expr : order_bys_) {
order_bys.push_back(expr->ToString());
}

std::string start_offset = "None";
if (start_offset_.has_value()) {
start_offset = (*start_offset_)->ToString();
}

std::string end_offset = "None";
if (end_offset_.has_value()) {
end_offset = (*end_offset_)->ToString();
}

std::string start_mode = Binder::WindowBoundaryToString(start_);
std::string end_mode = Binder::WindowBoundaryToString(end_);

// TODO(avery): add frame
return fmt::format("{}({}) Over {{ partition_by={}, order_by={} }}", func_name_, args_,
StringUtil::IndentAllLines(fmt::format("[{}]", fmt::join(partition_by, ", ")), 2, true),
StringUtil::IndentAllLines(fmt::format("[{}]", fmt::join(order_bys, ", ")), 2, true));
}

} // namespace bustub
Loading

0 comments on commit 62ff1b2

Please sign in to comment.