为 BusTub 添加新的运算符执行器和查询优化。BusTub 使用迭代查询处理模型(火山模型),其中每个执行器都实现了一个 Next 函数,用于获取下一个元组结果。当 DBMS 调用执行器的 Next 函数时,执行器会返回 (1) 一个元组或 (2) 一个没有更多元组的指示符。通过这种方法,每个执行器都实现了一个循环,不断调用其子执行器的 Next 来检索元组并逐个处理。 在 BusTub 的迭代器模型实现中,每个执行器的 Next 函数除了返回一个元组外,还会返回一个记录标识符(RID)。记录标识符是元组的唯一标识符。 目录的全部实现都在 src/include/catalog/catalog.h 中。注意成员函数 Catalog::GetTable() 和 Catalog::GetIndex()。在执行器的实现中使用这些函数来查询目录中的表和索引。 对于表修改执行程序(InsertExecutor、UpdateExecutor 和 DeleteExecutor),必须修改操作目标表的所有索引。Catalog::GetTableIndexes() 函数在查询为特定表定义的所有索引时非常有用。一旦获得表中每个索引的 IndexInfo 实例,就可以在底层索引结构上调用索引修改操作。 BusTub 优化器是一种基于规则的优化器。大多数优化器规则以自下而上的方式构建优化计划。由于查询计划具有树形结构,因此在对当前计划节点应用优化器规则之前,首先要对其子节点递归应用规则。 在每个计划节点上,应确定源计划结构是否与要优化的计划结构相匹配,然后检查该计划中的属性,看是否能优化为目标优化计划结构。
/**
* Execute a query plan.
* @param plan The query plan to execute
* @param result_set The set of tuples produced by executing the plan
* @param txn The transaction context in which the query executes
* @param exec_ctx The executor context in which the query executes
* @return `true` if execution of the query plan succeeds, `false` otherwise
*/// NOLINTNEXTLINEautoExecute(const AbstractPlanNodeRef &plan, std::vector<Tuple>*result_set, Transaction *txn,
ExecutorContext *exec_ctx)->bool{BUSTUB_ASSERT((txn == exec_ctx->GetTransaction()),"Broken Invariant");// Construct the executor for the abstract plan nodeauto executor =ExecutorFactory::CreateExecutor(exec_ctx, plan);// Initialize the executorauto executor_succeeded =true;try{
executor->Init();PollExecutor(executor.get(), plan, result_set);PerformChecks(exec_ctx);}catch(const ExecutionException &ex){
executor_succeeded =false;if(result_set !=nullptr){
result_set->clear();}}return executor_succeeded;}