背景
题目要求:
update 单个字段即可。 可以参考 insert_record 和 delete_record 的实现。目前能支持 update 的语法解析,但是不能执行。需要考虑带条件查询的更新,和不带条件的更新。
测例:
1update t set age =100 where id=2;2update set age=20 where id>100;insert_record 代码分析
insert_record 是实现 insert 语句的核心代码,其调用链为:handle_request ==> do_insert ==> table->insert_record
insert_record(trx, value_num, values) 的流程:
- 检查输入参数是否合法
- 调用
make_record创建记录数据 record - 调用
insert_record(trx, record)执行插入
trx 是一个与事务相关的类,暂且这里先忽略不看(当成 nullptr 即可)
忽略掉 trx 相关的代码后,insert_record(trx, record) 主要还是调用 record_handler_->insert_record 插入记录,并嗲用 insert_entry_of_indexes 更新索引上的记录。
delete_record 代码分析
delete_record 是实现 delete 语句的核心代码,其调用链为 `handle_request ==> do_delete ==> DeleteOperator:: open ==> table->delete_record
handle_request 中相关的代码与 insert_record 的类似,但是在 do_delete 中,其核心代码如下:
1DeleteStmt *delete_stmt = (DeleteStmt *)stmt;2TableScanOperator scan_oper(delete_stmt->table());3PredicateOperator pred_oper(delete_stmt->filter_stmt());4pred_oper.add_child(&scan_oper);5DeleteOperator delete_oper(delete_stmt);6delete_oper.add_child(&pred_oper);7
8RC rc = delete_oper.open();看起来是miniob里面有一套 Operator机制来实现逻辑复用。不同的 Operator 应该被构造成一个树的结构。当前do_delete构造的结构为:DeleteOperator -> PredicateOperator -> ScanOperator,执行顺序应该刚好反过来,从树的叶子节点不断往上执行。
这里分别略看一下三个 Operator 的实现:
ScanOperator:扫描记录open:初始化recod_scannernext:设置current_record_close:关闭record_scanner
PredicateOperator:对记录进行过滤open:调用children的open函数next:调用children的next函数,并进行过滤,直到有一个满足条件的记录才返回close:调用children的close函数
DeleteOperator:删除记录open:- 调用
children的open函数 - 循环调用
children的next函数,并调用table->delete_record进行删除
- 调用
next和close:空实现
==从上面可以知道,利用 ScanOperator 和 PredicateOperator 可以实现条件过滤找出想要的记录==
table->delete_record的实现,如果忽略trx的话,就是简单调用delete_entry_of_indexes和record_handler_->delete_record函数。
delete_entry_of_indexes:对每个index嗲用delete_entryrecord_handler_->delete_record- 初始化
RecordPageHandler - 调用
delete_record函数 - 成功后将该也加入
free_pages_
- 初始化
实现的大致思路
首先肯定是把handle_request里面的do_update打开,如果这时候你跑一下代码,会发现其实走不到do_update函数里面去,因为前面CreateStmt里面没有正确调用UpdateStmt,而且UpdateStmt的代码也没有实现。这个的实现没有特别要注意的,照着其他的写就好了。
然后到了do_update的具体实现,按照前面delete_record的做法,我们先仿照DeleteOperator实现一个UpdateOperator,然后
可以先仿照DeleteOperator实现一个UpdateOperator,只是把table->delete_record函数更换成table->update_record。
update_record 步骤:
- 首先根据
attribute_name找到对应的field - 检查类型是否与输入的一致
- 修改
record中对应field内容 - 调用
record_hanlder->update_record完成更新
MR链接:update by wuxiaobai24 · Pull Request #2 · wuxiaobai24/miniob · GitHub