| From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
|---|---|
| To: | ma(dot)sao(at)msa(dot)hinet(dot)net |
| Cc: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Subject: | Re: BUG #19454: PL/pgSQL mishandling jsonb attribute reference |
| Date: | 2026-04-13 14:12:31 |
| Message-ID: | 822926.1776089551@sss.pgh.pa.us |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
PG Bug reporting form <noreply(at)postgresql(dot)org> writes:
> It appears the PL/pgSQL assignment operator := fails to maintain the
> stability of a jsonb attribute reference (from a function result) during a
> self-concatenation operation, whereas a SELECT wrapper forces correct
> materialization.
Your problem is operator precedence:
> v_payload := v_payload || tj->'delta'; -- The problematic line
> v_payload := (SELECT v_payload || (tj->'delta')); --This avoids the issue.
The second formulation works because of the "extra" parentheses;
that is,
v_payload || tj->'delta'
is parsed as
(v_payload || tj)->'delta'
but what you need is
v_payload || (tj->'delta')
Yeah, this isn't super intuitive, but all our non-SQL-standard
operators have the same precedence [1], so || and -> associate
left-to-right by default.
regards, tom lane
[1] https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-PRECEDENCE
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Tom Lane | 2026-04-13 14:22:02 | Re: BUG #19455: ALTER TABLE RENAME will rename a sequence |
| Previous Message | David G. Johnston | 2026-04-13 14:10:29 | Re: BUG #19454: PL/pgSQL mishandling jsonb attribute reference |