Revert "Allow ON CONFLICT .. DO NOTHING on a partitioned table."

This reverts commit 8355a011a0, which
turns out to have been a misguided effort.  We can't really support
this in a partitioning hierarchy after all for exactly the reasons
stated in the documentation removed by that commit.  It's still
possible to use ON CONFLICT .. DO NOTHING (or for that matter ON
CONFLICT .. DO UPDATE) on individual partitions if desired, but
but to allow this on a partitioned table implies that we have some
way of evaluating uniqueness across the whole partitioning
hierarchy, which is false.

Shinoda Noriyoshi noticed that the old code was crashing (which we
could fix, though not in a nice way) and Amit Langote realized
that this was indicative of a fundamental problem with the commit
being reverted here.

Discussion: http://postgr.es/m/ff3dc21d-7204-c09c-50ac-cf11a8c45c81@lab.ntt.co.jp
This commit is contained in:
Robert Haas 2017-03-31 16:47:38 -04:00
parent c94e6942ce
commit f05230752d
4 changed files with 10 additions and 26 deletions

View File

@ -3854,12 +3854,8 @@ ANALYZE measurement;
<listitem>
<para>
Using the <literal>ON CONFLICT</literal> clause with partitioned tables
will cause an error if <literal>DO UPDATE</literal> is specified as the
alternative action, because unique or exclusion constraints can only be
created on individual partitions. There is no support for enforcing
uniqueness (or an exclusion constraint) across an entire partitioning
hierarchy.
<command>INSERT</command> statements with <literal>ON CONFLICT</>
clause are currently not allowed on partitioned tables.
</para>
</listitem>

View File

@ -842,8 +842,16 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
/* Process ON CONFLICT, if any. */
if (stmt->onConflictClause)
{
/* Bail out if target relation is partitioned table */
if (pstate->p_target_rangetblentry->relkind == RELKIND_PARTITIONED_TABLE)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("ON CONFLICT clause is not supported with partitioned tables")));
qry->onConflict = transformOnConflictClause(pstate,
stmt->onConflictClause);
}
/*
* If we have a RETURNING clause, we need to add the target relation to

View File

@ -786,13 +786,3 @@ select * from selfconflict;
(3 rows)
drop table selfconflict;
-- check that the following works:
-- insert into partitioned_table on conflict do nothing
create table parted_conflict_test (a int, b char) partition by list (a);
create table parted_conflict_test_1 partition of parted_conflict_test for values in (1);
insert into parted_conflict_test values (1, 'a') on conflict do nothing;
insert into parted_conflict_test values (1, 'a') on conflict do nothing;
-- however, on conflict do update not supported yet
insert into parted_conflict_test values (1) on conflict (a) do update set b = excluded.b where excluded.a = 1;
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
drop table parted_conflict_test, parted_conflict_test_1;

View File

@ -471,13 +471,3 @@ commit;
select * from selfconflict;
drop table selfconflict;
-- check that the following works:
-- insert into partitioned_table on conflict do nothing
create table parted_conflict_test (a int, b char) partition by list (a);
create table parted_conflict_test_1 partition of parted_conflict_test for values in (1);
insert into parted_conflict_test values (1, 'a') on conflict do nothing;
insert into parted_conflict_test values (1, 'a') on conflict do nothing;
-- however, on conflict do update not supported yet
insert into parted_conflict_test values (1) on conflict (a) do update set b = excluded.b where excluded.a = 1;
drop table parted_conflict_test, parted_conflict_test_1;