mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-22 22:37:01 +08:00
Fix bogus ctid requirement for dummy-root partitioned targets
ExecInitModifyTable() unconditionally required a ctid junk column even when the target was a partitioned table. This led to spurious "could not find junk ctid column" errors when all children were excluded and only the dummy root result relation remained. A partitioned table only appears in the result relations list when all leaf partitions have been pruned, leaving the dummy root as the sole entry. Assert this invariant (nrels == 1) and skip the ctid requirement. Also adjust ExecModifyTable() to tolerate invalid ri_RowIdAttNo for partitioned tables, which is safe since no rows will be processed in this case. Bug: #19099 Reported-by: Alexander Lakhin <exclusion@gmail.com> Author: Amit Langote <amitlangote09@gmail.com> Reviewed-by: Tender Wang <tndrwang@gmail.com> Reviewed-by: Kirill Reshke <reshkekirill@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/19099-e05dcfa022fe553d%40postgresql.org Backpatch-through: 14
This commit is contained in:
@ -3916,8 +3916,12 @@ ExecModifyTable(PlanState *pstate)
|
||||
relkind == RELKIND_MATVIEW ||
|
||||
relkind == RELKIND_PARTITIONED_TABLE)
|
||||
{
|
||||
/* ri_RowIdAttNo refers to a ctid attribute */
|
||||
Assert(AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo));
|
||||
/*
|
||||
* ri_RowIdAttNo refers to a ctid attribute. See the comment
|
||||
* in ExecInitModifyTable().
|
||||
*/
|
||||
Assert(AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo) ||
|
||||
relkind == RELKIND_PARTITIONED_TABLE);
|
||||
datum = ExecGetJunkAttribute(slot,
|
||||
resultRelInfo->ri_RowIdAttNo,
|
||||
&isNull);
|
||||
@ -4307,7 +4311,16 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
{
|
||||
resultRelInfo->ri_RowIdAttNo =
|
||||
ExecFindJunkAttributeInTlist(subplan->targetlist, "ctid");
|
||||
if (!AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo))
|
||||
|
||||
/*
|
||||
* For heap relations, a ctid junk attribute must be present.
|
||||
* Partitioned tables should only appear here when all leaf
|
||||
* partitions were pruned, in which case no rows can be
|
||||
* produced and ctid is not needed.
|
||||
*/
|
||||
if (relkind == RELKIND_PARTITIONED_TABLE)
|
||||
Assert(nrels == 1);
|
||||
else if (!AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo))
|
||||
elog(ERROR, "could not find junk ctid column");
|
||||
}
|
||||
else if (relkind == RELKIND_FOREIGN_TABLE)
|
||||
|
||||
Reference in New Issue
Block a user