微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 postgresql case 子句中两个逻辑上相同的条件有不同的行为?

如何解决为什么 postgresql case 子句中两个逻辑上相同的条件有不同的行为?

我有两个查询是 postgresql

1. SELECT CASE WHEN (1=1) THEN NULL ELSE cast(1/0 as text) END;
2. SELECT CASE WHEN (EXISTS (SELECT 10)) THEN NULL ELSE cast(1/0 as text) END;

您可能已经注意到两个查询中第一个条件的结果为真,但第一个查询的结果是 null,第二个查询的结果是 ERROR: division by zero

这里发生了什么?

在评估发生的顺序上是否有任何优化?如果是,是否有任何原因将其关闭

当条件结果为真时,是否有任何原因在条件块中有一个复杂的查询,而不会在 else 块中触发运行时错误

Postgresql 版本:13.1

解决方法

错误发生在计划查询时,而不是运行时。

在第一种情况下,在计划时已知 1=1 为真,导致整个 CASE 折叠为 NULL::text。因此,1=1CASE WHEN true 的常量折叠使您免于 1/0 的常量折叠异常。您可以通过执行 EXPLAIN VERBOSE 来看到这一点。

当条件结果为真时,是否有任何原因在条件块中有一个复杂的查询,而不会在 else 块中触发运行时错误?

是的,除非它不是真正在运行时出现问题。

就像一个虚拟的 SELECT 打败了防止问题的常量折叠,另一个虚拟的 select 可以打败导致问题的常量折叠。

SELECT CASE WHEN (EXISTS (SELECT 10)) THEN NULL::text ELSE cast (1/(select 0) as text)  END;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。