]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Disallow MERGE cleanly for foreign partitions
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Sat, 15 Oct 2022 17:24:26 +0000 (19:24 +0200)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Sat, 15 Oct 2022 17:24:26 +0000 (19:24 +0200)
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

contrib/postgres_fdw/expected/postgres_fdw.out
contrib/postgres_fdw/sql/postgres_fdw.sql
src/backend/optimizer/plan/createplan.c

index 1ca248f33791789accbaa1ad72339106bcee7059..499bf503866a95a1c1de08c1d23371d892a65975 100644 (file)
@@ -8251,6 +8251,11 @@ select tableoid::regclass, * FROM remp2;
 (3 rows)
 
 delete from itrtest;
+-- MERGE ought to fail cleanly
+merge into itrtest using (select 1, 'foo') as source on (true)
+  when matched then do nothing;
+ERROR:  cannot execute MERGE on relation "remp1"
+DETAIL:  This operation is not supported for foreign tables.
 create unique index loct1_idx on loct1 (a);
 -- DO NOTHING without an inference specification is supported
 insert into itrtest values (1, 'foo') on conflict do nothing returning *;
index 0356f081e7207cdc1489b3a4627566ec6be3669b..1561297fc3cb530ee807519c76867946c08f7f82 100644 (file)
@@ -2194,6 +2194,10 @@ select tableoid::regclass, * FROM remp2;
 
 delete from itrtest;
 
+-- MERGE ought to fail cleanly
+merge into itrtest using (select 1, 'foo') as source on (true)
+  when matched then do nothing;
+
 create unique index loct1_idx on loct1 (a);
 
 -- DO NOTHING without an inference specification is supported
index 76606faa3e4918339769d0f93d33f7ba62d0815f..1bc59c94578fc9ef4df7c4d2ecd012ca5ef6e60a 100644 (file)
@@ -7084,12 +7084,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