赞
踩
导语:SQL作为现代计算机行业的数据处理事实标准,是目前最重要的数据处理接口之一,从传统的DBMS(如MySQL、Oracle),到主流的计算框架(如spark,flink)都提供了SQL的解析引擎,因此想对sql进行精细化的操作,一定离不开SQL Parser。Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,需要对SQL进行精细化的操作,如改写,加密等,因此也实现了SQL Parser,并提供独立的Parser引擎。
先来认识一下传统数据库中一条SQL处理流程是怎样的,接受网络包-》数据库协议解析网络包的到sql-》SQL语法解析为抽象语法树-》把语法树转换成关系代数表达式树(逻辑执行计划)-》再转换成物理算子树(物理执行计划)-》遍历物理算子树执行相应算子的实现获取数据并返回。
一、工作原理
SQL Parser 的功能是把一条SQL解析为抽象语法树(AST),SQL Parser需要编译原理相关的知识,简单介绍一下。
SQL Parser 包含词法解析(Lexer)和语法解析(Parser),词法解析的作用是把一个sql 分割成一个一个不可分割的单元,例子:
原始sql: select id,name from table1 where name=“xxx”;
词法解析器输入是原始sql,并且暴露一个接口nextToken(),每次调用nextToken()都会返回一个Token(表示上面所说的不可分割的元素),伪代码如下:
String originSql = "select id,name from table1 where name='xxx'";
Lexer lexer = new Lexer(originSql);
while(!lexer._hitEOF){// 判断是否结束
System.out.printLn(lexer.nextToken())
}
// 输出如下:
select
id
,
name
from
table1
where
name
=
'xxx'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
语法分析器的作用是使用Lexer的输出(调用nextToken()),构造出AST,以上面的sql为例,解析器得出的语法树如下:
1、Lexer(词法分析)原理
Lexer 也称为分词,从左向右扫描SQL,将其分割成一个个的toke(不可分割的,具有独立意义的单元,类似英语中的单词)。
Lexer的实现一般都是构造DFA(确定性有限状态自动机)来实现的,以一个例子说明。
状态转移图如下,这是一个能够识别标识符,数字和一般运算符的词法解析器。
代码实现可以使用传统的while case的模板实现,伪代码如下:
Class Token{...}
Enum State {
BEGIN,OPERATER,IDENTIFIER,NUMBER
}
Class Lexer{
String input = "...";
State state = BEGIN;
int index = 0;
Token nextToken() {
while(index < input.length) {
Char char = input.charAt(index);
switch (state) {
case BEGIN:
switch (char){
case a-zA-Z_ :
index++;
state = IDENTIFIER;
case +-*/ :
state = BEGIN
return Token(OPERATER)
case 0-9:
state = NUMBER;
index++;
default:
return null;
}
case IDENTIFIER:
switch (char){
case a-zA-Z_0-9 :
index++;
state = IDENTIFIER;
default :
state = BEGIN;
index--;
return Token(IDENTIFIER)
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。