我们仍旧以update语句为例。上面是根据源代码整理的逻辑,不是源码,主要是为了理清思路。
- 首先是创建一个新的查询update_stmt,并为其生成一个独立的查询标识qid
- 解析语句中的表,并将表的标识tid添加到update_stmt的引用列表
- 利用for循环逐个解析要更新的列-值对:
(1). 根据列名获取列;
(2). 将该列存储到update_stmt的vector中,并将列引用id添加到update_stmt的更新列列表ObArray update_columns_中;
(3). 解析值表达式;
(4). 将值表达式引用id添加到更新值列表ObArrayupdate_exprs_中去; - 解析where子句.
3.2 如何解析表和列?
通过上面我们知道,逻辑计划的解析的一个重要内容就是要确定查询stmt,表,列,表达式的标识.查询和表达式的标识id都可以在解析的时候生成。因为这两项不是线程共有的,但是表和列是持久的数据,可以跨线程使用同样的id。这些表和列的信息由谁来管理?
3.2.1 使用Schema
追根溯源,你会发现实体表和列的id是在ob_schema.cpp中获取的。什么是schema?schema就是数据库对象的一个集合。网上有一个很形象的比喻,我稍微做了点改动:
什么是Database,什么是Schema,什么是Table,什么是列,什么是行,什么是User?我们可以可以把Database看作是一个大仓库,仓库分了很多很多的房间,Schema就是其中的房间,一个Schema代表一个房间,Table可以看作是每个Schema中的柜子,行和列就是柜子中的格子。User就是房间的主人。
OceanBase要求schema强类型约束,也就是要预先定义好schema。这样可以方便的进行各种online ddl操作。
OceanBase的表和列信息存储在Schema的一个hash_map中。关于Schema 以后再深入了解。
四、总结
制定逻辑计划,最关键的是要理解逻辑计划的设计目标,其中最主要的内容就是确定逻辑计划中使用到的查询Stmt,表,列,表达式,并为它们生成或设置唯一标识,确保在同一个逻辑计划中是不相同的。制定逻辑计划的函数只要是reslove系列函数。而表和列的信息存储在Schema中一个hash_map中。
欢迎光临我的网站----我的博客园----我的CSDN。
如果阅读本文过程中有任何问题,请联系作者,转载请注明出处!