| From: | Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com> |
|---|---|
| To: | hackerzheng666(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Subject: | Re: BUG #19632: RULE rewriting crashes with XX000 when RETURNING old/new references a system column |
| Date: | 2026-08-19 10:10:23 |
| Message-ID: | CAJTYsWUavFP1O-F=vsQofBG3o_gb3wjiwfUNjC4+Nt76kEAQVw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Hi,
On Wed, 19 Aug 2026 at 14:54, PG Bug reporting form <noreply(at)postgresql(dot)org>
wrote:
> The following bug has been logged on the website:
>
> Bug reference: 19632
> Logged by: Zheng Hacker
> Email address: hackerzheng666(at)gmail(dot)com
> PostgreSQL version: 19beta3
> Operating system: Linux x86_64
> Description:
>
> PostgreSQL version: 20devel (commit bdbf662, 2026-08-19)
> OS: Linux x86_64
>
> When a DML query with RETURNING old.<system_column> or
> RETURNING new.<system_column> (PG 20 new syntax) is rewritten
> through a RULE, the query rewriter cannot find replacement
> targetlist entries for system columns, hitting elog(ERROR) in
> rewriteManip.c.
>
> Reproducer:
>
> CREATE TABLE t (a int);
> INSERT INTO t VALUES (1);
> CREATE RULE t_del AS ON DELETE TO t
> DO INSTEAD UPDATE t SET a = -1 WHERE a = OLD.a RETURNING *;
>
> -- All of these crash with XX000:
> DELETE FROM t WHERE a = 1 RETURNING old.tableoid;
> -- ERROR: XX000: could not find replacement targetlist entry for attno -6
> -- LOCATION: ReplaceVarFromTargetList, rewriteManip.c:1884
>
> DELETE FROM t WHERE a = 1 RETURNING old.ctid; -- attno -1
> DELETE FROM t WHERE a = 1 RETURNING new.tableoid; -- attno -6
>
> -- Without the RULE, the same RETURNING clause works correctly:
> DROP RULE t_del ON t;
> DELETE FROM t WHERE a = 1 RETURNING old.tableoid; -- works fine
>
> Root cause: src/backend/rewrite/rewriteManip.c, function
> ReplaceVarFromTargetList (line 1884). When the rewriter processes
> the RULE's action to replace Vars, it iterates over the action's
> target list looking for an entry with matching resno. System
> columns have negative attribute numbers (e.g. tableoid = -6), but
> the RULE's RETURNING target list only contains user-defined columns
> (with positive resnos), so no match is found.
>
> The PG 20 old/new RETURNING syntax (var->varreturningtype !=
> VAR_RETURNING_DEFAULT) is handled AFTER the targetlist entry lookup
> succeeds (lines 1894-1910), so the code never reaches that logic
> for system columns.
>
> Affects all system columns (tableoid, ctid, xmin, cmin, xmax)
> through any RULE that uses DO INSTEAD.
>
> Found by automated SQL fuzzing.
> Credit: Zheng Wang, Yanjie Zhao, Yiyang Liu
>
Thanks for the report.
It seems all 19629 to 19632 bug is the same line of issue, and there
might be more such cases where ERRCODE is not added
across the tree. We can accumulate all such cases and do a single
commit for them.
Regards,
Ayush
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Ayush Tiwari | 2026-08-19 10:46:23 | Re: BUG #19631: currtid2() on a view with GROUP BY ctid crashes with XX000 |
| Previous Message | Andrey Rachitskiy | 2026-08-19 07:02:45 | Re: BUG #19626: Segmentation fault planning self-join IN subquery with LATERAL UNION ALL |