一文走进SQL编译-语义解析

一、概述
 sql 引擎主要由三大部分构成:解析器、优化器和执行器。
解析器的主要作用是将客户端传来的命令解析编译成数据库能识别运行的命令,其主要由词法解析、语法解析和语义解析三部分构成,如下图所示。
本文将重点介绍 kaiwudb 语义解析部分,其输入为 ast 语法树,输出为可供优化器使用的 expr 表达式。
kaiwudb 中的语义解析主要包括:
检查数据库或表是否存在
检查语句所需的特定权限
对语句中的表达式进行语义解析
检查 ddl 语句所请求的 schema change 的有效性  
二、语义解析
kaiwudb 中的语义解析主要包括以下流程:
检查查询是否为 sql 语言中的有效语句
解析名称,例如表名或变量名的值
消除不必要的中间计算,例如用 1.0 替换 0.6 + 0.4,这也被称为常数折叠
确定用于中间结果的数据类型
其代码流程介于 parser 和 memo 构建之间,将 parser 输出的 ast 中的对象进行语义解析,语义解析的输出作为 memo 构建的输入。
接下来,将重点介绍查询语句的语义解析流程:  
source and target analysis (目标解析)   
permission check (权限校验)
semantic decomposition & validation (表达式拆分及其语义解析)
1. 目标解析及权限校验
1)接口路径:
buildstmt() -> buildselectstmtwithoutparent() ->  buildselectclause() -> builtfrom() -> builddatasource()
2)核心接口为:
resolvedatasource 通过 object name 解析出对象描述符(元数据),privilege check 使用 current username 来校验当前用户对该对象是否有相应权限。
在完成目标解析和权限校验后,会为 select stmt 中的 from clause 构建 memo 表达式。这个行为看似不是语义解析应该做的,出现在这里的原因是 kaiwudb 的语义解析和部分逻辑计划优化是相互融合的。
2. 表达式拆分及其语义解析
1)接口路径:
buildstmt() -> buildselectstmtwithoutparent() -> buildselectclause()
kaiwudb 将 select stmt 中的各个部分拆分为表达式,并对其进行标量表达式的语义解析,从而完成 scalarexpr 的构建。例如:
2)标量表达式语义解析:
role:检查表达式是否合法,为其做一些初步的优化,为其赋予类型。
interface:
in : expr
out : typedexpr
实质上是检查并赋予类型 + 简化表达式
analyzeexpr()
how:
i. name resolution
ii. typecheck
iii. normalize expr
这些子任务实现几乎是纯粹的函数,唯一的缺陷是, typecheck 将 sql 占位符($1、$2 等)的类型以一种对顺序敏感的方式,输出到通过递归传递的语义环境对象上。
注意:可以使用 explain(exprs, types) 来检查表达式,而不进行解构和简化。
i. name resolution
参数 sources 和 indexedvars,如果都不是 nil,则表示 resolvenames 应该被执行。indexedvars map 将被填充并且作为结果返回。
用 parser.indexedvar 实例替换列名
用 parser.funcdef 引用替换函数名
ii. typecheck
parser.typecheck() / parser.typecheckandrequire():
常数折叠
类型推断
类型检查
在 comparisonexpr 节点上记忆比较器函数
用其类型来注释表达式和占位符
实现 expr 接口的表达式有很多:andexpr, orexpr, castexpr, caseexpr 等。
每个表达式都实现了 typecheck 接口,在被调用时返回结果表达式的类型,包括 bool, string, int 等。
iii. normalize   parser.normalizeexpr():
注意:此处的 normalize 有点不太准确,因为他并没有进行标准的 normalize,这里只是将除变量名以外的东西都放到比较符号的右侧,从而达到简化的目的。
normalize example:
(a+1) < 3 is transformed to a = c and a <= d
normalize 的实现主要依靠 walkexpr 函数。walkexpr 会横穿 expr,其通过传入对应的 visitor 来定义 walkexpr 的具体行为,前面讲到的 name resolution 也是通过传入 name resolution visitor 实现的。


苹果为AirPods更新了新固件,可支持自动切换多设备连接
相对延时和绝对延时区别
富士通实验室在74.7秒内完成了ImageNet上训练ResNet-50网络
微功耗亚超声遥控照明灯电路工作原理
双十一最值得入手的是什么:OPPO Watch 2很给力
一文走进SQL编译-语义解析
手机芯片由什么组成
不到三万的1500W手持激光焊接机价格,物超所值吗?
具备什么属性的细分市场适合区块链
一文搞懂齿轮的前世今生!
等离子清洗机在铝合金/航空连接器/芳纶纤维中的应用
新型柔性太阳能电池:可吸收近红外光
!泰克TDS2024B/TDS2024B/TDS2024B示
OLCD显示技术加入战局,可将LCD显示屏生产线转向柔性OLCD制造
虹科干货|TSN标准——IEEE802.1AS-2020和IEEE802.1AS-2011有哪些不同?
西井科技PowerOnair产品能满足换电重卡场景对续航能力高的需求
人工智能C2B定制化购车模式 让科技宅男梦想成真
又一款金属3D打印火箭发动机 有望在2021年第四季度进行亚轨道发射
物联网爆发期的日益临近,谁又将成为新时代的主角?
海康威视发布零售连锁行业iVMS-8720 v1.1综合管理平台