postgresql - PostgreSQL ALTER VIEW 重写更改 AND/OR 含义
问题描述
我们在 PostgreSQL 中有一个大视图,它应该包含这个连接(更改名称以保护无辜者):
LEFT JOIN table1 ON
table4.a = table1.a AND
(regexp_split_to_array(table2.code::text, '_'::text))[1:2] = (regexp_split_to_array(table1.code::text, '_'::text))[1:2] AND
(
table3.b = table1.b OR
(table3.b IS NULL AND table1.b IS NULL) OR
(table3.b = 1 AND table1.b IS NULL) OR
(table3.b IS NULL AND table1.b = 1)
) AND
(
table3.c = table1.c OR
(table3.c IS NULL AND table1.c IS NULL) OR
(table3.c = 1 AND table1.c IS NULL) OR
(table3.c IS NULL AND table1.c = 1)
)
但是,当我们使用 CREATE OR REPLACE VIEW ... AS 保存视图定义时,它会重写它并删除一堆括号,这大大改变了 AND/OR 的含义:
LEFT JOIN table1 ON
table4.a = table1.a AND
(regexp_split_to_array(table2.code::text, '_'::text))[1:2] = (regexp_split_to_array(table1.code::text, '_'::text))[1:2] AND
(
table3.b = table1.b OR
table3.b IS NULL AND
table1.b IS NULL OR
table3.b = 1 AND
table1.b IS NULL OR
table3.b IS NULL AND
table1.b = 1
) AND
(
table3.c = table1.c OR
table3.c IS NULL AND
table1.c IS NULL OR
table3.c = 1 AND
table1.c IS NULL OR
table3.c IS NULL AND
table1.c = 1
)
这些查询不会产生相同的结果。
(数据来自第 3 方,其中表根据 a、b 和 c 中的数字连接,但如果 ID 为 1,则有时它为 NULL,因此 1 应与 NULL 匹配,反之亦然;它搞砸了,但我们不想更改数据)
所以本质上重写是改变视图的含义并有效地破坏它。
由于遗留软件冲突,我们被困在 9.4.26,所以我不确定问题是否仍然存在。
有什么方法可以防止 PostgreSQL 在重写期间破坏视图(我认为这是不可避免的)?
谢谢
解决方案
我不知道如何弄乱 Postgres 处理视图的方式,但阻力最小的路径可能是将您的查询重写为仅使用AND
s ,因此避免任何类型的括号恶作剧。就像是:
LEFT JOIN table1 ON
table4.a = table1.a
AND (regexp_split_to_array(table2.code::text, '_'::text))[1:2] = (regexp_split_to_array(table1.code::text, '_'::text))[1:2]
AND coalesce(table3.b, 1) = coalesce(table1.b, 1)
AND coalesce(table3.c, 1) = coalesce(table1.c, 1)
推荐阅读
- javascript - 如何在 reactJs 中访问其他项目的外部函数?
- eucalyptus - 节点显示状态为未就绪。节点不工作。我已经在其他系统中安装了节点控制器
- reactjs - 为什么我的插件没有被添加到 ckeditor4-react 中?
- android - 框架布局在 ConstraintLayout 内未正确定位
- azure-pipelines - azure-pipelines - 打印要输出的变量
- javascript - 排毒“无法读取 null 的属性‘绑定’”错误
- c# - UWP 后台应用程序未部署(错误 DEP0700)
- php - RabbitMQ - 如何使用多个通道重用相同的连接
- python - 从磁盘加载 TensorFlow 模型是即时的,而从 gcs 加载非常慢
- javascript - 页面加载动画在 IOS 设备上的页面加载之前很久就停止了动画