On Fri, Aug 28, 2026 at 10:29 PM Richard Guo <[email protected]> wrote:
> 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:

I found another related but separate problem by grepping all the
places that handle CaseTestExpr.

contain_context_dependent_node_walker() knows that a CaseTestExpr is
expected under a simple CaseExpr or in the elemexpr of an
ArrayCoerceExpr, but not that a JsonConstructorExpr whose RETURNING
type needs a coercion also carries one in that coercion.  So
inline_function() refuses to inline any SQL function that is passed
such a constructor as an argument.  As an example, consider:

create function f(text) returns text language sql immutable
  as $$ select $1 || '!' $$;

explain (verbose, costs off)
select f(json_object('a': x returning text)) from generate_series(1,1) x;
                    QUERY PLAN
--------------------------------------------------
 Function Scan on pg_catalog.generate_series x
   Output: f(JSON_OBJECT('a' : x RETURNING text))
   Function Call: generate_series(1, 1)
(3 rows)

The attached 0002 teaches the walker about the coercion of a
JsonConstructorExpr.  It's basically just mirroring what it already
does for ArrayCoerceExpr.

0001 is a bug fix and should be back-patched to v16 where JSON
constructor was introduced.  0002 is a missed optimization so maybe we
can leave it to master-only?

- Richard

Attachment: v2-0001-Fix-const-folding-of-JSON-constructors-inside-a-s.patch
Description: Binary data

Attachment: v2-0002-Don-t-let-JSON-constructor-coercions-block-SQL-fu.patch
Description: Binary data

Reply via email to