1. 什么是AST
AST是abstract syntax tree的缩写,也就是抽象语法树。和所有的Parser一样,Druid Parser会生成一个抽象语法树。 具体的过程如下:
可以通过把一个Sql语句 解析成 不同类型的对象 。从而形成 一颗树状结构 。
2. 在Druid SQL Parser中有哪些AST节点类型
在Druid中,AST节点类型主要包括SQLObject、SQLExpr、SQLStatement三种抽象型。已这3个类为基础构成了功能复杂的各种节点。
interface SQLObject {} interface SQLExpr extends SQLObject {} interface SQLStatement extends SQLObject {} interface SQLTableSource extends SQLObject {} class SQLSelect extends SQLObject {} class SQLSelectQueryBlock extends SQLObject {}整个AST的结构大概如下 ,以SQLSelectStatement为例:
SQLSelectStatement
SQLSelect
SQLSelectQueryBlock
List<SQLSelectItem>-->列名
SQLTableSource--->表
SQLExpr-->where 语句
SQLOrderBy-->排序语句
SQLLimit--> limit分页操作
通过上面的结构可以形成一棵语法树
3.语法树的生成流程
SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); 通过上面的的方法可以得到一个语法树解析器. List<SQLStatement> stmtList = parser.parseStatementList(); 通过调用解析器可以得到一棵语法树,当传入的sql是多条时,多条语句以逗号隔开,则会返回多条的list数据。语法树生成的底层原理:
SQLStatementParser的内部,内嵌着 SQLExprParser 对象,表达式解析的对象。
SQLExprParser的内部,包含 Lexer lexer 分词对象。
Lexer对象的内部,内置了许多
Keywords keywords = Keywords.DEFAULT_KEYWORDS; 这些关键词都是SQL语法中的关键词 ,所以我们可以大致猜测,整个处理流程 就是通过 分词器去获取SQL语句中的分词,和 分词器 内部的 keyword 做对比 ,如果 一样 则说明,该关键词的前后段 为 关键的 AST对象,需要做封装的处理 。最终形成一棵 语法树。
4 常用的SQLStatemment
最常用的Statement当然是SELECT/UPDATE/DELETE/INSERT,他们分别是
package com.alibaba.druid.sql.ast.statement; class SQLSelectStatement implements SQLStatement { SQLSelect select; } class SQLUpdateStatement implements SQLStatement { SQLExprTableSource tableSource; List<SQLUpdateSetItem> items; SQLExpr where; } class SQLDeleteStatement implements SQLStatement { SQLTableSource tableSource; SQLExpr where; } class SQLInsertStatement implements SQLStatement { SQLExprTableSource tableSource; List<SQLExpr> columns; SQLSelect query; }
5. SQLSelect & SQLSelectQuery
SQLSelectStatement包含一个SQLSelect,SQLSelect包含一个SQLSelectQuery,都是组成的关系。SQLSelectQuery有主要的两个派生类,分别是SQLSelectQueryBlock和SQLUnionQuery。
class SQLSelect extends SQLObjectImpl { SQLWithSubqueryClause withSubQuery; SQLSelectQuery query; } interface SQLSelectQuery extends SQLObject {} class SQLSelectQueryBlock implements SQLSelectQuery { List<SQLSelectItem> selectList; SQLTableSource from; SQLExprTableSource into; SQLExpr where; SQLSelectGroupByClause groupBy; SQLOrderBy orderBy; SQLLimit limit; } class SQLUnionQuery implements SQLSelectQuery { SQLSelectQuery left; SQLSelectQuery right; SQLUnionOperator operator; // UNION/UNION_ALL/MINUS/INTERSECT }