Wrong result from JSON constructor in a simple CASE

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Wrong result from JSON constructor in a simple CASE
Date: 2026-08-28 13:29:17
Message-ID: CAMbWs48A=VCFbteTkuCoknO1_0-Cu0aMBT0M07dm7vj1QyixDg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

While working on the fix for qual pushdown past grouping through a
simple CASE [1], I modeled the v2 patch's handling of CaseTestExpr on
what eval_const_expressions does. Ewan Young pointed out that v2
mishandled the CaseTestExpr in a JSON constructor's coercion
expression, which led me to notice that eval_const_expressions has the
same bug:

SELECT CASE 'x' WHEN JSON_OBJECT('a': 'b' RETURNING text)
THEN 1 ELSE 0 END;
case
------
1
(1 row)

The result should be 0, since 'x' is not equal to '{"a" : "b"}'.

A JSON constructor with a RETURNING clause uses a CaseTestExpr as the
placeholder for its result in the coercion expression. When it
appears in a WHEN clause of a simple CASE with a constant test
expression, eval_const_expressions substitutes that constant for the
placeholder too, so the coercion yields the CASE's test value instead
of the constructor's result.

The same hazard exists for the elemexpr of an ArrayCoerceExpr, and
eval_const_expressions already clears case_val while processing that.
The attached patch does the same for the coercion of a
JsonConstructorExpr.

[1] https://postgr.es/m/CAHewXNkvGTOgijRLjmudpg=wz0d-J8ChY2o7ksh3Be+Q_Bxwog@mail.gmail.com

- Richard

Attachment Content-Type Size
v1-0001-Fix-const-folding-of-JSON-constructors-inside-a-s.patch application/octet-stream 4.4 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Bertrand Drouvot 2026-08-28 13:32:06 Re: Persist slot invalidations before publishing them
Previous Message Nisha Moond 2026-08-28 13:22:34 Re: Proposal: Conflict log history table for Logical Replication