CMU数据库(15-445)Lab3- QUERY EXECUTION (3)

这里注意插入的时候我们value是直接从子计划获得的result_set中获取

bool inserted = table_info->table_->InsertTuple(*result_set.begin(), rid, exec_ctx_->GetTransaction()); BUSTUB_ASSERT(inserted, "Sequential insertion cannot fail"); for (auto index : table_Indexs) { index->index_->InsertEntry(*result_set.begin(), *rid, exec_ctx_->GetTransaction()); } result_set.erase(result_set.begin()); return true; UPDATE

Update修改指定表中的现有元组并更新其索引。UpdatePlanNode可以利用SeqScanPlanNode或IndexScanPlanNode来提供进行更新的目标元组如

先向empty_table2表中插入数据

然后修改colA的值

INSERT INTO empty_table2 SELECT colA, colA FROM test_1 WHERE colA < 50 UPDATE empty_table2 SET colA = colA+10 WHERE colA < 50 实现

这里也是附上比较重要的next函数实现

bool UpdateExecutor::Next([[maybe_unused]] Tuple *tuple, RID *rid) { if (child_executor_->Next(tuple, rid)) { *tuple = GenerateUpdatedTuple(*tuple); return table_info_->table_.get()->UpdateTuple(*tuple, *rid, txn); } return false; } Delete

delete的逻辑都是非常简单的。就是找到满足要求的tuple,然后将其删除。这里还要注意出了删除tuple还要删除对应的index

实现 std::vector<RID> rids; index->index_->ScanKey(key, &rids, txn); table_info_->table_->MarkDelete(rids[0], txn); index->index_->DeleteEntry(key, key.GetRid(), txn); JOIN

join操作用于将两个子执行语句的结果组合在一起。在这个任务中你需要实现两种形式的join操作一种是基本的join另外一种是基于索引的join操作

实现 1. 基本join操作

这个实现非常简单,就是二重循环。对于外查询中的每一个元素在内表中进行遍历看一下是否有相等的。

SELECT test_1.colA, test_1.colB, test_2.col1, test_2.col3 FROM test_1 JOIN test_2 ON test_1.colA = test_2.col1 AND test_1.colA < 50

比如对于上面这个语句。我们要先把后面的select语句执行完。然后就是一个二重循环

const Schema *left_schema = left_executor_->GetOutputSchema(); const Schema *right_schema = right_executor_->GetOutputSchema(); for (const auto &p1 : left_tuples) { for (const auto &p2 : right_tuples) { Tuple left_tuple = p1; Tuple right_tuple = p2; if (plan_->Predicate()->EvaluateJoin(&left_tuple, left_schema, &right_tuple, right_schema).GetAs<bool>()) { std::vector<Value> left_values = getValuesFromTuple(&left_tuple, left_schema); std::vector<Value> right_values = getValuesFromTuple(&right_tuple, right_schema); left_values.insert(left_values.end(), right_values.begin(), right_values.end()); res.emplace_back(left_values, plan_->OutputSchema()); } } } 2. 利用index的join操作

主要有两个注意点。获得key_tuple和在index中利用key_tuple找到rid

Tuple key_tuple = outer_tuple.KeyFromTuple(*outer_table_schema, *index_key_schema, inner_index_->index_->GetKeyAttrs()); inner_index_->index_->ScanKey(key_tuple, &rids, exec_ctx_->GetTransaction());

别的基本逻辑和上面的类似了不能贴太多代码啊。

AGGREGATION

聚合用于将来自单个子执行器的多个元组结果组合为单个元组。在这个项目中,我们要求您实现COUNT、SUM、MIN和MAX。

我们为您提供了一个SimpleAggregationHashTable。我们强烈建议您使用这个哈希表。

实现

SimpleAggregationHashTable这个hash表提供了一系列操作。下面我们依次来看一下。

1.为聚合操作提供不同的初始值

可以发现这个函数为count和sum操作提供的初始值为0。而为求最小值操作提供的初始值是32位的最大值。max函数则提供了32位的最小值。这都是符合我们思维的

CMU数据库(15-445)Lab3- QUERY EXECUTION

2. 这个函数主要是为了构建一个迭代器方便后面的having group by操作

CMU数据库(15-445)Lab3- QUERY EXECUTION

3. 帮你实现聚合操作的函数

CMU数据库(15-445)Lab3- QUERY EXECUTION

注意这里的hash表。就是groupby操作用的

std::unordered_map<AggregateKey, AggregateValue> ht{};

它的key就是group by操作的列。这样就可以实现去重操作。嗯设计的真不错

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxjxp.html