postgresql - 强制对 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 中的不明确引用问题(其中代码库中有很多)。
解决方案
Hibernate 生成的查询有f.ID as ID1_98_
. 该ORDER BY id
子句在严格的 SQL 中应该失败,因为它已重命名ID
列。
10 多年前,HSQLDB 接受此查询是为了与其他一些数据库兼容。近年来,添加了兼容性设置以允许严格检查。sql.enforce_refs
涵盖了在选择列表中命名了两列的情况,但ID
不涵盖这种情况。我们可能会在下一个版本中添加这个案例。
关于使用 HSQLDB 进行数据库应用程序测试,您仍然需要不时地针对预期目标运行测试,以避免误报结果。
推荐阅读
- terraform - 如何使用一个 terraform 脚本和不同的变量值管理多个不同环境的部署
- flutter - 如何使用 image_picker 依赖项在颤振中将图像上传到 sqlite 数据库
- keyboard - 使用外接键盘在 Mac 上编程
- reactjs - React JS:在父组件中调用子组件方法(使用打字稿反应)
- php - 在刀片 php 中将英文日期名称转换为日文
- javascript - 在动态组件中访问 nuxt $store
- macos - NSOpenPanel 打破 macOS 上的 UI 测试
- parallel-processing - Joblib、Parallel 和 batch_size
- regex - 匹配特殊字符串后面的文本
- cypress - cy.visit 在没有有意义的消息的情况下崩溃