`
jackyhongvip
  • 浏览: 158200 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ANTLR实现的SQL解析器 - OQL

 
阅读更多

OQL
使用ANTLR写了个SQL解析器,这样ORM的基本功能就比较完整了。几天的时间比较仓促,所以对于最终目标,还只能算是个雏形。

总体状况
使用SQL解析器的主要优点:
1. 基于解析之后的语法树提供用户操作接口,灵活性非常好,因为达到了对SQL每一部分的完整控制。
2. 对数据库的适应性。
   首先可以采用标准SQL,以及部分封装好的特性(例如分页)、函数(例如主要数据库都支持的函数,但语法有一定差异的),使用一个适配器Dialect基于语法树进行翻译。这样能满足绝大部分用途。
   如果确实需要使用某数据库的特性,可能只需要修改语法描述文件就能实现,或者对语法树等作少量修改进行配合。
3. 跟LINQ的比较。
   a. LINQ具备编译期检查,与VS整合的优点。
   b. 根据粗略的了解,感觉LINQ语法树操作起来比较繁琐。
   c. 自己完全把握住了整个解析过程,不会受LINQ语法和语法树的限制。
   d. 不了解LINQ语法树的开放性,即结构的稳定、兼容性。例如以后添加新的特性,是否会影响到语法树的结构?
   类似LINQ to Hinbernate一样,只将LINQ当作查询的输入,而使用自己的ORM实现持久化,中间的可控能力会比较强。虽然LINQ与OQL在功能上重合,只是各有优缺点而已,并且可以采用不错的结合点。

目前的主要缺点:
1. 基于SQL Server的语法。
2. AST语法树看起来以及实现上不大流畅,表达式类体系结构理的不大清楚。
3. 数据库Dialect的机制不好。

以后的目标:
1. 多数据库支持。
   不管是纯粹ORM操作,还是OQL或者SQL,都能由数据库dialect自动翻译。
2. 语法: 基于标准DML语法,添加必要的特性。
   a. 分页,预计使用select distinct? range(start, end) column1, column2..这样的方式,由数据库dialect向各特定数据库SQL语法进行翻译。SQL Server 2000这种不完整支持的,由dialect辅助完成。
   b. 标准函数,常用的SQL 92标准函数应当都能向各个数据库进行翻译,还可以提取一些其它函数,主流数据库都支持且能够进行翻译的。
3. 标准化Query Hints。
   目的是在OQL中提供一个性能调优的机会,针对主要Query Hints进行提取,由dialect翻译成各数据库特定语法。
4. Object Query / 标准SQL Query功能。
   a. 不象Hibernate要求纯粹的对象模型,OQL使用DomainClass1 inner join DomainClass2 on ...这样的方式。缺点是对象模型的内部结构被暴露,但更具灵活性。以后考虑对对象模型的自动支持,也就是可以使用各种混合方式进行开发。还允许DomainClass和Database Table混合写在OQL中,用于满足类似many-to-many的关联表不会建立DomainClass,又不想用对象属性建立双向映射关系的情况。
   b. 程序先给出查询语句,OQL解析出语法树,基于语法树再动态修改,例如根据界面的选择添加查询条件、排序方式、需要的字段等。进一步,一些非必要的关联关系能够在运行时自动、动态确定。
   c. 基于语法树进行修改的灵活性,应当能够提供比较灵活的AOP功能,例如AOP方式的数据权限控制。

下一步代办事项:
1. 项目中将用户接口和必要的功能特性进行完善。
2. 语法树结构的完善,表达式类体系的完善,数据库Dialect、O-R Mapping等与OQL结合的机制以及职责的梳理完善。
3. 标准化,主流数据库Dialect。
4. 语法优化(重点是解析性能)。

目前语法大致描述:
Statement: SelectStatement | UnionStatement | InsertStatement | UpdateStatement | DeleteStatement;
SelectStatement: SelectClause FromClause? WhereClause? (GroupByClause Having?)? OrderByClause?;

SelectClause: Columns+;
Column: '*'? | Identifier '.*'
             | Expressions Alias?
//MathOperator为数学运算符,例如+, -, *, /, %
Expressions: Expression (MathOperator Expression)*;
//Identifier为字段/属性名,Constant为常量,包括系统变量例如@@identity之类以及字符串等
//Case .. When 语句当作Function处理
Expression: Identifier | Constant | UserVariable | Function | SelectStatement | UnionStatement;

//Where子句采用较标准的运算语法树形式,类EBNF描述
WhereClause: Condition;
Condition: SubCondition ((AND ^ | OR ^) SubCondition)*
SubCondition: '(' Condition ')' | Predicate;
Predicate: Expressions (
        ComparisonOperator Expressions //ComparisonOperator为>, <=, !>, Like等比较运算符
        | IS NOT? NULL
        | IN '(' Expressions (',' Expressions)* ')'
        | BETWEEN Expressions AND Expressions
        | IN '(' (SelectStatement | UnionStatement) ')'
    ) |
    EXISTS '(' (SelectStatement | UnionStatement) ')';

整体:
  

Select子句:                                                        Where子句:
                                  

解析性能测试:
下面这个SQL应该能够代表绝大部分普通查询情况,循环解析1000次,所用时间在480-600ms之间。其中{0}, {1}是在循环中替换为当前计数,使每次解析的SQL不一样。这样普通情况下,把解析后的语法树进行缓存已经没有太多必要。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->Select 12'ada {0} And >0""' As c1, (select 1), @UserNamecase when a=1 then 1 else 0 endsum(a) as Total
From Sys_User a, Sys_Org b
inner join Sys_Org_View c on c.Org_Id=b.Org_Id and (ccc={1})
Where cast(a.User_Id as varchar)=b.User_Id or (a=and Total between 100 And 1000)
Group bY a, b
haViNg Total between 100 And 1000
Order By a, DDD Desc, A asc
分享到:
评论

相关推荐

    java-antlr-sql.rar_antlr_antlr sql_antlr-sql_antlr4 sql解析_java

    在这个名为"java-antlr-sql.rar"的压缩包中,包含了一个使用ANTLR来解析SQL的Java项目。ANTLR支持多种目标语言,包括Java,而在这个案例中,我们看到的是如何将ANTLR与Java结合来解析SQL语句。 ANTLR的工作原理是...

    antlr-intellij-plugin-v4-1.14.zip

    对于下载的"antlr-intellij-plugin-v4-1.14.zip"文件,它是2020年版本的ANTLR Intellij Plugin v4.14的备份。这意味着它可以安装到IntelliJ IDEA中,为用户提供ANTLR 4的支持。安装步骤通常包括解压缩文件,将解压后...

    antlr4-runtime-4.2-API文档-中文版.zip

    赠送jar包:antlr4-runtime-4.2.jar; 赠送原API文档:antlr4-runtime-4.2-javadoc.jar; 赠送源代码:antlr4-runtime-4.2-sources.jar; 赠送Maven依赖信息文件:antlr4-runtime-4.2.pom; 包含翻译后的API文档:...

    antlr-runtime-3.4-API文档-中文版.zip

    赠送jar包:antlr-runtime-3.4.jar; 赠送原API文档:antlr-runtime-3.4-javadoc.jar; 赠送源代码:antlr-runtime-3.4-sources.jar; 赠送Maven依赖信息文件:antlr-runtime-3.4.pom; 包含翻译后的API文档:antlr-...

    antlr4-runtime-4.7-API文档-中文版.zip

    赠送jar包:antlr4-runtime-4.7.jar; 赠送原API文档:antlr4-runtime-4.7-javadoc.jar; 赠送源代码:antlr4-runtime-4.7-sources.jar; 赠送Maven依赖信息文件:antlr4-runtime-4.7.pom; 包含翻译后的API文档:...

    antlr-3.4-complete-no-antlrv2.jar

    antlr-3.4-complete-no-antlrv2.jar

    antlr-runtime-3.5-API文档-中文版.zip

    赠送jar包:antlr-runtime-3.5.jar; 赠送原API文档:antlr-runtime-3.5-javadoc.jar; 赠送源代码:antlr-runtime-3.5-sources.jar; 赠送Maven依赖信息文件:antlr-runtime-3.5.pom; 包含翻译后的API文档:antlr-...

    antlr-runtime-3.5.2-API文档-中英对照版.zip

    赠送jar包:antlr-runtime-3.5.2.jar; 赠送原API文档:antlr-runtime-3.5.2-javadoc.jar; 赠送源代码:antlr-runtime-3.5.2-sources.jar; 赠送Maven依赖信息文件:antlr-runtime-3.5.2.pom; 包含翻译后的API文档...

    antlr-python-runtime-3.1.3.zip

    ANTLR被广泛应用于构建语言、工具和框架,如SQL处理器、XML解析器、Java语法分析器等。Python runtime是ANTLR在Python语言中的运行时库,它允许你在Python环境中使用ANTLR生成的解析器。 标题“antlr-python-...

    antlr4-runtime-4.7-API文档-中英对照版.zip

    赠送jar包:antlr4-runtime-4.7.jar; 赠送原API文档:antlr4-runtime-4.7-javadoc.jar; 赠送源代码:antlr4-runtime-4.7-sources.jar; 赠送Maven依赖信息文件:antlr4-runtime-4.7.pom; 包含翻译后的API文档:...

    基于 Antlr4 的 Hive SQL 解析.zip

    4. **实现解析器**:利用Antlr4生成的解析器类,处理输入的Hive SQL语句,构建并遍历AST,以执行语句的逻辑。 5. **测试和优化**:编写测试用例,确保解析器能够正确处理各种复杂的Hive SQL查询,同时优化性能,...

    antlr-maven-plugin-2.1.jar.zip

    总的来说,`antlr-maven-plugin-2.1.jar.zip`是针对ANTLR的一个Maven插件,方便开发者在Java项目中集成ANTLR,利用其强大的解析能力来处理各种结构化数据。配合Maven的自动化构建流程,可以极大地提高开发效率和代码...

    antlr-runtime-3.5-API文档-中英对照版.zip

    赠送jar包:antlr-runtime-3.5.jar; 赠送原API文档:antlr-runtime-3.5-javadoc.jar; 赠送源代码:antlr-runtime-3.5-sources.jar; 赠送Maven依赖信息文件:antlr-runtime-3.5.pom; 包含翻译后的API文档:antlr-...

    基于antlr4 解析器,支持spark sql, tidb sql, flink sql, Sparkflink运行命令解析器

    在"superior-sql-parser-master"这个压缩包中,很可能包含了ANTLR4的语法定义文件(.g4)以及相关的Java源代码,这些代码实现了对各种SQL方言和运行命令的解析逻辑。开发者可以通过阅读这些代码,了解如何自定义...

    antlr-runtime-3.1.3-sources.jar.zip

    这意味着即使你没有ANTLR的编译工具,也可以在项目中引入"antlr-runtime-3.1.3-sources.jar"作为依赖,以便解析由ANTLR生成的语法文件(通常以.g或.gram结尾)所创建的解析器。 在Java项目中,如果需要使用ANTLR...

    antlr解析sql

    在SQL解析领域,ANTLR被广泛应用于构建能够理解SQL语句的解析器。这个项目的目标是将SQL查询语句解析成对象,以便于进一步的操作和处理。虽然当前实现仅涵盖了查询语句,但设计时已经考虑到了扩展性,预留了对UPDATE...

    antlr-intellij-plugin-v4-1.12.zip idea的antlr插件

    ANTLR(ANother Tool for Language Recognition)是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化...通过使用这个插件,可以更好地在IDE内实现ANTLR的语法定义和解析器的开发工作,提升开发体验和生产力。

    antlr-intellij-plugin-v4-1.17-2020.zip

    通过将ANTLR与IntelliJ IDEA结合,开发者可以获得一个强大的环境来设计、实现和调试这类解析器,从而提高开发效率和代码质量。 总之,“antlr-intellij-plugin-v4-1.17-2020.zip”是一个专为IntelliJ IDEA设计的...

    antlr-2.7.7.jar和antlr-2.7.6.jar

    总之,ANTLR是构建解析器的强大工具,而antlr-2.7.7.jar和antlr-2.7.6.jar是ANTLR的不同版本,它们以JAR文件的形式提供,用于Java项目中解析和处理结构化文本。选择使用哪个版本应根据项目的需求、兼容性和稳定性来...

    antlr-2.7.7.jar.zip

    "antlr-2.7.7.jar.zip"这个压缩包是ANTLR 2.7.7版本的Java实现,包含了运行ANTLR工具和使用其生成的解析器所需的所有类。在Java项目中正确引用这个jar包,就能利用ANTLR的能力来解析和处理自定义语言的语法。

Global site tag (gtag.js) - Google Analytics