diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-07-29 20:56:21 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-07-29 20:56:21 +0000 |
commit | 25d9bf2e3e66ee2e546c5c523d148ecab6ee1dcc (patch) | |
tree | b0dee0f1d6111fd6658d432ec30e5ddb88adc02f /src/include/access | |
parent | 850490579318ff52097eec92ce535357dd0c7a3a (diff) | |
download | postgresql-25d9bf2e3e66ee2e546c5c523d148ecab6ee1dcc.tar.gz postgresql-25d9bf2e3e66ee2e546c5c523d148ecab6ee1dcc.zip |
Support deferrable uniqueness constraints.
The current implementation fires an AFTER ROW trigger for each tuple that
looks like it might be non-unique according to the index contents at the
time of insertion. This works well as long as there aren't many conflicts,
but won't scale to massive unique-key reassignments. Improving that case
is a TODO item.
Dean Rasheed
Diffstat (limited to 'src/include/access')
-rw-r--r-- | src/include/access/genam.h | 32 | ||||
-rw-r--r-- | src/include/access/nbtree.h | 6 |
2 files changed, 33 insertions, 5 deletions
diff --git a/src/include/access/genam.h b/src/include/access/genam.h index bf3fe96e26d..a8c0e029296 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.78 2009/06/11 14:49:08 momjian Exp $ + * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.79 2009/07/29 20:56:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -85,6 +85,34 @@ typedef bool (*IndexBulkDeleteCallback) (ItemPointer itemptr, void *state); typedef struct IndexScanDescData *IndexScanDesc; typedef struct SysScanDescData *SysScanDesc; +/* + * Enumeration specifying the type of uniqueness check to perform in + * index_insert(). + * + * UNIQUE_CHECK_YES is the traditional Postgres immediate check, possibly + * blocking to see if a conflicting transaction commits. + * + * For deferrable unique constraints, UNIQUE_CHECK_PARTIAL is specified at + * insertion time. The index AM should test if the tuple is unique, but + * should not throw error, block, or prevent the insertion if the tuple + * appears not to be unique. We'll recheck later when it is time for the + * constraint to be enforced. The AM must return true if the tuple is + * known unique, false if it is possibly non-unique. In the "true" case + * it is safe to omit the later recheck. + * + * When it is time to recheck the deferred constraint, a pseudo-insertion + * call is made with UNIQUE_CHECK_EXISTING. The tuple is already in the + * index in this case, so it should not be inserted again. Rather, just + * check for conflicting live tuples (possibly blocking). + */ +typedef enum IndexUniqueCheck +{ + UNIQUE_CHECK_NO, /* Don't do any uniqueness checking */ + UNIQUE_CHECK_YES, /* Enforce uniqueness at insertion time */ + UNIQUE_CHECK_PARTIAL, /* Test uniqueness, but no error */ + UNIQUE_CHECK_EXISTING /* Check if existing tuple is unique */ +} IndexUniqueCheck; + /* * generalized index_ interface routines (in indexam.c) @@ -103,7 +131,7 @@ extern bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, - bool check_uniqueness); + IndexUniqueCheck checkUnique); extern IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 1d3e42d99bc..ed5ec57e47f 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.124 2009/06/11 14:49:08 momjian Exp $ + * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.125 2009/07/29 20:56:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -517,8 +517,8 @@ extern Datum btoptions(PG_FUNCTION_ARGS); /* * prototypes for functions in nbtinsert.c */ -extern void _bt_doinsert(Relation rel, IndexTuple itup, - bool index_is_unique, Relation heapRel); +extern bool _bt_doinsert(Relation rel, IndexTuple itup, + IndexUniqueCheck checkUnique, Relation heapRel); extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access); extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, BTStack stack, bool is_root, bool is_only); |