aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2019-03-25 16:52:55 -0700
committerAndres Freund <andres@anarazel.de>2019-03-25 16:52:55 -0700
commit71bdc99d0d7c3b2d73fa04fb2ff80870ce1305f7 (patch)
tree543735343b99a2d3ebd2752130f26747d9f14eb3 /src/backend/access
parentaa1419e63f85b23503076bb4b6413aca30b535fe (diff)
downloadpostgresql-71bdc99d0d7c3b2d73fa04fb2ff80870ce1305f7.tar.gz
postgresql-71bdc99d0d7c3b2d73fa04fb2ff80870ce1305f7.zip
tableam: Add helper for indexes to check if a corresponding table tuples exist.
This is, likely exclusively, useful to verify that conflicts detected in a unique index are with live tuples, rather than dead ones. Author: Andres Freund Discussion: https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/nbtree/nbtinsert.c17
-rw-r--r--src/backend/access/nbtree/nbtsort.c2
-rw-r--r--src/backend/access/table/tableam.c34
3 files changed, 45 insertions, 8 deletions
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 2c98405aac8..96b7593fc1c 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -15,9 +15,9 @@
#include "postgres.h"
-#include "access/heapam.h"
#include "access/nbtree.h"
#include "access/nbtxlog.h"
+#include "access/tableam.h"
#include "access/transam.h"
#include "access/xloginsert.h"
#include "miscadmin.h"
@@ -431,12 +431,14 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
}
/*
- * We check the whole HOT-chain to see if there is any tuple
- * that satisfies SnapshotDirty. This is necessary because we
- * have just a single index entry for the entire chain.
+ * Check if there's any table tuples for this index entry
+ * satisfying SnapshotDirty. This is necessary because for AMs
+ * with optimizations like heap's HOT, we have just a single
+ * index entry for the entire chain.
*/
- else if (heap_hot_search(&htid, heapRel, &SnapshotDirty,
- &all_dead))
+ else if (table_index_fetch_tuple_check(heapRel, &htid,
+ &SnapshotDirty,
+ &all_dead))
{
TransactionId xwait;
@@ -489,7 +491,8 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
* entry.
*/
htid = itup->t_tid;
- if (heap_hot_search(&htid, heapRel, SnapshotSelf, NULL))
+ if (table_index_fetch_tuple_check(heapRel, &htid,
+ SnapshotSelf, NULL))
{
/* Normal case --- it's still live */
}
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 2762a2d5485..46e0831834e 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -57,10 +57,10 @@
#include "postgres.h"
-#include "access/heapam.h"
#include "access/nbtree.h"
#include "access/parallel.h"
#include "access/relscan.h"
+#include "access/table.h"
#include "access/tableam.h"
#include "access/xact.h"
#include "access/xlog.h"
diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c
index b1e31982918..8ad4c629432 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -177,6 +177,40 @@ table_beginscan_parallel(Relation relation, ParallelTableScanDesc parallel_scan)
/* ----------------------------------------------------------------------------
+ * Index scan related functions.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ * To perform that check simply start an index scan, create the necessary
+ * slot, do the heap lookup, and shut everything down again. This could be
+ * optimized, but is unlikely to matter from a performance POV. If there
+ * frequently are live index pointers also matching a unique index key, the
+ * CPU overhead of this routine is unlikely to matter.
+ */
+bool
+table_index_fetch_tuple_check(Relation rel,
+ ItemPointer tid,
+ Snapshot snapshot,
+ bool *all_dead)
+{
+ IndexFetchTableData *scan;
+ TupleTableSlot *slot;
+ bool call_again = false;
+ bool found;
+
+ slot = table_slot_create(rel, NULL);
+ scan = table_index_fetch_begin(rel);
+ found = table_index_fetch_tuple(scan, tid, snapshot, slot, &call_again,
+ all_dead);
+ table_index_fetch_end(scan);
+ ExecDropSingleTupleTableSlot(slot);
+
+ return found;
+}
+
+
+/* ----------------------------------------------------------------------------
* Functions to make modifications a bit simpler.
* ----------------------------------------------------------------------------
*/