Support INSERT ... ON CONFLICT IGNORE
authorPeter Geoghegan <[email protected]>
Wed, 4 Mar 2015 03:44:42 +0000 (19:44 -0800)
committerPeter Geoghegan <[email protected]>
Mon, 20 Apr 2015 04:27:54 +0000 (21:27 -0700)
commit5ece9d204c09ebf0bb850448c37d51ffe7ec4aaf
tree6395efa4dc88343cc082388279e3316e92a9ac6f
parentf92fc4c95ddcc25978354a8248d3df22269201bc
Support INSERT ... ON CONFLICT IGNORE

This non-standard INSERT clause allows DML statement authors to specify
that in the event of each of any of the tuples being inserted
duplicating an existing tuple in terms of a value or set of values
constrained by a unique index, an alternative IGNORE path may be taken
(the tuple slot proposed for insertion is skipped without raising an
error).  The implementation loops until either an insert occurs, or a
conclusively committed conflicting tuple is determined to exist.

This is implemented using a new infrastructure called "speculative
insertion".  (The approach to "Value locking" presenting here follows
design #2, as described on the value locking Postgres Wiki page).

Users optionally specify a single unique index to take the alternative
path on, which is inferred from a set of user-supplied column names (or
expressions).

Speculative (heap) insertions are WAL-logged in two steps:  One record
relates to an initial intent to insert, while a second minimal record
simply affirms that that attempt was ultimately successful (i.e. no
conflicts where detected when inserting into constraint-related
indexes).  In this revision, logical decoding does not rely on the
presence of this second record to affirm that a speculative insertion
succeeded, though; it relies on the *absence* on an (internal) "super
deletion" record.
85 files changed:
contrib/pageinspect/heapfuncs.c
contrib/pg_stat_statements/pg_stat_statements.c
contrib/postgres_fdw/deparse.c
contrib/postgres_fdw/expected/postgres_fdw.out
contrib/postgres_fdw/postgres_fdw.c
contrib/postgres_fdw/postgres_fdw.h
contrib/postgres_fdw/sql/postgres_fdw.sql
doc/src/sgml/ddl.sgml
doc/src/sgml/fdwhandler.sgml
doc/src/sgml/keywords.sgml
doc/src/sgml/postgres-fdw.sgml
doc/src/sgml/ref/create_rule.sgml
doc/src/sgml/ref/create_table.sgml
doc/src/sgml/ref/create_view.sgml
doc/src/sgml/ref/insert.sgml
doc/src/sgml/ref/set_constraints.sgml
src/backend/access/common/heaptuple.c
src/backend/access/heap/heapam.c
src/backend/access/heap/hio.c
src/backend/access/heap/pruneheap.c
src/backend/access/heap/rewriteheap.c
src/backend/access/heap/tuptoaster.c
src/backend/access/nbtree/nbtinsert.c
src/backend/access/rmgrdesc/heapdesc.c
src/backend/catalog/index.c
src/backend/catalog/indexing.c
src/backend/commands/constraint.c
src/backend/commands/copy.c
src/backend/commands/explain.c
src/backend/commands/sequence.c
src/backend/executor/README
src/backend/executor/execMain.c
src/backend/executor/execUtils.c
src/backend/executor/nodeModifyTable.c
src/backend/executor/spi.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/nodeFuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/util/plancat.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/parse_clause.c
src/backend/parser/parse_collate.c
src/backend/replication/logical/decode.c
src/backend/replication/logical/reorderbuffer.c
src/backend/rewrite/rewriteHandler.c
src/backend/storage/lmgr/lmgr.c
src/backend/utils/adt/lockfuncs.c
src/backend/utils/time/tqual.c
src/include/access/heapam.h
src/include/access/heapam_xlog.h
src/include/access/hio.h
src/include/access/htup_details.h
src/include/catalog/index.h
src/include/executor/executor.h
src/include/nodes/execnodes.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/nodes/plannodes.h
src/include/nodes/primnodes.h
src/include/optimizer/plancat.h
src/include/optimizer/planmain.h
src/include/parser/kwlist.h
src/include/parser/parse_clause.h
src/include/replication/reorderbuffer.h
src/include/storage/block.h
src/include/storage/lmgr.h
src/include/storage/lock.h
src/include/storage/off.h
src/include/utils/snapshot.h
src/test/isolation/expected/insert-conflict-ignore.out [new file with mode: 0644]
src/test/isolation/isolation_schedule
src/test/isolation/specs/insert-conflict-ignore.spec [new file with mode: 0644]
src/test/regress/expected/insert_conflict.out [new file with mode: 0644]
src/test/regress/expected/rules.out
src/test/regress/expected/updatable_views.out
src/test/regress/parallel_schedule
src/test/regress/serial_schedule
src/test/regress/sql/insert_conflict.sql [new file with mode: 0644]
src/test/regress/sql/rules.sql
src/test/regress/sql/updatable_views.sql