首页 > 解决方案 > 强制对 HSQLDB 中的列名进行明确引用

问题描述

我有一个 HQL 查询在 PostgreSQL 上失败,因为 order by 子句包含一个不明确的列引用。我了解问题的原因以及如何解决它,但是,在针对内存 HSQLDB 数据库运行时,测试相同查询和 order by 子句的单元测试通过且没有错误。如果在其他查询中遇到类似问题,我想确保在 CI 构建中在 HSQLDB 上运行的所有单元测试都将失败。

阅读 HSQLDB 指南 ( http://hsqldb.org/doc/2.0/guide/guide.pdf ) 发现有几个默认禁用的设置,启用它们将强制检查数据库对象和查询是否符合 SQL 标准。

我相信我需要的设置是sql.enforce_refs=true在我的 JDBC 连接 URL 上,以便在遇到不明确的引用时测试失败。

我已经更新了我的 URL,所以它现在看起来如下所示。

jdbc.url=jdbc:hsqldb:mem:testdb;shutdown=false;sql.enforce_refs=true;sql.restrict_exec=true;sql.enforce_type=true

(注意:我也包括在内sql.enforce_names=true,但这导致了很多我尚未调查的失败)。

我遇到的问题是,即使在连接 URL 中使用这些设置,测试也会继续通过。似乎 HSQLDB 没有执行检查。我没有发现有关此设置的任何问题,并且我使用的是最新的 HSQLDB 版本(当前为 2.5.0)。

我的问题是我想通过连接 URL 设置强制执行此检查,以便在 CI 构建执行单元测试时检测这些问题,并且该设置似乎不起作用,所以我想知道这是否是一个已知问题,或者我做错了什么,或者其他人是否设法以不同的方式启用了此检查?(我真的不想执行SET DATABASE...命令来启用此检查)。

非常感谢,罗布


编辑:2019 年 4 月 11 日

包含示例 SQL 以帮助解决问题。请注意,我的问题不是这个 SQL,而是在 CI 构建中运行测试时使用 HSQLDB 连接字符串中的选项来检测这种 SQL 问题。

    select
        f.ID as ID1_98_,
        f.PROP_A as PROP_A2_98_,
        f.CLOSE_DATE as CLOSE_DA3_98_,
    from
        FOO f 
    left outer join
        FOO_SUB_TYPE fst 
            on f.FOO_SUB_TYPE_FK=fst.ID 
    left outer join
        FOO_TYPE ft 
            on fst.ID=ft.ID 
    where
        ?=f.WIBBLE_FK 
    order by
        id ASC nulls last

SQL 是从 Hibernate HQL 生成的,如下所示:

from Foo f
left outer join f.fooSubType as fst
where (:wibbleId = f.wibble.id)

我不是 HQL / SQL 的作者(除了在这里更改表/实体类名称),我认为这left outer join是不必要的。正如我所说,SQL 并不是很重要,问题是能够检测到 SQL / HQL 中的不明确引用问题(其中代码库中有很多)。

标签: postgresqlhsqldb

解决方案


Hibernate 生成的查询有f.ID as ID1_98_. 该ORDER BY id子句在严格的 SQL 中应该失败,因为它已重命名ID列。

10 多年前,HSQLDB 接受此查询是为了与其他一些数据库兼容。近年来,添加了兼容性设置以允许严格检查。sql.enforce_refs涵盖了在选择列表中命名了两列的情况,但ID不涵盖这种情况。我们可能会在下一个版本中添加这个案例。

关于使用 HSQLDB 进行数据库应用程序测试,您仍然需要不时地针对预期目标运行测试,以避免误报结果。


推荐阅读