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
This commit is contained in:
parent
1054c604bc
commit
cba4e78f35
@ -8284,6 +8284,11 @@ select tableoid::regclass, * FROM remp2;
|
|||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
delete from itrtest;
|
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);
|
create unique index loct1_idx on loct1 (a);
|
||||||
-- DO NOTHING without an inference specification is supported
|
-- DO NOTHING without an inference specification is supported
|
||||||
insert into itrtest values (1, 'foo') on conflict do nothing returning *;
|
insert into itrtest values (1, 'foo') on conflict do nothing returning *;
|
||||||
|
@ -2207,6 +2207,10 @@ select tableoid::regclass, * FROM remp2;
|
|||||||
|
|
||||||
delete from itrtest;
|
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);
|
create unique index loct1_idx on loct1 (a);
|
||||||
|
|
||||||
-- DO NOTHING without an inference specification is supported
|
-- DO NOTHING without an inference specification is supported
|
||||||
|
@ -7078,12 +7078,32 @@ make_modifytable(PlannerInfo *root, Plan *subplan,
|
|||||||
RelOptInfo *resultRel = root->simple_rel_array[rti];
|
RelOptInfo *resultRel = root->simple_rel_array[rti];
|
||||||
|
|
||||||
fdwroutine = resultRel->fdwroutine;
|
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
|
else
|
||||||
{
|
{
|
||||||
RangeTblEntry *rte = planner_rt_fetch(rti, root);
|
RangeTblEntry *rte = planner_rt_fetch(rti, root);
|
||||||
|
|
||||||
Assert(rte->rtekind == RTE_RELATION);
|
Assert(rte->rtekind == RTE_RELATION);
|
||||||
|
Assert(operation != CMD_MERGE);
|
||||||
if (rte->relkind == RELKIND_FOREIGN_TABLE)
|
if (rte->relkind == RELKIND_FOREIGN_TABLE)
|
||||||
fdwroutine = GetFdwRoutineByRelId(rte->relid);
|
fdwroutine = GetFdwRoutineByRelId(rte->relid);
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user