diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2022-10-15 19:24:26 +0200 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2022-10-15 19:24:26 +0200 |
commit | cba4e78f3599f7edc3fb53d1b094f037fbb8158a (patch) | |
tree | e25faddf0e60731a5bda39596a31ccad2728326e /src/backend/optimizer/plan/createplan.c | |
parent | 1054c604bcdbae5de42beab2f60da7b0067cd4bb (diff) | |
download | postgresql-cba4e78f3599f7edc3fb53d1b094f037fbb8158a.tar.gz postgresql-cba4e78f3599f7edc3fb53d1b094f037fbb8158a.zip |
Disallow MERGE cleanly for foreign partitions
While directly targetting a foreign table with MERGE was already
expressly forbidden, we failed to catch the case of a partitioned table
that has a foreign table as a partition; and the result if you try is an
incomprehensible error. Fix that by adding a specific check.
Backpatch to 15.
Reported-by: Tatsuhiro Nakamori <bt22nakamorit@oss.nttdata.com>
Discussion: https://postgr.es/m/bt22nakamorit@oss.nttdata.com
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index ab4d8e201df..ac86ce90033 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -7078,12 +7078,32 @@ 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) fdwroutine = GetFdwRoutineByRelId(rte->relid); else |