Code & Func

Update 实现

2022-10-15
miniob
database
源码
最后更新:2024-09-19
4分钟
728字

背景

题目要求:

update 单个字段即可。 可以参考 insert_record 和 delete_record 的实现。目前能支持 update 的语法解析,但是不能执行。需要考虑带条件查询的更新,和不带条件的更新。

测例:

1
update t set age =100 where id=2;
2
update 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 中,其核心代码如下:

1
DeleteStmt *delete_stmt = (DeleteStmt *)stmt;
2
TableScanOperator scan_oper(delete_stmt->table());
3
PredicateOperator pred_oper(delete_stmt->filter_stmt());
4
pred_oper.add_child(&scan_oper);
5
DeleteOperator delete_oper(delete_stmt);
6
delete_oper.add_child(&pred_oper);
7
8
RC rc = delete_oper.open();

看起来是miniob里面有一套 Operator机制来实现逻辑复用。不同的 Operator 应该被构造成一个树的结构。当前do_delete构造的结构为:DeleteOperator -> PredicateOperator -> ScanOperator,执行顺序应该刚好反过来,从树的叶子节点不断往上执行。

这里分别略看一下三个 Operator 的实现:

  • ScanOperator:扫描记录
    • open:初始化recod_scanner
    • next:设置current_record_
    • close:关闭record_scanner
  • PredicateOperator:对记录进行过滤
    • open:调用childrenopen函数
    • next:调用childrennext函数,并进行过滤,直到有一个满足条件的记录才返回
    • close:调用childrenclose函数
  • DeleteOperator:删除记录
    • open
      • 调用childrenopen函数
      • 循环调用childrennext函数,并调用table->delete_record进行删除
    • nextclose:空实现

==从上面可以知道,利用 ScanOperator 和 PredicateOperator 可以实现条件过滤找出想要的记录==

table->delete_record的实现,如果忽略trx的话,就是简单调用delete_entry_of_indexesrecord_handler_->delete_record函数。

  • delete_entry_of_indexes:对每个index嗲用delete_entry
  • record_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 步骤:

  1. 首先根据attribute_name找到对应的field
  2. 检查类型是否与输入的一致
  3. 修改record中对应field 内容
  4. 调用record_hanlder->update_record完成更新

MR链接:update by wuxiaobai24 · Pull Request #2 · wuxiaobai24/miniob · GitHub

本文标题:Update 实现
文章作者:wuxiaobai24
发布时间:2022-10-15