Re: AW: AW: BUG #18147: ERROR: invalid perminfoindex 0 in RTE with relid xxxxx
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: Amit Langote <amitlangote09@gmail.com>
Cc: Hans Buschmann <buschmann@nidsa.net>, Peter Geoghegan <pg@bowt.ie>,
"David G. Johnston" <david.g.johnston@gmail.com>,
"pgsql-bugs@lists.postgresql.org" <pgsql-bugs@lists.postgresql.org>
Date: 2023-10-23T20:59:25Z
Lists: pgsql-bugs
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Prevent duplicate RTEPermissionInfo for plain-inheritance parents
- 01575ad788e3 17.0 landed
- 178ee1d858d8 16.1 landed
-
Fix problems when a plain-inheritance parent table is excluded.
- b1444a09dcb5 16.1 landed
- 8f4a6b9e4f5b 14.10 landed
- 1268e7378123 15.5 landed
- 387f9ed0a083 17.0 landed
-
Doc: indexUnchanged is strictly a hint.
- 74e5ea1e002f 17.0 landed
- cf89d3052d62 16.1 landed
- be2502947f29 15.5 landed
- df73ca35144a 14.10 landed
I wrote: > So the proximate problem is that we're trying to fetch an updatedCols > bitmapset for a child table that has no permissions checks to make > and thus doesn't need an RTEPermissionInfo, so its perminfoindex is > zero. It might be that this relinfo should have ri_RootResultRelInfo > set, but it doesn't. That seems to be a fairly good guess. I was able to reduce the test case to this: drop table if exists t1 cascade; create table t1 (f1 int, f2 int, f3 int , check (f1 < 10) no inherit ); create table t2 () inherits(t1); insert into t2 select i, i+1, 0 from generate_series(1,1000) i; create index on t2(f1,f2); update t1 set f3 = 11 where f1 = 12 and f2 = 13; You don't see the failure without the check constraint on t1. What is happening is that with that, we remove t1 from the plan entirely, causing us to think that t2 is the root target relation, and then things blow up because the root should have an RTEPermissionInfo and doesn't. The place where things start to go off the rails is in ExecInitModifyTable: * If it's a partitioned table, the root partition doesn't appear * elsewhere in the plan and its RT index is given explicitly in * node->rootRelation. Otherwise (i.e. table inheritance) the target * relation is the first relation in the node->resultRelations list. node->resultRelations contains only t2, so boom. Maybe we could fix this by setting ModifyTable.rootRelation to the parent relation in the plain-inheritance case not only the partitioned case; but I've not investigated what else might be expecting it to be set only for partitions. According to this understanding, the root cause is quite old and the RTEPermissionInfo failure just exposes it in an obvious way. I wonder whether we can find related cases that misbehave even before v16. > (I haven't looked into exactly why it's so hard to reach this > error. Seems like any inherited UPDATE is at risk, so there > must be additional gating factors to explain why we've not > noticed this before.) I haven't tracked that down yet, but I did find that without the CHECK constraint we don't reach index_unchanged_by_update at all in repeat executions of the problem query. This is because ExecUpdateEpilogue sees updateCxt->updateIndexes == TU_None and thinks it doesn't have to do anything. This seems a bit suspicious in its own right. Maybe it's okay, because the updates would be HOT in this test case, but the first one should be HOT too. It smells like something is being cached across queries that probably should not be. regards, tom lane