| From: | Tender Wang <tndrwang(at)gmail(dot)com> |
|---|---|
| To: | Amit Langote <amitlangote09(at)gmail(dot)com> |
| Cc: | David Rowley <dgrowleyml(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Kirill Reshke <reshkekirill(at)gmail(dot)com>, jian he <jian(dot)universality(at)gmail(dot)com>, exclusion(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Subject: | Re: BUG #19099: Conditional DELETE from partitioned table with non-updatable partition raises internal error |
| Date: | 2025-11-30 05:59:59 |
| Message-ID: | CAHewXNnD0744Vykj6ujE5c=rRP=61sh7K154uNdgEaTmJrRegQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Amit Langote <amitlangote09(at)gmail(dot)com> 于2025年11月26日周三 19:27写道:
> On Thu, Nov 6, 2025 at 7:00 PM Amit Langote <amitlangote09(at)gmail(dot)com>
> wrote:
> > Among those options, I considered the following block, which adds a
> > ctid for the partitioned root table when it’s the only target in the
> > query after partition pruning removes all child tables due to the
> > WHERE false condition in the problematic case:
> >
> > /*
> > * Ordinarily, we expect that leaf result relation(s) will have
> added some
> > * ROWID_VAR Vars to the query. However, it's possible that
> constraint
> > * exclusion suppressed every leaf relation. The executor will get
> upset
> > * if the plan has no row identity columns at all, even though it
> will
> > * certainly process no rows. Handle this edge case by re-opening
> the top
> > * result relation and adding the row identity columns it would have
> used,
> > * as preprocess_targetlist() would have done if it weren't marked
> "inh".
> > * Then re-run build_base_rel_tlists() to ensure that the added
> columns
> > * get propagated to the relation's reltarget. (This is a bit ugly,
> but
> > * it seems better to confine the ugliness and extra cycles to this
> > * unusual corner case.)
> > */
> > if (root->row_identity_vars == NIL)
> > {
> > Relation target_relation;
> >
> > target_relation = table_open(target_rte->relid, NoLock);
> > add_row_identity_columns(root, result_relation,
> > target_rte, target_relation);
> > table_close(target_relation, NoLock);
> > build_base_rel_tlists(root, root->processed_tlist);
> > /* There are no ROWID_VAR Vars in this case, so we're done. */
> > return;
> > }
> >
> > If enable_partition_pruning is off, root->row_identity_vars already
> > contains a RowIdentityVarInfo entry for the tableoid Var that was
> > added while processing the foreign-table child partition. Because of
> > that, the if (root->row_identity_vars == NIL) block doesn’t run in
> > this case, so it won’t add any row identity columns such as ctid for
> > the partitioned root table.
> >
> > In theory, we could prevent the planner from adding tableoid in the
> > first place when the child table doesn’t support any row identity
> > column -- or worse, doesn’t support the UPDATE/DELETE/MERGE command at
> > all -- but doing so would require changing the order in which tableoid
> > appears in root->processed_tlist. That would be too invasive for a
> > back-patch.
>
> I’ve implemented this alternative as well -- the version that prevents
> adding tableoid when no other row-identity columns are added for the
> child. That allows to keep root->row_identity_vars empty so the
> dummy-root path can add ctid as intended by the above code block of
> distribute_row_identity_vars().
>
> This provides an alternative approach to compare against the other patch.
>
> --
> Thanks, Amit Langote
>
I apply the patch, and I find it forgets to update the diff for
postgres_fdw.
So I add it in the v2 patch.
With this patch, the targetlists are identical whether or not
enable_partition_pruning is on.
In my first email on this thread, to avoid adding "tableoid", I tried to
add the following codes:
"(childrte->relkind != RELKIND_PARTITIONED_TABLE && childrte->relkind
!= RELKIND_FOREIGN_TABLE)"
in expand_single_inheritance_child().
But this didn't work for all test cases. It would trigger an assert failure
in fix_scan_expr_walker():
Assert(!(IsA(node, Var) && ((Var *) node)->varno == ROWID_VAR));
Your patch is much better than mine.
--
Thanks,
Tender Wang
| Attachment | Content-Type | Size |
|---|---|---|
| v2-0001-Fix-row-identity-handling-for-dummy-partitioned-r.patch | text/plain | 43.1 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Devrim Gündüz | 2025-11-30 20:50:00 | Re: BUG #19337: Errors during downloading metadata for repository pgdg-rhel9-extras |
| Previous Message | David Rowley | 2025-11-29 23:56:34 | Re: Segmentation fault in var_is_nonnullable when running query with COUNT() on 42473b3b |