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

Why two logically same conditions in postgresql case clause have different behavior?

我有两个查询是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 来查看。

Is there any why to have a complex query in the condition block that doesn't trigger runtime error in else block when result of condition is true?

是的,除了它并不是真正出现问题的 运行 时间。

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

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