源码分析MyCat之SQL解析篇-----sql解析引擎druid之抽象语法树(mycat1.6)
1、Druid解析引擎概要
Druid SQL 解析引擎主要分为三个部分,AST抽象语法树,词法解析,语法解析。
AST抽象语法树,语法解析的结果,由众多AST语法对象组成一颗树,而词法分析就是解析出一个一个关键字,作为语法解析的输入。
Druid SQL解析引擎整体介绍,推荐一篇文章:http://www.tuicool.com/articles/NNJNbmF
故本节重点认识一下Druid解析引擎中抽象语法树中对象。
整颗ast语法对象,大体可以分为如下三类,表达式(expr,包括运算符)、语句级(statement)、其他(基础类,比如hint)。
2、表达式(Expr,运算符)
druid关于表达式的常用对象如图所示:
图片如果不清晰,建议下载原图浏览。
基于如下SQL举例说明如下对象:
select a.id,a.name,(select count(1) from acc_b b where b.user_id=a.id) as num from acc_user a
- SQLExpr 表达式根接口对象
- SQLPropertyExpr 查询字段列表,比如上面查询列表中的 a.id ,a.name 就是用一个SQLPropertyExpr表示
- SQLIdentifierExpr 一般表示表名或别名,还是上面的a.id,整体是一个SQLPropertyExpr,但SQLPropertyExpr由owner与name组成,其中name为id,而表的别名由owner来表示,也就是一个SQLIdentiferExpr,如图所示:
- SQLAllColumnExpr 查询字段(*)的表示符
- SQLLiteralExpr 字面量表示,其子类如下:
- SQLIntegerExpr 整数型字面量表达式,比如 where a.id = 1 ,其中1就是用SQLIntegerExpr来表示。下面的类似
- SQLBooleanExpr
- SQLNumericLiteralExpr
- SQLCharExpr
- SQLDateExpr
- SQLTextLiteralExpr
- SQLTimestampExpr
- SQLAllExpr、SQLSomeExpr、SQLAnyExpr 运算符 all,some、any。
- SQLQueryExpr 出现在select 查询列表中,是查询的情况,如下:【select a.id,a.name,(select count(1) from acc_b b where b.user_id=a.id) as num from acc_user a 】
- SQLVariantRefExpr 预编译,占位符,比如?或序号索引
SQLBetweenExpr
- 1、beginExpr,endExpr是字面值表达式,例如SQLIntegerExpr
- 2、testExpr,SQLPropertyExpr,例如a.num(字段名)
SQLBinaryOpExpr 二维运算符表,比如 a.name = 1,这个表达式,左边是a.name(SQLPropertyExpr),右边是SQLIntegerExpr(字面量表达式),而中间是运算符,等于。
3、语句(statement)
每一条SQL语句都会对应一个Statement类,比如创建数据库,创建表,删除修改表,查询,更新,删除,插入等语句,本节主要讲解常用的语句进行讲解。
图片如果不清晰,建议下载原图浏览。
SQLAlterDatabaseStatement、SQLCreateDatabaseStatement、SQLDropDatabaseStatement 创建数据库,修改数据库、创建表,创建索引,增加字段等,都会对应一个statement,在这里就不详细展开,根据类名基本就能知道改类对应什么SQL语句。
- SQLConstraint : SQL约束
- SQLIfStatement:IF语句,包含ElseIf,Else
- SQLLoopStatement : sql循环语句。
- SQLBlockStatement: SQL语句块语句
SQLCallStatement:存储过程描述, 包括存储过程名称,所有参数(包括入参、出参),出参。(SQLVariantRefExpr)。
接下来重点描述,查询语句,插入语句,更新语句,删除语句。
2.1 SQLSelectStatement
查询语句,包含两个属性,一个是SQLSelect对象,一个是List<CommentHint>。
SQLSelect来表示一个select查询的各个部分,分为withSubQuery、查询语句主体部分(SQLSelectQuery)、排序(SQLOrderBy)和 List<SQLHint>。
查询主体部分SQLSelectQuery包含如下实现类:SQLUnionQuery、SQLSelectQueryBlock、SQLUnionQuery的left,right属性又是一个SQLSelectQuery,不难看出,最终的查询主体部分会落到SQLSelectQueryBlock上。
查询部分(SQLSelectQueryBlock)包括如下组成部分:
- 查询字段列表 List<SQLSelectItem>,如果是 select id,name 这种字段列表,则表示为SQLIdentifierExpr,如果是select a.id,a.name则表示为SQLPropertyExpr。
- from 属性,类型为SQLTableSource,SQLTableSource有如下几个实现类,SQLExprTableSource、SQLJoinTableSource、SQLSubqueryTableSource、SQLUnionQueryTableSource。
a、SQLExprTableSource:from 后面接简单的表名,例如 select a.id,a.name from acc_user a。
b、SQLJoinTableSource : from 后面的表使用了连接操作,比如select a.id,a.name from acc_user a left join acc_account b on b.user_id=a.id and b.id=a.id, 该对象拥有 SQLTableSource left,right(典型的二叉树结构),joinType属性表明连接的类型。condition,用一个SQLExpr来表示,大家或许会想,如果有两个连怎么办,只用一个SQLExpr如何表示多个条件,其实是通过SQLBinaryOpExpr这个二元操作符来表示的,SQLBinaryOpExpr两个类型为SQLExpr的left,right属性,然后一个运算符。
c、SQLSubqueryTableSource:子查询表,例如 select * from (select a.id,a.name from acc_user a) tmp;该对象内部再持有一个SQLSelect对象。
d、SQLUnionQueryTableSource,union表,,内部持有一个SQLUnionQuery对象。
- into 属性,类型为SQLExprTableSouce,into关键字后接一个普通的表。
- where属性,类型为SQLExpr,这里的原理与join 的 on 条件类似,如果有多个条件,会用SQLBinaryOpExpr对象来表示(二元运算符),通过left.right组织成一颗树。
- groupBy属性 ,SQLSelectGroupByClause,group by a.name,a.id ,首先会有多个a.name,用一个List<SQLExpr> items表示,用一个SQLExpr表示having。
- 6)orderBy属性,SQLOrderBy,就是用List<SQLSelectOrderByItem>,来表示(order by a.id desc,a.create_time desc)
- limit属性,类型SQLLimit,limit 1,5, (limitoffset,rowCount)就是两个属性,offSet, rowCount。
2.2 SQLInsertStatement
SQLInsertStatement继承自SQLInsertInfo类,MySqlInsertStatement继承SQLInsertStatement。
insert 语句的基本信息,封装在SQLInsertInfo,主要有如下属性:
- SQLExprTableSource tableSource,插入目的表名
- List<SQLExpr> columns,插入字段列表
- SQLSelect query,select 查询语句
- List<ValuesClause> valuesList,valeus 列表,与query二选一存在,每一个ValuesClause为一个值列表,想象一下该语句 insert into es_user(id,name) values (1,2),(3,4);
2.3 SQLUpdateStatement
对应更新SQL语句,属性介绍如下:
- List<SQLUpdateSetItem> items, set 字段列表,set a.id=1,a.name="a",一个SQLUpdateSetItem由一个SQLExpr column和SQLExpr value来表示。
- SQLTableSourceTable tableSouce,更新的表名
- SQLExpr where,where条件
2.4 SQLDeleteStatement
删除SQL语句,主要属性如下:
- SQLTableSource tableSource,操作的表名、
- SQLExpr where,where 条件。
欢迎加笔者微信号(dingwpmz),加群探讨,笔者优质专栏目录:
1、源码分析RocketMQ专栏(40篇+)
2、源码分析Sentinel专栏(12篇+)
3、源码分析Dubbo专栏(28篇+)
4、源码分析Mybatis专栏
5、源码分析Netty专栏(18篇+)
6、源码分析JUC专栏
7、源码分析Elasticjob专栏
8、Elasticsearch专栏
9、源码分析Mycat专栏
更多推荐
所有评论(0)