PostgreSQL Source Code  git master
execIndexing.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * execIndexing.c
4  * routines for inserting index tuples and enforcing unique and
5  * exclusion constraints.
6  *
7  * ExecInsertIndexTuples() is the main entry point. It's called after
8  * inserting a tuple to the heap, and it inserts corresponding index tuples
9  * into all indexes. At the same time, it enforces any unique and
10  * exclusion constraints:
11  *
12  * Unique Indexes
13  * --------------
14  *
15  * Enforcing a unique constraint is straightforward. When the index AM
16  * inserts the tuple to the index, it also checks that there are no
17  * conflicting tuples in the index already. It does so atomically, so that
18  * even if two backends try to insert the same key concurrently, only one
19  * of them will succeed. All the logic to ensure atomicity, and to wait
20  * for in-progress transactions to finish, is handled by the index AM.
21  *
22  * If a unique constraint is deferred, we request the index AM to not
23  * throw an error if a conflict is found. Instead, we make note that there
24  * was a conflict and return the list of indexes with conflicts to the
25  * caller. The caller must re-check them later, by calling index_insert()
26  * with the UNIQUE_CHECK_EXISTING option.
27  *
28  * Exclusion Constraints
29  * ---------------------
30  *
31  * Exclusion constraints are different from unique indexes in that when the
32  * tuple is inserted to the index, the index AM does not check for
33  * duplicate keys at the same time. After the insertion, we perform a
34  * separate scan on the index to check for conflicting tuples, and if one
35  * is found, we throw an error and the transaction is aborted. If the
36  * conflicting tuple's inserter or deleter is in-progress, we wait for it
37  * to finish first.
38  *
39  * There is a chance of deadlock, if two backends insert a tuple at the
40  * same time, and then perform the scan to check for conflicts. They will
41  * find each other's tuple, and both try to wait for each other. The
42  * deadlock detector will detect that, and abort one of the transactions.
43  * That's fairly harmless, as one of them was bound to abort with a
44  * "duplicate key error" anyway, although you get a different error
45  * message.
46  *
47  * If an exclusion constraint is deferred, we still perform the conflict
48  * checking scan immediately after inserting the index tuple. But instead
49  * of throwing an error if a conflict is found, we return that information
50  * to the caller. The caller must re-check them later by calling
51  * check_exclusion_constraint().
52  *
53  * Speculative insertion
54  * ---------------------
55  *
56  * Speculative insertion is a two-phase mechanism used to implement
57  * INSERT ... ON CONFLICT DO UPDATE/NOTHING. The tuple is first inserted
58  * to the heap and update the indexes as usual, but if a constraint is
59  * violated, we can still back out the insertion without aborting the whole
60  * transaction. In an INSERT ... ON CONFLICT statement, if a conflict is
61  * detected, the inserted tuple is backed out and the ON CONFLICT action is
62  * executed instead.
63  *
64  * Insertion to a unique index works as usual: the index AM checks for
65  * duplicate keys atomically with the insertion. But instead of throwing
66  * an error on a conflict, the speculatively inserted heap tuple is backed
67  * out.
68  *
69  * Exclusion constraints are slightly more complicated. As mentioned
70  * earlier, there is a risk of deadlock when two backends insert the same
71  * key concurrently. That was not a problem for regular insertions, when
72  * one of the transactions has to be aborted anyway, but with a speculative
73  * insertion we cannot let a deadlock happen, because we only want to back
74  * out the speculatively inserted tuple on conflict, not abort the whole
75  * transaction.
76  *
77  * When a backend detects that the speculative insertion conflicts with
78  * another in-progress tuple, it has two options:
79  *
80  * 1. back out the speculatively inserted tuple, then wait for the other
81  * transaction, and retry. Or,
82  * 2. wait for the other transaction, with the speculatively inserted tuple
83  * still in place.
84  *
85  * If two backends insert at the same time, and both try to wait for each
86  * other, they will deadlock. So option 2 is not acceptable. Option 1
87  * avoids the deadlock, but it is prone to a livelock instead. Both
88  * transactions will wake up immediately as the other transaction backs
89  * out. Then they both retry, and conflict with each other again, lather,
90  * rinse, repeat.
91  *
92  * To avoid the livelock, one of the backends must back out first, and then
93  * wait, while the other one waits without backing out. It doesn't matter
94  * which one backs out, so we employ an arbitrary rule that the transaction
95  * with the higher XID backs out.
96  *
97  *
98  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
99  * Portions Copyright (c) 1994, Regents of the University of California
100  *
101  *
102  * IDENTIFICATION
103  * src/backend/executor/execIndexing.c
104  *
105  *-------------------------------------------------------------------------
106  */
107 #include "postgres.h"
108 
109 #include "access/genam.h"
110 #include "access/relscan.h"
111 #include "access/tableam.h"
112 #include "access/xact.h"
113 #include "catalog/index.h"
114 #include "executor/executor.h"
115 #include "nodes/nodeFuncs.h"
116 #include "storage/lmgr.h"
117 #include "utils/snapmgr.h"
118 
119 /* waitMode argument to check_exclusion_or_unique_constraint() */
120 typedef enum
121 {
126 
128  IndexInfo *indexInfo,
129  ItemPointer tupleid,
130  Datum *values, bool *isnull,
131  EState *estate, bool newIndex,
132  CEOUC_WAIT_MODE waitMode,
133  bool errorOK,
134  ItemPointer conflictTid);
135 
136 static bool index_recheck_constraint(Relation index, Oid *constr_procs,
137  Datum *existing_values, bool *existing_isnull,
138  Datum *new_values);
139 
140 /* ----------------------------------------------------------------
141  * ExecOpenIndices
142  *
143  * Find the indices associated with a result relation, open them,
144  * and save information about them in the result ResultRelInfo.
145  *
146  * At entry, caller has already opened and locked
147  * resultRelInfo->ri_RelationDesc.
148  * ----------------------------------------------------------------
149  */
150 void
151 ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
152 {
153  Relation resultRelation = resultRelInfo->ri_RelationDesc;
154  List *indexoidlist;
155  ListCell *l;
156  int len,
157  i;
158  RelationPtr relationDescs;
159  IndexInfo **indexInfoArray;
160 
161  resultRelInfo->ri_NumIndices = 0;
162 
163  /* fast path if no indexes */
164  if (!RelationGetForm(resultRelation)->relhasindex)
165  return;
166 
167  /*
168  * Get cached list of index OIDs
169  */
170  indexoidlist = RelationGetIndexList(resultRelation);
171  len = list_length(indexoidlist);
172  if (len == 0)
173  return;
174 
175  /*
176  * allocate space for result arrays
177  */
178  relationDescs = (RelationPtr) palloc(len * sizeof(Relation));
179  indexInfoArray = (IndexInfo **) palloc(len * sizeof(IndexInfo *));
180 
181  resultRelInfo->ri_NumIndices = len;
182  resultRelInfo->ri_IndexRelationDescs = relationDescs;
183  resultRelInfo->ri_IndexRelationInfo = indexInfoArray;
184 
185  /*
186  * For each index, open the index relation and save pg_index info. We
187  * acquire RowExclusiveLock, signifying we will update the index.
188  *
189  * Note: we do this even if the index is not indisready; it's not worth
190  * the trouble to optimize for the case where it isn't.
191  */
192  i = 0;
193  foreach(l, indexoidlist)
194  {
195  Oid indexOid = lfirst_oid(l);
196  Relation indexDesc;
197  IndexInfo *ii;
198 
199  indexDesc = index_open(indexOid, RowExclusiveLock);
200 
201  /* extract index key information from the index's pg_index info */
202  ii = BuildIndexInfo(indexDesc);
203 
204  /*
205  * If the indexes are to be used for speculative insertion, add extra
206  * information required by unique index entries.
207  */
208  if (speculative && ii->ii_Unique)
209  BuildSpeculativeIndexInfo(indexDesc, ii);
210 
211  relationDescs[i] = indexDesc;
212  indexInfoArray[i] = ii;
213  i++;
214  }
215 
216  list_free(indexoidlist);
217 }
218 
219 /* ----------------------------------------------------------------
220  * ExecCloseIndices
221  *
222  * Close the index relations stored in resultRelInfo
223  * ----------------------------------------------------------------
224  */
225 void
227 {
228  int i;
229  int numIndices;
230  RelationPtr indexDescs;
231 
232  numIndices = resultRelInfo->ri_NumIndices;
233  indexDescs = resultRelInfo->ri_IndexRelationDescs;
234 
235  for (i = 0; i < numIndices; i++)
236  {
237  if (indexDescs[i] == NULL)
238  continue; /* shouldn't happen? */
239 
240  /* Drop lock acquired by ExecOpenIndices */
241  index_close(indexDescs[i], RowExclusiveLock);
242  }
243 
244  /*
245  * XXX should free indexInfo array here too? Currently we assume that
246  * such stuff will be cleaned up automatically in FreeExecutorState.
247  */
248 }
249 
250 /* ----------------------------------------------------------------
251  * ExecInsertIndexTuples
252  *
253  * This routine takes care of inserting index tuples
254  * into all the relations indexing the result relation
255  * when a heap tuple is inserted into the result relation.
256  *
257  * Unique and exclusion constraints are enforced at the same
258  * time. This returns a list of index OIDs for any unique or
259  * exclusion constraints that are deferred and that had
260  * potential (unconfirmed) conflicts. (if noDupErr == true,
261  * the same is done for non-deferred constraints, but report
262  * if conflict was speculative or deferred conflict to caller)
263  *
264  * If 'arbiterIndexes' is nonempty, noDupErr applies only to
265  * those indexes. NIL means noDupErr applies to all indexes.
266  *
267  * CAUTION: this must not be called for a HOT update.
268  * We can't defend against that here for lack of info.
269  * Should we change the API to make it safer?
270  * ----------------------------------------------------------------
271  */
272 List *
274  EState *estate,
275  bool noDupErr,
276  bool *specConflict,
277  List *arbiterIndexes)
278 {
279  ItemPointer tupleid = &slot->tts_tid;
280  List *result = NIL;
281  ResultRelInfo *resultRelInfo;
282  int i;
283  int numIndices;
284  RelationPtr relationDescs;
285  Relation heapRelation;
286  IndexInfo **indexInfoArray;
287  ExprContext *econtext;
289  bool isnull[INDEX_MAX_KEYS];
290 
291  Assert(ItemPointerIsValid(tupleid));
292 
293  /*
294  * Get information from the result relation info structure.
295  */
296  resultRelInfo = estate->es_result_relation_info;
297  numIndices = resultRelInfo->ri_NumIndices;
298  relationDescs = resultRelInfo->ri_IndexRelationDescs;
299  indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
300  heapRelation = resultRelInfo->ri_RelationDesc;
301 
302  /* Sanity check: slot must belong to the same rel as the resultRelInfo. */
303  Assert(slot->tts_tableOid == RelationGetRelid(heapRelation));
304 
305  /*
306  * We will use the EState's per-tuple context for evaluating predicates
307  * and index expressions (creating it if it's not already there).
308  */
309  econtext = GetPerTupleExprContext(estate);
310 
311  /* Arrange for econtext's scan tuple to be the tuple under test */
312  econtext->ecxt_scantuple = slot;
313 
314  /*
315  * for each index, form and insert the index tuple
316  */
317  for (i = 0; i < numIndices; i++)
318  {
319  Relation indexRelation = relationDescs[i];
320  IndexInfo *indexInfo;
321  bool applyNoDupErr;
322  IndexUniqueCheck checkUnique;
323  bool satisfiesConstraint;
324 
325  if (indexRelation == NULL)
326  continue;
327 
328  indexInfo = indexInfoArray[i];
329 
330  /* If the index is marked as read-only, ignore it */
331  if (!indexInfo->ii_ReadyForInserts)
332  continue;
333 
334  /* Check for partial index */
335  if (indexInfo->ii_Predicate != NIL)
336  {
337  ExprState *predicate;
338 
339  /*
340  * If predicate state not set up yet, create it (in the estate's
341  * per-query context)
342  */
343  predicate = indexInfo->ii_PredicateState;
344  if (predicate == NULL)
345  {
346  predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
347  indexInfo->ii_PredicateState = predicate;
348  }
349 
350  /* Skip this index-update if the predicate isn't satisfied */
351  if (!ExecQual(predicate, econtext))
352  continue;
353  }
354 
355  /*
356  * FormIndexDatum fills in its values and isnull parameters with the
357  * appropriate values for the column(s) of the index.
358  */
359  FormIndexDatum(indexInfo,
360  slot,
361  estate,
362  values,
363  isnull);
364 
365  /* Check whether to apply noDupErr to this index */
366  applyNoDupErr = noDupErr &&
367  (arbiterIndexes == NIL ||
368  list_member_oid(arbiterIndexes,
369  indexRelation->rd_index->indexrelid));
370 
371  /*
372  * The index AM does the actual insertion, plus uniqueness checking.
373  *
374  * For an immediate-mode unique index, we just tell the index AM to
375  * throw error if not unique.
376  *
377  * For a deferrable unique index, we tell the index AM to just detect
378  * possible non-uniqueness, and we add the index OID to the result
379  * list if further checking is needed.
380  *
381  * For a speculative insertion (used by INSERT ... ON CONFLICT), do
382  * the same as for a deferrable unique index.
383  */
384  if (!indexRelation->rd_index->indisunique)
385  checkUnique = UNIQUE_CHECK_NO;
386  else if (applyNoDupErr)
387  checkUnique = UNIQUE_CHECK_PARTIAL;
388  else if (indexRelation->rd_index->indimmediate)
389  checkUnique = UNIQUE_CHECK_YES;
390  else
391  checkUnique = UNIQUE_CHECK_PARTIAL;
392 
393  satisfiesConstraint =
394  index_insert(indexRelation, /* index relation */
395  values, /* array of index Datums */
396  isnull, /* null flags */
397  tupleid, /* tid of heap tuple */
398  heapRelation, /* heap relation */
399  checkUnique, /* type of uniqueness check to do */
400  indexInfo); /* index AM may need this */
401 
402  /*
403  * If the index has an associated exclusion constraint, check that.
404  * This is simpler than the process for uniqueness checks since we
405  * always insert first and then check. If the constraint is deferred,
406  * we check now anyway, but don't throw error on violation or wait for
407  * a conclusive outcome from a concurrent insertion; instead we'll
408  * queue a recheck event. Similarly, noDupErr callers (speculative
409  * inserters) will recheck later, and wait for a conclusive outcome
410  * then.
411  *
412  * An index for an exclusion constraint can't also be UNIQUE (not an
413  * essential property, we just don't allow it in the grammar), so no
414  * need to preserve the prior state of satisfiesConstraint.
415  */
416  if (indexInfo->ii_ExclusionOps != NULL)
417  {
418  bool violationOK;
419  CEOUC_WAIT_MODE waitMode;
420 
421  if (applyNoDupErr)
422  {
423  violationOK = true;
425  }
426  else if (!indexRelation->rd_index->indimmediate)
427  {
428  violationOK = true;
429  waitMode = CEOUC_NOWAIT;
430  }
431  else
432  {
433  violationOK = false;
434  waitMode = CEOUC_WAIT;
435  }
436 
437  satisfiesConstraint =
439  indexRelation, indexInfo,
440  tupleid, values, isnull,
441  estate, false,
442  waitMode, violationOK, NULL);
443  }
444 
445  if ((checkUnique == UNIQUE_CHECK_PARTIAL ||
446  indexInfo->ii_ExclusionOps != NULL) &&
447  !satisfiesConstraint)
448  {
449  /*
450  * The tuple potentially violates the uniqueness or exclusion
451  * constraint, so make a note of the index so that we can re-check
452  * it later. Speculative inserters are told if there was a
453  * speculative conflict, since that always requires a restart.
454  */
455  result = lappend_oid(result, RelationGetRelid(indexRelation));
456  if (indexRelation->rd_index->indimmediate && specConflict)
457  *specConflict = true;
458  }
459  }
460 
461  return result;
462 }
463 
464 /* ----------------------------------------------------------------
465  * ExecCheckIndexConstraints
466  *
467  * This routine checks if a tuple violates any unique or
468  * exclusion constraints. Returns true if there is no conflict.
469  * Otherwise returns false, and the TID of the conflicting
470  * tuple is returned in *conflictTid.
471  *
472  * If 'arbiterIndexes' is given, only those indexes are checked.
473  * NIL means all indexes.
474  *
475  * Note that this doesn't lock the values in any way, so it's
476  * possible that a conflicting tuple is inserted immediately
477  * after this returns. But this can be used for a pre-check
478  * before insertion.
479  * ----------------------------------------------------------------
480  */
481 bool
483  EState *estate, ItemPointer conflictTid,
484  List *arbiterIndexes)
485 {
486  ResultRelInfo *resultRelInfo;
487  int i;
488  int numIndices;
489  RelationPtr relationDescs;
490  Relation heapRelation;
491  IndexInfo **indexInfoArray;
492  ExprContext *econtext;
494  bool isnull[INDEX_MAX_KEYS];
495  ItemPointerData invalidItemPtr;
496  bool checkedIndex = false;
497 
498  ItemPointerSetInvalid(conflictTid);
499  ItemPointerSetInvalid(&invalidItemPtr);
500 
501  /*
502  * Get information from the result relation info structure.
503  */
504  resultRelInfo = estate->es_result_relation_info;
505  numIndices = resultRelInfo->ri_NumIndices;
506  relationDescs = resultRelInfo->ri_IndexRelationDescs;
507  indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
508  heapRelation = resultRelInfo->ri_RelationDesc;
509 
510  /*
511  * We will use the EState's per-tuple context for evaluating predicates
512  * and index expressions (creating it if it's not already there).
513  */
514  econtext = GetPerTupleExprContext(estate);
515 
516  /* Arrange for econtext's scan tuple to be the tuple under test */
517  econtext->ecxt_scantuple = slot;
518 
519  /*
520  * For each index, form index tuple and check if it satisfies the
521  * constraint.
522  */
523  for (i = 0; i < numIndices; i++)
524  {
525  Relation indexRelation = relationDescs[i];
526  IndexInfo *indexInfo;
527  bool satisfiesConstraint;
528 
529  if (indexRelation == NULL)
530  continue;
531 
532  indexInfo = indexInfoArray[i];
533 
534  if (!indexInfo->ii_Unique && !indexInfo->ii_ExclusionOps)
535  continue;
536 
537  /* If the index is marked as read-only, ignore it */
538  if (!indexInfo->ii_ReadyForInserts)
539  continue;
540 
541  /* When specific arbiter indexes requested, only examine them */
542  if (arbiterIndexes != NIL &&
543  !list_member_oid(arbiterIndexes,
544  indexRelation->rd_index->indexrelid))
545  continue;
546 
547  if (!indexRelation->rd_index->indimmediate)
548  ereport(ERROR,
549  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
550  errmsg("ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters"),
551  errtableconstraint(heapRelation,
552  RelationGetRelationName(indexRelation))));
553 
554  checkedIndex = true;
555 
556  /* Check for partial index */
557  if (indexInfo->ii_Predicate != NIL)
558  {
559  ExprState *predicate;
560 
561  /*
562  * If predicate state not set up yet, create it (in the estate's
563  * per-query context)
564  */
565  predicate = indexInfo->ii_PredicateState;
566  if (predicate == NULL)
567  {
568  predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
569  indexInfo->ii_PredicateState = predicate;
570  }
571 
572  /* Skip this index-update if the predicate isn't satisfied */
573  if (!ExecQual(predicate, econtext))
574  continue;
575  }
576 
577  /*
578  * FormIndexDatum fills in its values and isnull parameters with the
579  * appropriate values for the column(s) of the index.
580  */
581  FormIndexDatum(indexInfo,
582  slot,
583  estate,
584  values,
585  isnull);
586 
587  satisfiesConstraint =
588  check_exclusion_or_unique_constraint(heapRelation, indexRelation,
589  indexInfo, &invalidItemPtr,
590  values, isnull, estate, false,
591  CEOUC_WAIT, true,
592  conflictTid);
593  if (!satisfiesConstraint)
594  return false;
595  }
596 
597  if (arbiterIndexes != NIL && !checkedIndex)
598  elog(ERROR, "unexpected failure to find arbiter index");
599 
600  return true;
601 }
602 
603 /*
604  * Check for violation of an exclusion or unique constraint
605  *
606  * heap: the table containing the new tuple
607  * index: the index supporting the constraint
608  * indexInfo: info about the index, including the exclusion properties
609  * tupleid: heap TID of the new tuple we have just inserted (invalid if we
610  * haven't inserted a new tuple yet)
611  * values, isnull: the *index* column values computed for the new tuple
612  * estate: an EState we can do evaluation in
613  * newIndex: if true, we are trying to build a new index (this affects
614  * only the wording of error messages)
615  * waitMode: whether to wait for concurrent inserters/deleters
616  * violationOK: if true, don't throw error for violation
617  * conflictTid: if not-NULL, the TID of the conflicting tuple is returned here
618  *
619  * Returns true if OK, false if actual or potential violation
620  *
621  * 'waitMode' determines what happens if a conflict is detected with a tuple
622  * that was inserted or deleted by a transaction that's still running.
623  * CEOUC_WAIT means that we wait for the transaction to commit, before
624  * throwing an error or returning. CEOUC_NOWAIT means that we report the
625  * violation immediately; so the violation is only potential, and the caller
626  * must recheck sometime later. This behavior is convenient for deferred
627  * exclusion checks; we need not bother queuing a deferred event if there is
628  * definitely no conflict at insertion time.
629  *
630  * CEOUC_LIVELOCK_PREVENTING_WAIT is like CEOUC_NOWAIT, but we will sometimes
631  * wait anyway, to prevent livelocking if two transactions try inserting at
632  * the same time. This is used with speculative insertions, for INSERT ON
633  * CONFLICT statements. (See notes in file header)
634  *
635  * If violationOK is true, we just report the potential or actual violation to
636  * the caller by returning 'false'. Otherwise we throw a descriptive error
637  * message here. When violationOK is false, a false result is impossible.
638  *
639  * Note: The indexam is normally responsible for checking unique constraints,
640  * so this normally only needs to be used for exclusion constraints. But this
641  * function is also called when doing a "pre-check" for conflicts on a unique
642  * constraint, when doing speculative insertion. Caller may use the returned
643  * conflict TID to take further steps.
644  */
645 static bool
647  IndexInfo *indexInfo,
648  ItemPointer tupleid,
649  Datum *values, bool *isnull,
650  EState *estate, bool newIndex,
651  CEOUC_WAIT_MODE waitMode,
652  bool violationOK,
653  ItemPointer conflictTid)
654 {
655  Oid *constr_procs;
656  uint16 *constr_strats;
657  Oid *index_collations = index->rd_indcollation;
658  int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index);
659  IndexScanDesc index_scan;
660  ScanKeyData scankeys[INDEX_MAX_KEYS];
661  SnapshotData DirtySnapshot;
662  int i;
663  bool conflict;
664  bool found_self;
665  ExprContext *econtext;
666  TupleTableSlot *existing_slot;
667  TupleTableSlot *save_scantuple;
668 
669  if (indexInfo->ii_ExclusionOps)
670  {
671  constr_procs = indexInfo->ii_ExclusionProcs;
672  constr_strats = indexInfo->ii_ExclusionStrats;
673  }
674  else
675  {
676  constr_procs = indexInfo->ii_UniqueProcs;
677  constr_strats = indexInfo->ii_UniqueStrats;
678  }
679 
680  /*
681  * If any of the input values are NULL, the constraint check is assumed to
682  * pass (i.e., we assume the operators are strict).
683  */
684  for (i = 0; i < indnkeyatts; i++)
685  {
686  if (isnull[i])
687  return true;
688  }
689 
690  /*
691  * Search the tuples that are in the index for any violations, including
692  * tuples that aren't visible yet.
693  */
694  InitDirtySnapshot(DirtySnapshot);
695 
696  for (i = 0; i < indnkeyatts; i++)
697  {
698  ScanKeyEntryInitialize(&scankeys[i],
699  0,
700  i + 1,
701  constr_strats[i],
702  InvalidOid,
703  index_collations[i],
704  constr_procs[i],
705  values[i]);
706  }
707 
708  /*
709  * Need a TupleTableSlot to put existing tuples in.
710  *
711  * To use FormIndexDatum, we have to make the econtext's scantuple point
712  * to this slot. Be sure to save and restore caller's value for
713  * scantuple.
714  */
715  existing_slot = table_slot_create(heap, NULL);
716 
717  econtext = GetPerTupleExprContext(estate);
718  save_scantuple = econtext->ecxt_scantuple;
719  econtext->ecxt_scantuple = existing_slot;
720 
721  /*
722  * May have to restart scan from this point if a potential conflict is
723  * found.
724  */
725 retry:
726  conflict = false;
727  found_self = false;
728  index_scan = index_beginscan(heap, index, &DirtySnapshot, indnkeyatts, 0);
729  index_rescan(index_scan, scankeys, indnkeyatts, NULL, 0);
730 
731  while (index_getnext_slot(index_scan, ForwardScanDirection, existing_slot))
732  {
733  TransactionId xwait;
734  XLTW_Oper reason_wait;
735  Datum existing_values[INDEX_MAX_KEYS];
736  bool existing_isnull[INDEX_MAX_KEYS];
737  char *error_new;
738  char *error_existing;
739 
740  /*
741  * Ignore the entry for the tuple we're trying to check.
742  */
743  if (ItemPointerIsValid(tupleid) &&
744  ItemPointerEquals(tupleid, &existing_slot->tts_tid))
745  {
746  if (found_self) /* should not happen */
747  elog(ERROR, "found self tuple multiple times in index \"%s\"",
748  RelationGetRelationName(index));
749  found_self = true;
750  continue;
751  }
752 
753  /*
754  * Extract the index column values and isnull flags from the existing
755  * tuple.
756  */
757  FormIndexDatum(indexInfo, existing_slot, estate,
758  existing_values, existing_isnull);
759 
760  /* If lossy indexscan, must recheck the condition */
761  if (index_scan->xs_recheck)
762  {
763  if (!index_recheck_constraint(index,
764  constr_procs,
765  existing_values,
766  existing_isnull,
767  values))
768  continue; /* tuple doesn't actually match, so no
769  * conflict */
770  }
771 
772  /*
773  * At this point we have either a conflict or a potential conflict.
774  *
775  * If an in-progress transaction is affecting the visibility of this
776  * tuple, we need to wait for it to complete and then recheck (unless
777  * the caller requested not to). For simplicity we do rechecking by
778  * just restarting the whole scan --- this case probably doesn't
779  * happen often enough to be worth trying harder, and anyway we don't
780  * want to hold any index internal locks while waiting.
781  */
782  xwait = TransactionIdIsValid(DirtySnapshot.xmin) ?
783  DirtySnapshot.xmin : DirtySnapshot.xmax;
784 
785  if (TransactionIdIsValid(xwait) &&
786  (waitMode == CEOUC_WAIT ||
787  (waitMode == CEOUC_LIVELOCK_PREVENTING_WAIT &&
788  DirtySnapshot.speculativeToken &&
790  {
791  reason_wait = indexInfo->ii_ExclusionOps ?
793  index_endscan(index_scan);
794  if (DirtySnapshot.speculativeToken)
795  SpeculativeInsertionWait(DirtySnapshot.xmin,
796  DirtySnapshot.speculativeToken);
797  else
798  XactLockTableWait(xwait, heap,
799  &existing_slot->tts_tid, reason_wait);
800  goto retry;
801  }
802 
803  /*
804  * We have a definite conflict (or a potential one, but the caller
805  * didn't want to wait). Return it to caller, or report it.
806  */
807  if (violationOK)
808  {
809  conflict = true;
810  if (conflictTid)
811  *conflictTid = existing_slot->tts_tid;
812  break;
813  }
814 
815  error_new = BuildIndexValueDescription(index, values, isnull);
816  error_existing = BuildIndexValueDescription(index, existing_values,
817  existing_isnull);
818  if (newIndex)
819  ereport(ERROR,
820  (errcode(ERRCODE_EXCLUSION_VIOLATION),
821  errmsg("could not create exclusion constraint \"%s\"",
822  RelationGetRelationName(index)),
823  error_new && error_existing ?
824  errdetail("Key %s conflicts with key %s.",
825  error_new, error_existing) :
826  errdetail("Key conflicts exist."),
827  errtableconstraint(heap,
828  RelationGetRelationName(index))));
829  else
830  ereport(ERROR,
831  (errcode(ERRCODE_EXCLUSION_VIOLATION),
832  errmsg("conflicting key value violates exclusion constraint \"%s\"",
833  RelationGetRelationName(index)),
834  error_new && error_existing ?
835  errdetail("Key %s conflicts with existing key %s.",
836  error_new, error_existing) :
837  errdetail("Key conflicts with existing key."),
838  errtableconstraint(heap,
839  RelationGetRelationName(index))));
840  }
841 
842  index_endscan(index_scan);
843 
844  /*
845  * Ordinarily, at this point the search should have found the originally
846  * inserted tuple (if any), unless we exited the loop early because of
847  * conflict. However, it is possible to define exclusion constraints for
848  * which that wouldn't be true --- for instance, if the operator is <>. So
849  * we no longer complain if found_self is still false.
850  */
851 
852  econtext->ecxt_scantuple = save_scantuple;
853 
854  ExecDropSingleTupleTableSlot(existing_slot);
855 
856  return !conflict;
857 }
858 
859 /*
860  * Check for violation of an exclusion constraint
861  *
862  * This is a dumbed down version of check_exclusion_or_unique_constraint
863  * for external callers. They don't need all the special modes.
864  */
865 void
867  IndexInfo *indexInfo,
868  ItemPointer tupleid,
869  Datum *values, bool *isnull,
870  EState *estate, bool newIndex)
871 {
872  (void) check_exclusion_or_unique_constraint(heap, index, indexInfo, tupleid,
873  values, isnull,
874  estate, newIndex,
875  CEOUC_WAIT, false, NULL);
876 }
877 
878 /*
879  * Check existing tuple's index values to see if it really matches the
880  * exclusion condition against the new_values. Returns true if conflict.
881  */
882 static bool
884  Datum *existing_values, bool *existing_isnull,
885  Datum *new_values)
886 {
887  int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index);
888  int i;
889 
890  for (i = 0; i < indnkeyatts; i++)
891  {
892  /* Assume the exclusion operators are strict */
893  if (existing_isnull[i])
894  return false;
895 
896  if (!DatumGetBool(OidFunctionCall2Coll(constr_procs[i],
897  index->rd_indcollation[i],
898  existing_values[i],
899  new_values[i])))
900  return false;
901  }
902 
903  return true;
904 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:77
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:82
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: index.c:2567
int ri_NumIndices
Definition: execnodes.h:413
#define NIL
Definition: pg_list.h:65
Oid tts_tableOid
Definition: tuptable.h:131
uint16 * ii_UniqueStrats
Definition: execnodes.h:168
Relation ri_RelationDesc
Definition: execnodes.h:410
#define InitDirtySnapshot(snapshotdata)
Definition: snapmgr.h:76
List * ii_Predicate
Definition: execnodes.h:161
uint32 TransactionId
Definition: c.h:514
ExprState * ii_PredicateState
Definition: execnodes.h:162
#define RelationGetForm(relation)
Definition: rel.h:416
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
Definition: indexam.c:289
Oid * ii_ExclusionProcs
Definition: execnodes.h:164
int errcode(int sqlerrcode)
Definition: elog.c:608
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:2285
unsigned int Oid
Definition: postgres_ext.h:31
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:365
List * lappend_oid(List *list, Oid datum)
Definition: list.c:358
bool ExecCheckIndexConstraints(TupleTableSlot *slot, EState *estate, ItemPointer conflictTid, List *arbiterIndexes)
Definition: execIndexing.c:482
static bool check_exclusion_or_unique_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex, CEOUC_WAIT_MODE waitMode, bool errorOK, ItemPointer conflictTid)
Definition: execIndexing.c:646
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
Definition: execIndexing.c:151
Definition: type.h:89
IndexUniqueCheck
Definition: genam.h:112
#define GetPerTupleExprContext(estate)
Definition: executor.h:501
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5272
Form_pg_index rd_index
Definition: rel.h:143
unsigned short uint16
Definition: c.h:358
Oid * rd_indcollation
Definition: rel.h:168
static bool index_recheck_constraint(Relation index, Oid *constr_procs, Datum *existing_values, bool *existing_isnull, Datum *new_values)
Definition: execIndexing.c:883
#define ERROR
Definition: elog.h:43
List * ExecInsertIndexTuples(TupleTableSlot *slot, EState *estate, bool noDupErr, bool *specConflict, List *arbiterIndexes)
Definition: execIndexing.c:273
void SpeculativeInsertionWait(TransactionId xid, uint32 token)
Definition: lmgr.c:781
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:422
void ScanKeyEntryInitialize(ScanKey entry, int flags, AttrNumber attributeNumber, StrategyNumber strategy, Oid subtype, Oid collation, RegProcedure procedure, Datum argument)
Definition: scankey.c:32
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
Oid * ii_UniqueProcs
Definition: execnodes.h:167
#define RowExclusiveLock
Definition: lockdefs.h:38
int errdetail(const char *fmt,...)
Definition: elog.c:955
#define DatumGetBool(X)
Definition: postgres.h:393
#define RelationGetRelationName(relation)
Definition: rel.h:456
ExprState * ExecPrepareQual(List *qual, EState *estate)
Definition: execExpr.c:518
Relation * RelationPtr
Definition: relcache.h:34
TransactionId xmax
Definition: snapshot.h:158
TransactionId xmin
Definition: snapshot.h:157
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition: rel.h:441
void index_endscan(IndexScanDesc scan)
Definition: indexam.c:315
Datum OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1422
bool ii_ReadyForInserts
Definition: execnodes.h:170
#define ereport(elevel, rest)
Definition: elog.h:141
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
bool ii_Unique
Definition: execnodes.h:169
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:675
uint32 speculativeToken
Definition: snapshot.h:193
void XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
Definition: lmgr.c:624
bool relhasindex
Definition: pg_class.h:72
#define Assert(condition)
Definition: c.h:739
#define INDEX_MAX_KEYS
static int list_length(const List *l)
Definition: pg_list.h:169
bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
Definition: indexam.c:607
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:223
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4347
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:29
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:152
static Datum values[MAXATTR]
Definition: bootstrap.c:167
XLTW_Oper
Definition: lmgr.h:24
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
Oid * ii_ExclusionOps
Definition: execnodes.h:163
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
void list_free(List *list)
Definition: list.c:1377
#define elog(elevel,...)
Definition: elog.h:228
IndexInfo ** ri_IndexRelationInfo
Definition: execnodes.h:419
int i
void BuildSpeculativeIndexInfo(Relation index, IndexInfo *ii)
Definition: index.c:2507
char * BuildIndexValueDescription(Relation indexRelation, Datum *values, bool *isnull)
Definition: genam.c:176
void check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex)
Definition: execIndexing.c:866
#define TransactionIdIsValid(xid)
Definition: transam.h:41
uint16 * ii_ExclusionStrats
Definition: execnodes.h:165
CEOUC_WAIT_MODE
Definition: execIndexing.c:120
Definition: pg_list.h:50
ItemPointerData tts_tid
Definition: tuptable.h:130
#define RelationGetRelid(relation)
Definition: rel.h:422
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:126
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:226
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:416
#define lfirst_oid(lc)
Definition: pg_list.h:192
bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, IndexInfo *indexInfo)
Definition: indexam.c:170
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, int norderbys)
Definition: indexam.c:197
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:521