sqlparser mysql_Apache顶级项目ShardingSphere — SQL Parser的设计与实现

本文介绍了SQL解析的重要性及其在Apache ShardingSphere中的应用。通过理解词法分析和语法分析的基本原理,展示了SQL Parser如何将SQL语句转化为抽象语法树。ShardingSphere使用ANTLR生成词法和语法解析代码,支持多种数据库方言,并提供独立的SQL解析引擎,具备SQL格式化、参数化等功能。
摘要由CSDN通过智能技术生成

导语: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为例,解析器得出的语法树如下:

61a1a6c2647c5bbcfa04fdd57d3f9246.png

1、Lexer(词法分析)原理

Lexer 也称为分词,从左向右扫描SQL,将其分割成一个个的toke(不可分割的,具有独立意义的单元,类似英语中的单词)。

Lexer的实现一般都是构造DFA(确定性有限状态自动机)来实现的,以一个例子说明。

状态转移图如下,这是一个能够识别标识符,数字和一般运算符的词法解析器。

81d4356a558ab202ebd24fd226916b69.png

代码实现可以使用传统的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)

}

c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值