`
whilew
  • 浏览: 21220 次
文章分类
社区版块
存档分类
最新评论

SQL语句解析过程浅析

 
阅读更多
在一些系统中需要对SQL查询语句进行解析,并最终根据业务需求将其转换处理将其转换为真实的SQL语句,这一过程我把它简称为:逻辑SQL-物理SQL的转换。在这一过程其中的关键技术是逻辑SQL语法分析,语法分析实现采用例如树型语法分析模型等方式实现,它是以二叉树方式,针对SQL中的关键字(例如:Select,From,Where等)进行判断并作为节点形成树型基本结构,再以二叉树方式加载查询数据(例如:查询字段,表名,条件等),最后形成二叉树结构模型,为后续的逻辑模型转换为物理模型提供词元数据,最后借助元数据系统辅助实现SQL语句转换工作。
逻辑SQL语句的解析(LSQL Parse)在技术上主要依托Antlr产品来实现。而ANTLR是语言识别的一种工具。它可以接受语法规则描述,并能根据语法规则自动产生识别这些符合语法规则的语句的程序。它作为翻译程序的一部分,可以允许使用简单的操作符和动作来表达你的语法规则,从而帮助ANTLR轻松简单地创建抽象语法树(AST)和产生最终输出信息。ANTLR能够知道怎样去生成识别程序,语言包括Java,C++,C#和Python等。

逻辑SQL脚本自动解析功能借助Antlr来实现对逻辑SQL脚本的词法、语法和语义分析,然后将逻辑SQL语句根据规则自动分拆为不同词元,并生成AST(抽象语法树)对象结构进行存储,后续的逻辑SQL检查与转换工作将主要围绕解析后生成的AST对象展开。具体的逻辑SQL完整解析过程如下图所示:


图:LSQL语句解析全过程示意图

为了能够不断地对后续逻辑SQL解析功能的完善和应用扩展,在系统实现过程中将逻辑SQL解析模块封装形成了独立组件,整体上保持形成一个较为松耦合的架构。其中逻辑SQL解析组件主要负责进行逻辑SQL语句按照设定的词法规则分拆成为特定的词元(Token),并在词元分拆的基础上进行相应的语法分析(主要依据设定的语法规则进行),最后将符合词法与语法要求的LSQL转换成为由若干词元形成的AST对象,并在AST对象的基础上配合元数据管理系统进行语义检查工作(主要是进行表实体,表属性,及实体与实体关系,实体属性关系等检查),最后完成由逻辑SQL语句到SQL语句的转换工作,具体工作过程如下图所示:


图:LSQL解析器工作过程示意图

下面通过一个具体的LSQL示例,来具体分析一下基于Antlr进行词法分析、语法分析后生成的AST对象结构,加强一下对解析过程的直接了解,示例LSQL语句如下所示:

SELECT [个人用户基本属性.用户编码],[个人用户基本属性.居住地址] FROM [个人用户基本属性] WHERE [个人用户基本属性.居住地址] IN ( SELECT [k.ADDR] FROM (SELECTCOUNT([个人用户基本属性.用户编码]) AS[C_USERID], [个人用户基本属性.居住地址] AS[ADDR] FROM [个人用户基本属性] GROUP BY [个人用户基本属性.居住地址]) as [K] WHERE [K.C_USERID]<5)

经过LSQL解析器后,生成的AST对象结构如下图所示:


从上图中可以看出,在AST中将结合在语法规则中设定的不同SQL句型的标识,形成完整的树形结构,后续的工作将紧紧围绕着树形对象的遍历展开.

整个LSQL解析组件基于编译技术,实现LSQL脚本的语法结构化描述,为后续的语义结构化描述建立抽象语法树(AST)。其处理过程可分为词法分析和语法分析两个步骤。在词法分析阶段,解析程序根据预先定义的SQL词法文法,对SQL脚本的字符流进行分词处理,输出SQL关键字、常量、变量、操作符等分词序列(TOKEN)。在语法分析阶段,解析程序根据预先定义的LSQL语法文法,对分词序列进行语法分析,建立层次化的抽象语法树。下图显示对一条SELECT语句解析处理后输出的AST。其中LSQL的语法规则文件如下所示:


图:LSQL语法规则文件示例

结合本次使用Antlr进行了LSQL解析工作进行的各项工作,对LSQL解析的主要优点与不足之处总结如下所示:

一、主要优点

a)基于解析之后的语法树提供用户操作接口,灵活性非常好,因为达到了对SQL每一部分的完整控制;

b)在数据库的适应性上只要符合标准SQL,以及部分封装好的特性(例如分页)、函数(例如主要数据库都支持的函数,但语法有一定差异的),基本上能够得到良好地支持;

c)具备编译期检查能力,能够提前检查LSQL的正确性,减少了系统不必要的开销;

d)能够完全把握住了整个解析过程,可以对解析过程进行深度加工处理;

二、不足之处

a)对LSQL的语法规则有较强的要求,目前测试所用的LSQL语句从语法结构上面来讲过于随意,没有一个标准的语法规则进行约束,这样给解析工作带来了较大的难度;

b)AST语法树看起来以及实现上不大流畅,表达式类体系结构清晰度不够,处理过程存在一定的复杂性,对性能有一定的影响;

对多种数据库的支持的Dialect的机制实现较为复杂,需要进行大量的二次开发工作,才能基本满足要求。



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics