ShadingJdbc2.X学习总结系列(四):源码解析—SQL解析
1.解析包整体介绍
1.5.0M1版本以后采用的是自研的解析引擎,支持join、aggregation、order by、group by、limit、or;目前不支持union、部分子查询、函数内分片等不太应在分片场景中出现的SQL解析。
SQL解析引擎在io.shardingjdbc.core.parsing包下,
包含两个组件: Lexer:词法解析器 Parser:SQL解析器
2.Lexer:词法解析器
Lexer:词法解析器:顺序解析 SQL,将字符串拆解成 N 个词法。
核心方法: #nextToken() 方法:不断解析出 Token(词法标记)
#skipIgnoredToken() 方法:跳过忽略的 Token
#isXXXX() 方法:判断下一个 Token 的类型
总结:Lexer#nextToken() 方法里,使用 #skipIgnoredToken() 方法跳过忽略的 Token,通过 #isXXXX() 方法判断下一个 Token 的类型后,交给 Tokenizer 进行分词返回 Token。
由于不同数据库遵守 SQL 规范略有不同,所以不同的数据库对应不同的 Lexer。子 Lexer 通过重写方法实现自己独有的 SQL 语法。
Lexer:包含4大属性:
String input:需要解析的SQL
Dictionary dictionary:KEY字典数据
int offset:下标
Token currentToken:当前解析出来的token信息
Token:包含三大属性
1.TokenType type :词法标记类型
DefaultKeyword :词法关键词
Literals :词法字面量标记:
IDENTIFIER :词法关键词
VARIABLE :变量
CHARS :字符串
HEX :十六进制
NT :整数
FLOAT :浮点数
Symbol :词法符号标记:
例如:”{“, “}”, “>=” 等等
Assist :词法辅助标记: END :分析结束
ERROR :分析错误
2.String literals :词法字面量标记
3.int endPosition :literals 在 SQL 里的结束位置
我们下面看一下例子:
3.Parser:SQL解析器
Parser 有三个组件:
SQLParsingEngine :SQL 解析引擎, 调用StatementParser 解析 SQL。
StatementParser :SQL语句解析器, 调用 SQLParser 解析 SQL 表达式。
SQLParser :SQL 解析器, 调用 Lexer 解析 SQL 词法。
3.1:StatementParser
SQL语句解析器,每种 SQL,都有相应的 SQL语句解析器实现。不同数据库,继承这些 SQL语句解析器,实现各自 SQL 上的差异。大体结构如下:调用 StatementParser#parse() 实现方法,对 SQL 进行解析。
3.2:SQLParser
不同的数据库会有对相应的解析器,主要提供只考虑 SQL 块的解析方法,不考虑 SQL 上下文,如下图:
主要包含五大方法:
#parseExpression() 解析表达式
#parseAlias() 解析别名
#parseSingleTable() 解析单表
#skipJoin() 跳过表关联词法
#parseWhere() 解析查询条件
3.3:Statement
不同 SQL 解析后,返回对应的 SQL 结果,即 Statement。Statement包含两部分信息: 分片上下文(context):用于 SQL 路由。 SQL 标记对象(token):用于 SQL 改写。大体结构如下:
3.4:实例分析
以之前的插入语句:
1.解析表名信息 ;
2.解析插入的表字段;
3.解析值-分库分表的条件字段 ;
4.自增键token