update 语句的解析实例

update 语句的解析中,SRA_T *where,首先是调用了SRATABLE()函数进行创建,这个SRATABLE代表的是关系中的所有元组。之后我们解析 update 的 where 子句,如果解析到where 子句,则调用 SRASELECT() ,传入一个SRATABLE,创建一个选择关系。

所以SRA列表(逻辑查询计划)的结构是这样的:

        SRASELECT(对应选择)
            |
        SRATABLE(对应整个关系)

当向physical_scan_generate函数传入sra参数之后,首先递归获取SRA列表的下一层,也就是SRATABLE,然后递归调用physical_scan_generate函数,创建了一个全表扫描的扫描器physical_scan_table。然后再次调用physical_scan_select_create 函数创建一个选择关系的扫描器physical_scan_select。

所以物理查询计划树的结构是这样的:

    physical_scan_select
            |
    physical_scan_table

再然后调用scan->beforeFirst(scan)函数,这里的beforeFirst函数调用的是physical_scan_select的函数,这个函数首先获取物理扫描树的下一层,也就是physical_scan_table,然后调用下一层的beforeFirst函数,physical_scan_table的beforFirst函数主要是将要读取的位置移动到记录的第一条上。这也就是表扫描进行前的初始任务。

接下来我们调用 scan->next(scan) 函数,因为这里的scan是physical_scan_select,即选择关系的扫描,physical_scan_select中的next()函数首先会获得下一层的扫描,即physical_scan_table,之后判断当前记录是否满足select选择关系,如果满足,就返回1,否则就扫描下一条,再次进行判断;如果没有满足条件的记录,就返回0,表示扫描完成。

然后使用 physical_scan_evaluate_expression 计算字段表达式的值,如果是整数,则调用setInt来修改记录;如果是字符串,则调用setString来修改记录。

这里调用的setInt和setString函数都是physical_scan_select中的函数,它们首先获得下一层中的扫描,也就是 physical_scan_table,然后在 physical_scan_table 中的setInt直接写入到记录中,修改内存中的记录,提交事务之后,将内存中的修改写会到硬盘上,完成记录的修改。

最后关系扫描scan->close(scan),仍旧是获得下一层的扫描,即 physical_scan_table 的close函数,这个函数关闭记录文件,然后完成关闭操作。

整个update语句的执行也就结束了