`
ivanf8e62
  • 浏览: 15135 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Hibernate使用ANTLR语法解析器对HQL的解析BUG

    博客分类:
  • Java
阅读更多
[u][/u]公司产品中有一处判断生日月份的HQL语句,以前用得好好的,突然到了8月份的时候,这条语句出错了。HQL语句大概是from User u where month(u.birth) = 08 。后来猜测想到可能08有前置0,被当成了8进制处理了。把08改为8后,果然问题解决了。这证明猜想是正确的,但以前一直没研究过Hibernate的实现,于是想在网上搜索关于这个问题的答案,结果搜索不到,又想知道其实现的机制,于是下载代码下来看了一翻,发现问题出在Hiberante自定义的语法处理规则问题上,并且还找到了其中的一个BUG。



分析一下Hibernate对HQL中对前置0的数字的处理规则:

Hibernate对HQL生成SQL的校验是使用antlr语法分析器来做正确性保证的,其有自定义语法文件hql.g里对数字处理规则为如有前置0则进一步分析2种情况:
1、如果接下来有“x” 则表示为16进制,采用16进制分析。分析OK, 然后进入语义解析,依然会出现数字转换的错误,这里的错误后面我会讲。

2、如果没有“x”,则表示是8进制,根据语法文件定义0后面只接受0-7的数字,如果超出则会语法检查失败。抛出异常,程序结束。


总结:Hibernate在对HQL进行转换SQL时,调用antlr开源语法分析器进行语法的分析检查,解析正确后Hibernate的语义分析器LiteralProcessor在 转换整数时的代码有一个BUG,转码整数时只处理10进制,所以在16进制的情况下,会出现错误,因为有0x 这个x非数字符号在内导致 Integer.parseInt的失败。 如果不出现错误的话,也可能会因为其他进制被转换成10进制出现的与真实数字的偏差,比如:一个8进制数字 011,真正转换为10进制应该是9才对,但Integer.parseInt会将其转换10进制数11,这样就会导致出错的出现了.因此你想写8进制的011实际上在Hb里就会被转换为10进制的11。

出现这种问题所在就是: 语法分析器对整型数值的处理规则与实际Hibernate的语义分析器对数值转型的不一致导致的差别。

建议:在进行程序SQL编写中的条件的数字有前置0的时候那么要注意,这个值可能在计算机里会被分析器解析成8进制数字,但又可能直接被当作10进制处理。
所以最好所有数字都以10进制的形式传入保证程序的正确性。不要写前置0。

我认为此处的代码应该调用 Integer.decode方法才是正确的,另外对长整形的处理也是类似的。

以前我几乎不在网上写技术方面的内容,这些天来有感于自己当时到对一些问题搜索不到解决方案,所以才将此记录上来,供大家遇到此类问题的参考。
分享到:
评论

相关推荐

    ANTLR语法解析器简介

    1. **定义文法**:用户使用ANTLR的元语言来描述他们想要解析的语言的语法规则。这个元语言允许用户定义各种语言结构,如表达式、语句等。 2. **生成解析器和词法分析器**:ANTLR根据用户定义的文法生成相应的词法...

    利用Antlr实现的命令行解析器(增强)

    在IT领域,命令行解析器是程序设计中的一个重要组成部分,特别是在构建CLI(命令行界面...通过对ANTLR语法文件的调整和优化,我们可以进一步提升解析器的功能性和用户体验,为开发高效、易用的命令行工具提供强大支持。

    ANTLR V3 语法解析工具

    它能够读取一个语言的语法规则定义(通常是以ANTLR特有的语法文件格式,扩展名为.g或.gram),然后生成解析器和词法分析器,这些生成器可以解析符合该语法规则的输入文本。ANTLR V3 版本是ANTLR系列中的一个重要版本...

    antlr解析sql

    同时,如果需要,还可以对解析结果进行优化,如查询计划的选择,以提高执行效率。 在这个项目中,由于只实现了查询语句的解析,我们可以推断其主要关注的是SELECT语句的解析,包括字段选择、表连接、过滤条件等。...

    基于 Antlr4 的 Hive SQL 解析.zip

    1. **学习Antlr4**:理解其工作原理,包括如何定义语法规则,如何生成词法分析器和解析器,以及如何使用它们解析SQL语句。 2. **研究Hive SQL语法**:熟悉Hive SQL的特性和与标准SQL的不同之处,例如Hive的JOIN操作...

    clj-antlr, ANTLR 4解析器的Clojure绑定.zip

    clj-antlr, ANTLR 4解析器的Clojure绑定 clj-antlr面向 ANTLR 4 解析器库的Clojure绑定,一个自适应的( * ) 。 看起来很像 Instaparse,只有更快的语法定义,更丰富的语法定义,而且没有令人愉悦的。安装只需将 clj-...

    Antlr4 JAVA 语法解析器

    解析java语法 grammar Java; // starting point for parsing a java file compilationUnit : packageDeclaration? importDeclaration* typeDeclaration* EOF ; packageDeclaration : annotation* 'package' ...

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

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

    antlr java语法分析程序

    2. **生成解析器和词法分析器**:使用ANTLR工具将语法文件转换为Java源代码,生成解析器和词法分析器类。 3. **编译和运行生成的代码**:编译ANTLR生成的Java源代码,然后在应用程序中使用这些类来解析输入的文本。 ...

    利用Antlr实现的命令行解析器

    `FCmd.g`定义了我们的语言,`FCmdLexer.java`和`FCmdParser.java`实现了词法和语法分析,而`TCmdParseTree.java`则允许我们对解析结果进行操作。这种能力在开发复杂命令行工具、脚本语言或自定义解释器时非常有用,...

    ANTLR-V3 ORACLE11G GRAMMAR

    ANTLR V3是ANTLR的一个版本,它提供了改进的语法规则定义方式和更高效的解析器生成。 Oracle 11g是Oracle公司的一个关系数据库管理系统,其内部使用了PL/SQL,一种结合了SQL和过程编程的语言,用于编写存储过程、...

    Hibernate的Antlr在Weblogic中产生Jar冲突的解决办法

    Hibernate的Antlr在Weblogic中产生Jar冲突的历史缘故以及解决办法

    java Antlr 4 语法文件合集

    Java Antlr 4 是一个强大的解析工具,用于生成解析器和词法分析器,它使得开发者可以轻松地处理各种语言的语法。Antlr 4 支持多种编程语言,包括 Java,C#,Python,JavaScript 等,而在这个“java Antlr 4 语法文件...

    mini_C_compiler:使用lexer(使用ANTLR4解析器生成器),语法语义分析器的C语言的编译器

    PS:确保在源文件中放入以下行(.bashrc,.zshrc等) export CLASSPATH= " .:/usr/local/lib/antlr-4.8-complete.jar: $CLASSPATH "alias antlr4= ' java -jar /usr/local/lib/antlr-4.8-complete.jar 'alias grun=...

    Antlr-Practice:使用ANTLR编写词法分析器和解析器

    ANTLR,全称是ANother Tool for Language Recognition,是一款强大的解析工具,主要用于生成词法分析器(Lexer)和语法解析器(Parser)。这个“Antlr-Practice”项目是针对ANTLR的实际应用,旨在帮助开发者学习如何...

    logstash-antlr-config:logstash ANTLR配置解析器

    ANTLR能够生成解析器和词法分析器,这些工具可以读取输入源(如Logstash配置文件),将其转换为抽象语法树(AST),从而让Logstash理解并执行配置中的指令。这种解析过程使得Logstash能够灵活处理复杂的过滤和转换...

    antlr-2.7.6.jar

    项目中如果没有添加antlr-2.7.6.jar,那么相关的hibernate映射不会执行hql语句 并且会报NoClassDefFoundError:antlr/ANTLRException antlr-2.7.6.jar 是 ANother Tool for Language Recognition 的简称,它是一个用于...

    java8源码-sqlParser:使用java antlr4的sql解析器

    Stream API则可以方便地对解析结果进行过滤、映射和收集等操作。 项目中的核心类可能是`SqlParserMain.java`,它负责启动ANTLR4解析过程,接收SQL语句,调用生成的Lexer和Parser,最终得到AST。在这个过程中,可能...

    使用antlrv3实现sql的解析

    在本主题中,“使用antlrv3实现sql的解析”指的是利用ANTLR v3版本来创建一个解析器,该解析器可以理解并解析SQL语句,特别是针对Oracle和Microsoft SQL Server(MSSQL)的语法。 ANTLR工作原理主要包括以下几个...

Global site tag (gtag.js) - Google Analytics