diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2023-02-20 12:06:30 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2023-02-20 12:06:30 -0500 |
commit | c6c3b3bc3de1be016de646403b923c1c8a2521cb (patch) | |
tree | 3c9e2d161737785c00ac8791d761d33fbd9cc286 /src/backend/optimizer/plan/createplan.c | |
parent | a316a3bc6d3f57e3fe0d287d11eb4f114388b1b6 (diff) | |
download | postgresql-c6c3b3bc3de1be016de646403b923c1c8a2521cb.tar.gz postgresql-c6c3b3bc3de1be016de646403b923c1c8a2521cb.zip |
Remove gratuitous assumptions about what make_modifytable can see.
For no clearly good reason, make_modifytable assumed that it
could not reach its get-the-FDW-info-the-hard-way path in MERGE.
It's currently possible to demonstrate that assertion failing,
which seems to be due to an upstream planner bug; but there's no
good reason to do it like this at all. Let's apply the principle
of separation of concerns and make the MERGE check separately,
after getting or not getting the fdwroutine pointer.
Per report from Alexander Lakhin. No test case, since I think
the potential test condition will go away soon.
Discussion: https://postgr.es/m/36bee393-b351-16ac-93b2-d46d83637e45@gmail.com
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 134130476e4..fa09a6103b1 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -7093,39 +7093,37 @@ make_modifytable(PlannerInfo *root, Plan *subplan, RelOptInfo *resultRel = root->simple_rel_array[rti]; fdwroutine = resultRel->fdwroutine; - - /* - * MERGE is not currently supported for foreign tables and we - * already checked when the table mentioned in the query is - * foreign; but we can still get here if a partitioned table has a - * foreign table as partition. Disallow that now, to avoid an - * uglier error message later. - */ - if (operation == CMD_MERGE && fdwroutine != NULL) - { - RangeTblEntry *rte = root->simple_rte_array[rti]; - - ereport(ERROR, - errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot execute MERGE on relation \"%s\"", - get_rel_name(rte->relid)), - errdetail_relkind_not_supported(rte->relkind)); - } - } else { RangeTblEntry *rte = planner_rt_fetch(rti, root); - Assert(rte->rtekind == RTE_RELATION); - Assert(operation != CMD_MERGE); - if (rte->relkind == RELKIND_FOREIGN_TABLE) + if (rte->rtekind == RTE_RELATION && + rte->relkind == RELKIND_FOREIGN_TABLE) fdwroutine = GetFdwRoutineByRelId(rte->relid); else fdwroutine = NULL; } /* + * MERGE is not currently supported for foreign tables. We already + * checked that when the table mentioned in the query is foreign; but + * we can still get here if a partitioned table has a foreign table as + * partition. Disallow that now, to avoid an uglier error message + * later. + */ + if (operation == CMD_MERGE && fdwroutine != NULL) + { + RangeTblEntry *rte = planner_rt_fetch(rti, root); + + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot execute MERGE on relation \"%s\"", + get_rel_name(rte->relid)), + errdetail_relkind_not_supported(rte->relkind)); + } + + /* * Try to modify the foreign table directly if (1) the FDW provides * callback functions needed for that and (2) there are no local * structures that need to be run for each modified row: row-level |