Line data Source code
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. The tuple is first inserted into the heap
58 : * and the indexes are updated as usual, but if a constraint is violated,
59 : * we can still back out of 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-2026, 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/injection_point.h"
118 : #include "utils/multirangetypes.h"
119 : #include "utils/rangetypes.h"
120 : #include "utils/snapmgr.h"
121 :
122 : /* waitMode argument to check_exclusion_or_unique_constraint() */
123 : typedef enum
124 : {
125 : CEOUC_WAIT,
126 : CEOUC_NOWAIT,
127 : CEOUC_LIVELOCK_PREVENTING_WAIT,
128 : } CEOUC_WAIT_MODE;
129 :
130 : static bool check_exclusion_or_unique_constraint(Relation heap, Relation index,
131 : IndexInfo *indexInfo,
132 : const ItemPointerData *tupleid,
133 : const Datum *values, const bool *isnull,
134 : EState *estate, bool newIndex,
135 : CEOUC_WAIT_MODE waitMode,
136 : bool violationOK,
137 : ItemPointer conflictTid);
138 :
139 : static bool index_recheck_constraint(Relation index, const Oid *constr_procs,
140 : const Datum *existing_values, const bool *existing_isnull,
141 : const Datum *new_values);
142 : static bool index_unchanged_by_update(ResultRelInfo *resultRelInfo,
143 : EState *estate, IndexInfo *indexInfo,
144 : Relation indexRelation);
145 : static bool index_expression_changed_walker(Node *node,
146 : Bitmapset *allUpdatedCols);
147 : static void ExecWithoutOverlapsNotEmpty(Relation rel, NameData attname, Datum attval,
148 : char typtype, Oid atttypid);
149 :
150 : /* ----------------------------------------------------------------
151 : * ExecOpenIndices
152 : *
153 : * Find the indices associated with a result relation, open them,
154 : * and save information about them in the result ResultRelInfo.
155 : *
156 : * At entry, caller has already opened and locked
157 : * resultRelInfo->ri_RelationDesc.
158 : * ----------------------------------------------------------------
159 : */
160 : void
161 963129 : ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
162 : {
163 963129 : Relation resultRelation = resultRelInfo->ri_RelationDesc;
164 : List *indexoidlist;
165 : ListCell *l;
166 : int len,
167 : i;
168 : RelationPtr relationDescs;
169 : IndexInfo **indexInfoArray;
170 :
171 963129 : resultRelInfo->ri_NumIndices = 0;
172 :
173 : /* fast path if no indexes */
174 963129 : if (!RelationGetForm(resultRelation)->relhasindex)
175 41298 : return;
176 :
177 : /*
178 : * Get cached list of index OIDs
179 : */
180 921831 : indexoidlist = RelationGetIndexList(resultRelation);
181 921831 : len = list_length(indexoidlist);
182 921831 : if (len == 0)
183 20296 : return;
184 :
185 : /* This Assert will fail if ExecOpenIndices is called twice */
186 : Assert(resultRelInfo->ri_IndexRelationDescs == NULL);
187 :
188 : /*
189 : * allocate space for result arrays
190 : */
191 901535 : relationDescs = palloc_array(Relation, len);
192 901535 : indexInfoArray = palloc_array(IndexInfo *, len);
193 :
194 901535 : resultRelInfo->ri_NumIndices = len;
195 901535 : resultRelInfo->ri_IndexRelationDescs = relationDescs;
196 901535 : resultRelInfo->ri_IndexRelationInfo = indexInfoArray;
197 :
198 : /*
199 : * For each index, open the index relation and save pg_index info. We
200 : * acquire RowExclusiveLock, signifying we will update the index.
201 : *
202 : * Note: we do this even if the index is not indisready; it's not worth
203 : * the trouble to optimize for the case where it isn't.
204 : */
205 901535 : i = 0;
206 2714774 : foreach(l, indexoidlist)
207 : {
208 1813239 : Oid indexOid = lfirst_oid(l);
209 : Relation indexDesc;
210 : IndexInfo *ii;
211 :
212 1813239 : indexDesc = index_open(indexOid, RowExclusiveLock);
213 :
214 : /* extract index key information from the index's pg_index info */
215 1813239 : ii = BuildIndexInfo(indexDesc);
216 :
217 : /*
218 : * If the indexes are to be used for speculative insertion, add extra
219 : * information required by unique index entries.
220 : */
221 1813239 : if (speculative && ii->ii_Unique && !indexDesc->rd_index->indisexclusion)
222 863 : BuildSpeculativeIndexInfo(indexDesc, ii);
223 :
224 1813239 : relationDescs[i] = indexDesc;
225 1813239 : indexInfoArray[i] = ii;
226 1813239 : i++;
227 : }
228 :
229 901535 : list_free(indexoidlist);
230 : }
231 :
232 : /* ----------------------------------------------------------------
233 : * ExecCloseIndices
234 : *
235 : * Close the index relations stored in resultRelInfo
236 : * ----------------------------------------------------------------
237 : */
238 : void
239 1003658 : ExecCloseIndices(ResultRelInfo *resultRelInfo)
240 : {
241 : int i;
242 : int numIndices;
243 : RelationPtr indexDescs;
244 : IndexInfo **indexInfos;
245 :
246 1003658 : numIndices = resultRelInfo->ri_NumIndices;
247 1003658 : indexDescs = resultRelInfo->ri_IndexRelationDescs;
248 1003658 : indexInfos = resultRelInfo->ri_IndexRelationInfo;
249 :
250 2815864 : for (i = 0; i < numIndices; i++)
251 : {
252 : /* This Assert will fail if ExecCloseIndices is called twice */
253 : Assert(indexDescs[i] != NULL);
254 :
255 : /* Give the index a chance to do some post-insert cleanup */
256 1812206 : index_insert_cleanup(indexDescs[i], indexInfos[i]);
257 :
258 : /* Drop lock acquired by ExecOpenIndices */
259 1812206 : index_close(indexDescs[i], RowExclusiveLock);
260 :
261 : /* Mark the index as closed */
262 1812206 : indexDescs[i] = NULL;
263 : }
264 :
265 : /*
266 : * We don't attempt to free the IndexInfo data structures or the arrays,
267 : * instead assuming that such stuff will be cleaned up automatically in
268 : * FreeExecutorState.
269 : */
270 1003658 : }
271 :
272 : /* ----------------------------------------------------------------
273 : * ExecInsertIndexTuples
274 : *
275 : * This routine takes care of inserting index tuples
276 : * into all the relations indexing the result relation
277 : * when a heap tuple is inserted into the result relation.
278 : *
279 : * When EIIT_IS_UPDATE is set and EIIT_ONLY_SUMMARIZING isn't,
280 : * executor is performing an UPDATE that could not use an
281 : * optimization like heapam's HOT (in more general terms a
282 : * call to table_tuple_update() took place and set
283 : * 'update_indexes' to TU_All). Receiving this hint makes
284 : * us consider if we should pass down the 'indexUnchanged'
285 : * hint in turn. That's something that we figure out for
286 : * each index_insert() call iff EIIT_IS_UPDATE is set.
287 : * (When that flag is not set we already know not to pass the
288 : * hint to any index.)
289 : *
290 : * If EIIT_ONLY_SUMMARIZING is set, an equivalent optimization to
291 : * HOT has been applied and any updated columns are indexed
292 : * only by summarizing indexes (or in more general terms a
293 : * call to table_tuple_update() took place and set
294 : * 'update_indexes' to TU_Summarizing). We can (and must)
295 : * therefore only update the indexes that have
296 : * 'amsummarizing' = true.
297 : *
298 : * Unique and exclusion constraints are enforced at the same
299 : * time. This returns a list of index OIDs for any unique or
300 : * exclusion constraints that are deferred and that had
301 : * potential (unconfirmed) conflicts. (if EIIT_NO_DUPE_ERROR,
302 : * the same is done for non-deferred constraints, but report
303 : * if conflict was speculative or deferred conflict to caller)
304 : *
305 : * If 'arbiterIndexes' is nonempty, EIIT_NO_DUPE_ERROR applies only to
306 : * those indexes. NIL means EIIT_NO_DUPE_ERROR applies to all indexes.
307 : * ----------------------------------------------------------------
308 : */
309 : List *
310 1816529 : ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
311 : EState *estate,
312 : bits32 flags,
313 : TupleTableSlot *slot,
314 : List *arbiterIndexes,
315 : bool *specConflict)
316 : {
317 1816529 : ItemPointer tupleid = &slot->tts_tid;
318 1816529 : List *result = NIL;
319 : int i;
320 : int numIndices;
321 : RelationPtr relationDescs;
322 : Relation heapRelation;
323 : IndexInfo **indexInfoArray;
324 : ExprContext *econtext;
325 : Datum values[INDEX_MAX_KEYS];
326 : bool isnull[INDEX_MAX_KEYS];
327 :
328 : Assert(ItemPointerIsValid(tupleid));
329 :
330 : /*
331 : * Get information from the result relation info structure.
332 : */
333 1816529 : numIndices = resultRelInfo->ri_NumIndices;
334 1816529 : relationDescs = resultRelInfo->ri_IndexRelationDescs;
335 1816529 : indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
336 1816529 : heapRelation = resultRelInfo->ri_RelationDesc;
337 :
338 : /* Sanity check: slot must belong to the same rel as the resultRelInfo. */
339 : Assert(slot->tts_tableOid == RelationGetRelid(heapRelation));
340 :
341 : /*
342 : * We will use the EState's per-tuple context for evaluating predicates
343 : * and index expressions (creating it if it's not already there).
344 : */
345 1816529 : econtext = GetPerTupleExprContext(estate);
346 :
347 : /* Arrange for econtext's scan tuple to be the tuple under test */
348 1816529 : econtext->ecxt_scantuple = slot;
349 :
350 : /*
351 : * for each index, form and insert the index tuple
352 : */
353 3817675 : for (i = 0; i < numIndices; i++)
354 : {
355 2001504 : Relation indexRelation = relationDescs[i];
356 : IndexInfo *indexInfo;
357 : bool applyNoDupErr;
358 : IndexUniqueCheck checkUnique;
359 : bool indexUnchanged;
360 : bool satisfiesConstraint;
361 :
362 2001504 : if (indexRelation == NULL)
363 0 : continue;
364 :
365 2001504 : indexInfo = indexInfoArray[i];
366 :
367 : /* If the index is marked as read-only, ignore it */
368 2001504 : if (!indexInfo->ii_ReadyForInserts)
369 82 : continue;
370 :
371 : /*
372 : * Skip processing of non-summarizing indexes if we only update
373 : * summarizing indexes
374 : */
375 2001422 : if ((flags & EIIT_ONLY_SUMMARIZING) && !indexInfo->ii_Summarizing)
376 3 : continue;
377 :
378 : /* Check for partial index */
379 2001419 : if (indexInfo->ii_Predicate != NIL)
380 : {
381 : ExprState *predicate;
382 :
383 : /*
384 : * If predicate state not set up yet, create it (in the estate's
385 : * per-query context)
386 : */
387 200551 : predicate = indexInfo->ii_PredicateState;
388 200551 : if (predicate == NULL)
389 : {
390 136 : predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
391 136 : indexInfo->ii_PredicateState = predicate;
392 : }
393 :
394 : /* Skip this index-update if the predicate isn't satisfied */
395 200551 : if (!ExecQual(predicate, econtext))
396 200280 : continue;
397 : }
398 :
399 : /*
400 : * FormIndexDatum fills in its values and isnull parameters with the
401 : * appropriate values for the column(s) of the index.
402 : */
403 1801139 : FormIndexDatum(indexInfo,
404 : slot,
405 : estate,
406 : values,
407 : isnull);
408 :
409 : /* Check whether to apply noDupErr to this index */
410 1879073 : applyNoDupErr = (flags & EIIT_NO_DUPE_ERROR) &&
411 77934 : (arbiterIndexes == NIL ||
412 77934 : list_member_oid(arbiterIndexes,
413 77934 : indexRelation->rd_index->indexrelid));
414 :
415 : /*
416 : * The index AM does the actual insertion, plus uniqueness checking.
417 : *
418 : * For an immediate-mode unique index, we just tell the index AM to
419 : * throw error if not unique.
420 : *
421 : * For a deferrable unique index, we tell the index AM to just detect
422 : * possible non-uniqueness, and we add the index OID to the result
423 : * list if further checking is needed.
424 : *
425 : * For a speculative insertion (used by INSERT ... ON CONFLICT), do
426 : * the same as for a deferrable unique index.
427 : */
428 1801139 : if (!indexRelation->rd_index->indisunique)
429 958137 : checkUnique = UNIQUE_CHECK_NO;
430 843002 : else if (applyNoDupErr)
431 77972 : checkUnique = UNIQUE_CHECK_PARTIAL;
432 765030 : else if (indexRelation->rd_index->indimmediate)
433 764955 : checkUnique = UNIQUE_CHECK_YES;
434 : else
435 75 : checkUnique = UNIQUE_CHECK_PARTIAL;
436 :
437 : /*
438 : * There's definitely going to be an index_insert() call for this
439 : * index. If we're being called as part of an UPDATE statement,
440 : * consider if the 'indexUnchanged' = true hint should be passed.
441 : */
442 1979112 : indexUnchanged = ((flags & EIIT_IS_UPDATE) &&
443 177973 : index_unchanged_by_update(resultRelInfo,
444 : estate,
445 : indexInfo,
446 : indexRelation));
447 :
448 : satisfiesConstraint =
449 1801139 : index_insert(indexRelation, /* index relation */
450 : values, /* array of index Datums */
451 : isnull, /* null flags */
452 : tupleid, /* tid of heap tuple */
453 : heapRelation, /* heap relation */
454 : checkUnique, /* type of uniqueness check to do */
455 : indexUnchanged, /* UPDATE without logical change? */
456 : indexInfo); /* index AM may need this */
457 :
458 : /*
459 : * If the index has an associated exclusion constraint, check that.
460 : * This is simpler than the process for uniqueness checks since we
461 : * always insert first and then check. If the constraint is deferred,
462 : * we check now anyway, but don't throw error on violation or wait for
463 : * a conclusive outcome from a concurrent insertion; instead we'll
464 : * queue a recheck event. Similarly, noDupErr callers (speculative
465 : * inserters) will recheck later, and wait for a conclusive outcome
466 : * then.
467 : *
468 : * An index for an exclusion constraint can't also be UNIQUE (not an
469 : * essential property, we just don't allow it in the grammar), so no
470 : * need to preserve the prior state of satisfiesConstraint.
471 : */
472 1800868 : if (indexInfo->ii_ExclusionOps != NULL)
473 : {
474 : bool violationOK;
475 : CEOUC_WAIT_MODE waitMode;
476 :
477 997 : if (applyNoDupErr)
478 : {
479 72 : violationOK = true;
480 72 : waitMode = CEOUC_LIVELOCK_PREVENTING_WAIT;
481 : }
482 925 : else if (!indexRelation->rd_index->indimmediate)
483 : {
484 21 : violationOK = true;
485 21 : waitMode = CEOUC_NOWAIT;
486 : }
487 : else
488 : {
489 904 : violationOK = false;
490 904 : waitMode = CEOUC_WAIT;
491 : }
492 :
493 : satisfiesConstraint =
494 997 : check_exclusion_or_unique_constraint(heapRelation,
495 : indexRelation, indexInfo,
496 : tupleid, values, isnull,
497 : estate, false,
498 : waitMode, violationOK, NULL);
499 : }
500 :
501 1800781 : if ((checkUnique == UNIQUE_CHECK_PARTIAL ||
502 1722734 : indexInfo->ii_ExclusionOps != NULL) &&
503 78885 : !satisfiesConstraint)
504 : {
505 : /*
506 : * The tuple potentially violates the uniqueness or exclusion
507 : * constraint, so make a note of the index so that we can re-check
508 : * it later. Speculative inserters are told if there was a
509 : * speculative conflict, since that always requires a restart.
510 : */
511 130 : result = lappend_oid(result, RelationGetRelid(indexRelation));
512 130 : if (indexRelation->rd_index->indimmediate && specConflict)
513 69 : *specConflict = true;
514 : }
515 : }
516 :
517 1816171 : return result;
518 : }
519 :
520 : /* ----------------------------------------------------------------
521 : * ExecCheckIndexConstraints
522 : *
523 : * This routine checks if a tuple violates any unique or
524 : * exclusion constraints. Returns true if there is no conflict.
525 : * Otherwise returns false, and the TID of the conflicting
526 : * tuple is returned in *conflictTid.
527 : *
528 : * If 'arbiterIndexes' is given, only those indexes are checked.
529 : * NIL means all indexes.
530 : *
531 : * Note that this doesn't lock the values in any way, so it's
532 : * possible that a conflicting tuple is inserted immediately
533 : * after this returns. This can be used for either a pre-check
534 : * before insertion or a re-check after finding a conflict.
535 : *
536 : * 'tupleid' should be the TID of the tuple that has been recently
537 : * inserted (or can be invalid if we haven't inserted a new tuple yet).
538 : * This tuple will be excluded from conflict checking.
539 : * ----------------------------------------------------------------
540 : */
541 : bool
542 5072 : ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
543 : EState *estate, ItemPointer conflictTid,
544 : const ItemPointerData *tupleid, List *arbiterIndexes)
545 : {
546 : int i;
547 : int numIndices;
548 : RelationPtr relationDescs;
549 : Relation heapRelation;
550 : IndexInfo **indexInfoArray;
551 : ExprContext *econtext;
552 : Datum values[INDEX_MAX_KEYS];
553 : bool isnull[INDEX_MAX_KEYS];
554 : ItemPointerData invalidItemPtr;
555 5072 : bool checkedIndex = false;
556 :
557 5072 : ItemPointerSetInvalid(conflictTid);
558 5072 : ItemPointerSetInvalid(&invalidItemPtr);
559 :
560 : /*
561 : * Get information from the result relation info structure.
562 : */
563 5072 : numIndices = resultRelInfo->ri_NumIndices;
564 5072 : relationDescs = resultRelInfo->ri_IndexRelationDescs;
565 5072 : indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
566 5072 : heapRelation = resultRelInfo->ri_RelationDesc;
567 :
568 : /*
569 : * We will use the EState's per-tuple context for evaluating predicates
570 : * and index expressions (creating it if it's not already there).
571 : */
572 5072 : econtext = GetPerTupleExprContext(estate);
573 :
574 : /* Arrange for econtext's scan tuple to be the tuple under test */
575 5072 : econtext->ecxt_scantuple = slot;
576 :
577 : /*
578 : * For each index, form index tuple and check if it satisfies the
579 : * constraint.
580 : */
581 7297 : for (i = 0; i < numIndices; i++)
582 : {
583 5164 : Relation indexRelation = relationDescs[i];
584 : IndexInfo *indexInfo;
585 : bool satisfiesConstraint;
586 :
587 5164 : if (indexRelation == NULL)
588 0 : continue;
589 :
590 5164 : indexInfo = indexInfoArray[i];
591 :
592 5164 : if (!indexInfo->ii_Unique && !indexInfo->ii_ExclusionOps)
593 2 : continue;
594 :
595 : /* If the index is marked as read-only, ignore it */
596 5162 : if (!indexInfo->ii_ReadyForInserts)
597 0 : continue;
598 :
599 : /* When specific arbiter indexes requested, only examine them */
600 5162 : if (arbiterIndexes != NIL &&
601 5027 : !list_member_oid(arbiterIndexes,
602 5027 : indexRelation->rd_index->indexrelid))
603 65 : continue;
604 :
605 5097 : if (!indexRelation->rd_index->indimmediate)
606 3 : ereport(ERROR,
607 : (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
608 : errmsg("ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters"),
609 : errtableconstraint(heapRelation,
610 : RelationGetRelationName(indexRelation))));
611 :
612 5094 : checkedIndex = true;
613 :
614 : /* Check for partial index */
615 5094 : if (indexInfo->ii_Predicate != NIL)
616 : {
617 : ExprState *predicate;
618 :
619 : /*
620 : * If predicate state not set up yet, create it (in the estate's
621 : * per-query context)
622 : */
623 20 : predicate = indexInfo->ii_PredicateState;
624 20 : if (predicate == NULL)
625 : {
626 20 : predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
627 20 : indexInfo->ii_PredicateState = predicate;
628 : }
629 :
630 : /* Skip this index-update if the predicate isn't satisfied */
631 20 : if (!ExecQual(predicate, econtext))
632 0 : continue;
633 : }
634 :
635 : /*
636 : * FormIndexDatum fills in its values and isnull parameters with the
637 : * appropriate values for the column(s) of the index.
638 : */
639 5094 : FormIndexDatum(indexInfo,
640 : slot,
641 : estate,
642 : values,
643 : isnull);
644 :
645 : satisfiesConstraint =
646 5094 : check_exclusion_or_unique_constraint(heapRelation, indexRelation,
647 : indexInfo, tupleid,
648 : values, isnull, estate, false,
649 : CEOUC_WAIT, true,
650 : conflictTid);
651 5093 : if (!satisfiesConstraint)
652 2935 : return false;
653 : }
654 :
655 2133 : if (arbiterIndexes != NIL && !checkedIndex)
656 0 : elog(ERROR, "unexpected failure to find arbiter index");
657 :
658 2133 : return true;
659 : }
660 :
661 : /*
662 : * Check for violation of an exclusion or unique constraint
663 : *
664 : * heap: the table containing the new tuple
665 : * index: the index supporting the constraint
666 : * indexInfo: info about the index, including the exclusion properties
667 : * tupleid: heap TID of the new tuple we have just inserted (invalid if we
668 : * haven't inserted a new tuple yet)
669 : * values, isnull: the *index* column values computed for the new tuple
670 : * estate: an EState we can do evaluation in
671 : * newIndex: if true, we are trying to build a new index (this affects
672 : * only the wording of error messages)
673 : * waitMode: whether to wait for concurrent inserters/deleters
674 : * violationOK: if true, don't throw error for violation
675 : * conflictTid: if not-NULL, the TID of the conflicting tuple is returned here
676 : *
677 : * Returns true if OK, false if actual or potential violation
678 : *
679 : * 'waitMode' determines what happens if a conflict is detected with a tuple
680 : * that was inserted or deleted by a transaction that's still running.
681 : * CEOUC_WAIT means that we wait for the transaction to commit, before
682 : * throwing an error or returning. CEOUC_NOWAIT means that we report the
683 : * violation immediately; so the violation is only potential, and the caller
684 : * must recheck sometime later. This behavior is convenient for deferred
685 : * exclusion checks; we need not bother queuing a deferred event if there is
686 : * definitely no conflict at insertion time.
687 : *
688 : * CEOUC_LIVELOCK_PREVENTING_WAIT is like CEOUC_NOWAIT, but we will sometimes
689 : * wait anyway, to prevent livelocking if two transactions try inserting at
690 : * the same time. This is used with speculative insertions, for INSERT ON
691 : * CONFLICT statements. (See notes in file header)
692 : *
693 : * If violationOK is true, we just report the potential or actual violation to
694 : * the caller by returning 'false'. Otherwise we throw a descriptive error
695 : * message here. When violationOK is false, a false result is impossible.
696 : *
697 : * Note: The indexam is normally responsible for checking unique constraints,
698 : * so this normally only needs to be used for exclusion constraints. But this
699 : * function is also called when doing a "pre-check" for conflicts on a unique
700 : * constraint, when doing speculative insertion. Caller may use the returned
701 : * conflict TID to take further steps.
702 : */
703 : static bool
704 6330 : check_exclusion_or_unique_constraint(Relation heap, Relation index,
705 : IndexInfo *indexInfo,
706 : const ItemPointerData *tupleid,
707 : const Datum *values, const bool *isnull,
708 : EState *estate, bool newIndex,
709 : CEOUC_WAIT_MODE waitMode,
710 : bool violationOK,
711 : ItemPointer conflictTid)
712 : {
713 : Oid *constr_procs;
714 : uint16 *constr_strats;
715 6330 : Oid *index_collations = index->rd_indcollation;
716 6330 : int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index);
717 : IndexScanDesc index_scan;
718 : ScanKeyData scankeys[INDEX_MAX_KEYS];
719 : SnapshotData DirtySnapshot;
720 : int i;
721 : bool conflict;
722 : bool found_self;
723 : ExprContext *econtext;
724 : TupleTableSlot *existing_slot;
725 : TupleTableSlot *save_scantuple;
726 :
727 6330 : if (indexInfo->ii_ExclusionOps)
728 : {
729 1314 : constr_procs = indexInfo->ii_ExclusionProcs;
730 1314 : constr_strats = indexInfo->ii_ExclusionStrats;
731 : }
732 : else
733 : {
734 5016 : constr_procs = indexInfo->ii_UniqueProcs;
735 5016 : constr_strats = indexInfo->ii_UniqueStrats;
736 : }
737 :
738 : /*
739 : * If this is a WITHOUT OVERLAPS constraint, we must also forbid empty
740 : * ranges/multiranges. This must happen before we look for NULLs below, or
741 : * a UNIQUE constraint could insert an empty range along with a NULL
742 : * scalar part.
743 : */
744 6330 : if (indexInfo->ii_WithoutOverlaps)
745 : {
746 : /*
747 : * Look up the type from the heap tuple, but check the Datum from the
748 : * index tuple.
749 : */
750 1111 : AttrNumber attno = indexInfo->ii_IndexAttrNumbers[indnkeyatts - 1];
751 :
752 1111 : if (!isnull[indnkeyatts - 1])
753 : {
754 1081 : TupleDesc tupdesc = RelationGetDescr(heap);
755 1081 : Form_pg_attribute att = TupleDescAttr(tupdesc, attno - 1);
756 1081 : TypeCacheEntry *typcache = lookup_type_cache(att->atttypid, 0);
757 :
758 1081 : ExecWithoutOverlapsNotEmpty(heap, att->attname,
759 1081 : values[indnkeyatts - 1],
760 1081 : typcache->typtype, att->atttypid);
761 : }
762 : }
763 :
764 : /*
765 : * If any of the input values are NULL, and the index uses the default
766 : * nulls-are-distinct mode, the constraint check is assumed to pass (i.e.,
767 : * we assume the operators are strict). Otherwise, we interpret the
768 : * constraint as specifying IS NULL for each column whose input value is
769 : * NULL.
770 : */
771 6288 : if (!indexInfo->ii_NullsNotDistinct)
772 : {
773 13663 : for (i = 0; i < indnkeyatts; i++)
774 : {
775 7438 : if (isnull[i])
776 60 : return true;
777 : }
778 : }
779 :
780 : /*
781 : * Search the tuples that are in the index for any violations, including
782 : * tuples that aren't visible yet.
783 : */
784 6228 : InitDirtySnapshot(DirtySnapshot);
785 :
786 13579 : for (i = 0; i < indnkeyatts; i++)
787 : {
788 7351 : ScanKeyEntryInitialize(&scankeys[i],
789 7351 : isnull[i] ? SK_ISNULL | SK_SEARCHNULL : 0,
790 7351 : i + 1,
791 7351 : constr_strats[i],
792 : InvalidOid,
793 7351 : index_collations[i],
794 7351 : constr_procs[i],
795 7351 : values[i]);
796 : }
797 :
798 : /*
799 : * Need a TupleTableSlot to put existing tuples in.
800 : *
801 : * To use FormIndexDatum, we have to make the econtext's scantuple point
802 : * to this slot. Be sure to save and restore caller's value for
803 : * scantuple.
804 : */
805 6228 : existing_slot = table_slot_create(heap, NULL);
806 :
807 6228 : econtext = GetPerTupleExprContext(estate);
808 6228 : save_scantuple = econtext->ecxt_scantuple;
809 6228 : econtext->ecxt_scantuple = existing_slot;
810 :
811 : /*
812 : * May have to restart scan from this point if a potential conflict is
813 : * found.
814 : */
815 6264 : retry:
816 6264 : conflict = false;
817 6264 : found_self = false;
818 6264 : index_scan = index_beginscan(heap, index, &DirtySnapshot, NULL, indnkeyatts, 0);
819 6264 : index_rescan(index_scan, scankeys, indnkeyatts, NULL, 0);
820 :
821 7339 : while (index_getnext_slot(index_scan, ForwardScanDirection, existing_slot))
822 : {
823 : TransactionId xwait;
824 : XLTW_Oper reason_wait;
825 : Datum existing_values[INDEX_MAX_KEYS];
826 : bool existing_isnull[INDEX_MAX_KEYS];
827 : char *error_new;
828 : char *error_existing;
829 :
830 : /*
831 : * Ignore the entry for the tuple we're trying to check.
832 : */
833 5366 : if (ItemPointerIsValid(tupleid) &&
834 1223 : ItemPointerEquals(tupleid, &existing_slot->tts_tid))
835 : {
836 1048 : if (found_self) /* should not happen */
837 0 : elog(ERROR, "found self tuple multiple times in index \"%s\"",
838 : RelationGetRelationName(index));
839 1048 : found_self = true;
840 1075 : continue;
841 : }
842 :
843 : /*
844 : * Extract the index column values and isnull flags from the existing
845 : * tuple.
846 : */
847 3095 : FormIndexDatum(indexInfo, existing_slot, estate,
848 : existing_values, existing_isnull);
849 :
850 : /* If lossy indexscan, must recheck the condition */
851 3095 : if (index_scan->xs_recheck)
852 : {
853 69 : if (!index_recheck_constraint(index,
854 : constr_procs,
855 : existing_values,
856 : existing_isnull,
857 : values))
858 27 : continue; /* tuple doesn't actually match, so no
859 : * conflict */
860 : }
861 :
862 : /*
863 : * At this point we have either a conflict or a potential conflict.
864 : *
865 : * If an in-progress transaction is affecting the visibility of this
866 : * tuple, we need to wait for it to complete and then recheck (unless
867 : * the caller requested not to). For simplicity we do rechecking by
868 : * just restarting the whole scan --- this case probably doesn't
869 : * happen often enough to be worth trying harder, and anyway we don't
870 : * want to hold any index internal locks while waiting.
871 : */
872 6136 : xwait = TransactionIdIsValid(DirtySnapshot.xmin) ?
873 3068 : DirtySnapshot.xmin : DirtySnapshot.xmax;
874 :
875 3068 : if (TransactionIdIsValid(xwait) &&
876 0 : (waitMode == CEOUC_WAIT ||
877 0 : (waitMode == CEOUC_LIVELOCK_PREVENTING_WAIT &&
878 0 : DirtySnapshot.speculativeToken &&
879 0 : TransactionIdPrecedes(GetCurrentTransactionId(), xwait))))
880 : {
881 74 : reason_wait = indexInfo->ii_ExclusionOps ?
882 37 : XLTW_RecheckExclusionConstr : XLTW_InsertIndex;
883 37 : index_endscan(index_scan);
884 37 : if (DirtySnapshot.speculativeToken)
885 1 : SpeculativeInsertionWait(DirtySnapshot.xmin,
886 : DirtySnapshot.speculativeToken);
887 : else
888 36 : XactLockTableWait(xwait, heap,
889 36 : &existing_slot->tts_tid, reason_wait);
890 36 : goto retry;
891 : }
892 :
893 : /*
894 : * We have a definite conflict (or a potential one, but the caller
895 : * didn't want to wait). Return it to caller, or report it.
896 : */
897 3031 : if (violationOK)
898 : {
899 2947 : conflict = true;
900 2947 : if (conflictTid)
901 2935 : *conflictTid = existing_slot->tts_tid;
902 2947 : break;
903 : }
904 :
905 84 : error_new = BuildIndexValueDescription(index, values, isnull);
906 84 : error_existing = BuildIndexValueDescription(index, existing_values,
907 : existing_isnull);
908 84 : if (newIndex)
909 18 : ereport(ERROR,
910 : (errcode(ERRCODE_EXCLUSION_VIOLATION),
911 : errmsg("could not create exclusion constraint \"%s\"",
912 : RelationGetRelationName(index)),
913 : error_new && error_existing ?
914 : errdetail("Key %s conflicts with key %s.",
915 : error_new, error_existing) :
916 : errdetail("Key conflicts exist."),
917 : errtableconstraint(heap,
918 : RelationGetRelationName(index))));
919 : else
920 66 : ereport(ERROR,
921 : (errcode(ERRCODE_EXCLUSION_VIOLATION),
922 : errmsg("conflicting key value violates exclusion constraint \"%s\"",
923 : RelationGetRelationName(index)),
924 : error_new && error_existing ?
925 : errdetail("Key %s conflicts with existing key %s.",
926 : error_new, error_existing) :
927 : errdetail("Key conflicts with existing key."),
928 : errtableconstraint(heap,
929 : RelationGetRelationName(index))));
930 : }
931 :
932 6143 : index_endscan(index_scan);
933 :
934 : /*
935 : * Ordinarily, at this point the search should have found the originally
936 : * inserted tuple (if any), unless we exited the loop early because of
937 : * conflict. However, it is possible to define exclusion constraints for
938 : * which that wouldn't be true --- for instance, if the operator is <>. So
939 : * we no longer complain if found_self is still false.
940 : */
941 :
942 6143 : econtext->ecxt_scantuple = save_scantuple;
943 :
944 6143 : ExecDropSingleTupleTableSlot(existing_slot);
945 :
946 : #ifdef USE_INJECTION_POINTS
947 6143 : if (!conflict)
948 3196 : INJECTION_POINT("check-exclusion-or-unique-constraint-no-conflict", NULL);
949 : #endif
950 :
951 6143 : return !conflict;
952 : }
953 :
954 : /*
955 : * Check for violation of an exclusion constraint
956 : *
957 : * This is a dumbed down version of check_exclusion_or_unique_constraint
958 : * for external callers. They don't need all the special modes.
959 : */
960 : void
961 239 : check_exclusion_constraint(Relation heap, Relation index,
962 : IndexInfo *indexInfo,
963 : const ItemPointerData *tupleid,
964 : const Datum *values, const bool *isnull,
965 : EState *estate, bool newIndex)
966 : {
967 239 : (void) check_exclusion_or_unique_constraint(heap, index, indexInfo, tupleid,
968 : values, isnull,
969 : estate, newIndex,
970 : CEOUC_WAIT, false, NULL);
971 200 : }
972 :
973 : /*
974 : * Check existing tuple's index values to see if it really matches the
975 : * exclusion condition against the new_values. Returns true if conflict.
976 : */
977 : static bool
978 69 : index_recheck_constraint(Relation index, const Oid *constr_procs,
979 : const Datum *existing_values, const bool *existing_isnull,
980 : const Datum *new_values)
981 : {
982 69 : int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index);
983 : int i;
984 :
985 171 : for (i = 0; i < indnkeyatts; i++)
986 : {
987 : /* Assume the exclusion operators are strict */
988 129 : if (existing_isnull[i])
989 0 : return false;
990 :
991 129 : if (!DatumGetBool(OidFunctionCall2Coll(constr_procs[i],
992 129 : index->rd_indcollation[i],
993 129 : existing_values[i],
994 129 : new_values[i])))
995 27 : return false;
996 : }
997 :
998 42 : return true;
999 : }
1000 :
1001 : /*
1002 : * Check if ExecInsertIndexTuples() should pass indexUnchanged hint.
1003 : *
1004 : * When the executor performs an UPDATE that requires a new round of index
1005 : * tuples, determine if we should pass 'indexUnchanged' = true hint for one
1006 : * single index.
1007 : */
1008 : static bool
1009 177973 : index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate,
1010 : IndexInfo *indexInfo, Relation indexRelation)
1011 : {
1012 : Bitmapset *updatedCols;
1013 : Bitmapset *extraUpdatedCols;
1014 : Bitmapset *allUpdatedCols;
1015 177973 : bool hasexpression = false;
1016 : List *idxExprs;
1017 :
1018 : /*
1019 : * Check cache first
1020 : */
1021 177973 : if (indexInfo->ii_CheckedUnchanged)
1022 155987 : return indexInfo->ii_IndexUnchanged;
1023 21986 : indexInfo->ii_CheckedUnchanged = true;
1024 :
1025 : /*
1026 : * Check for indexed attribute overlap with updated columns.
1027 : *
1028 : * Only do this for key columns. A change to a non-key column within an
1029 : * INCLUDE index should not be counted here. Non-key column values are
1030 : * opaque payload state to the index AM, a little like an extra table TID.
1031 : *
1032 : * Note that row-level BEFORE triggers won't affect our behavior, since
1033 : * they don't affect the updatedCols bitmaps generally. It doesn't seem
1034 : * worth the trouble of checking which attributes were changed directly.
1035 : */
1036 21986 : updatedCols = ExecGetUpdatedCols(resultRelInfo, estate);
1037 21986 : extraUpdatedCols = ExecGetExtraUpdatedCols(resultRelInfo, estate);
1038 23888 : for (int attr = 0; attr < indexInfo->ii_NumIndexKeyAttrs; attr++)
1039 : {
1040 22814 : int keycol = indexInfo->ii_IndexAttrNumbers[attr];
1041 :
1042 22814 : if (keycol <= 0)
1043 : {
1044 : /*
1045 : * Skip expressions for now, but remember to deal with them later
1046 : * on
1047 : */
1048 15 : hasexpression = true;
1049 15 : continue;
1050 : }
1051 :
1052 22799 : if (bms_is_member(keycol - FirstLowInvalidHeapAttributeNumber,
1053 1887 : updatedCols) ||
1054 1887 : bms_is_member(keycol - FirstLowInvalidHeapAttributeNumber,
1055 : extraUpdatedCols))
1056 : {
1057 : /* Changed key column -- don't hint for this index */
1058 20912 : indexInfo->ii_IndexUnchanged = false;
1059 20912 : return false;
1060 : }
1061 : }
1062 :
1063 : /*
1064 : * When we get this far and index has no expressions, return true so that
1065 : * index_insert() call will go on to pass 'indexUnchanged' = true hint.
1066 : *
1067 : * The _absence_ of an indexed key attribute that overlaps with updated
1068 : * attributes (in addition to the total absence of indexed expressions)
1069 : * shows that the index as a whole is logically unchanged by UPDATE.
1070 : */
1071 1074 : if (!hasexpression)
1072 : {
1073 1062 : indexInfo->ii_IndexUnchanged = true;
1074 1062 : return true;
1075 : }
1076 :
1077 : /*
1078 : * Need to pass only one bms to expression_tree_walker helper function.
1079 : * Avoid allocating memory in common case where there are no extra cols.
1080 : */
1081 12 : if (!extraUpdatedCols)
1082 12 : allUpdatedCols = updatedCols;
1083 : else
1084 0 : allUpdatedCols = bms_union(updatedCols, extraUpdatedCols);
1085 :
1086 : /*
1087 : * We have to work slightly harder in the event of indexed expressions,
1088 : * but the principle is the same as before: try to find columns (Vars,
1089 : * actually) that overlap with known-updated columns.
1090 : *
1091 : * If we find any matching Vars, don't pass hint for index. Otherwise
1092 : * pass hint.
1093 : */
1094 12 : idxExprs = RelationGetIndexExpressions(indexRelation);
1095 12 : hasexpression = index_expression_changed_walker((Node *) idxExprs,
1096 : allUpdatedCols);
1097 12 : list_free(idxExprs);
1098 12 : if (extraUpdatedCols)
1099 0 : bms_free(allUpdatedCols);
1100 :
1101 12 : if (hasexpression)
1102 : {
1103 9 : indexInfo->ii_IndexUnchanged = false;
1104 9 : return false;
1105 : }
1106 :
1107 : /*
1108 : * Deliberately don't consider index predicates. We should even give the
1109 : * hint when result rel's "updated tuple" has no corresponding index
1110 : * tuple, which is possible with a partial index (provided the usual
1111 : * conditions are met).
1112 : */
1113 3 : indexInfo->ii_IndexUnchanged = true;
1114 3 : return true;
1115 : }
1116 :
1117 : /*
1118 : * Indexed expression helper for index_unchanged_by_update().
1119 : *
1120 : * Returns true when Var that appears within allUpdatedCols located.
1121 : */
1122 : static bool
1123 38 : index_expression_changed_walker(Node *node, Bitmapset *allUpdatedCols)
1124 : {
1125 38 : if (node == NULL)
1126 0 : return false;
1127 :
1128 38 : if (IsA(node, Var))
1129 : {
1130 12 : Var *var = (Var *) node;
1131 :
1132 12 : if (bms_is_member(var->varattno - FirstLowInvalidHeapAttributeNumber,
1133 : allUpdatedCols))
1134 : {
1135 : /* Var was updated -- indicates that we should not hint */
1136 9 : return true;
1137 : }
1138 :
1139 : /* Still haven't found a reason to not pass the hint */
1140 3 : return false;
1141 : }
1142 :
1143 26 : return expression_tree_walker(node, index_expression_changed_walker,
1144 : allUpdatedCols);
1145 : }
1146 :
1147 : /*
1148 : * ExecWithoutOverlapsNotEmpty - raise an error if the tuple has an empty
1149 : * range or multirange in the given attribute.
1150 : */
1151 : static void
1152 1081 : ExecWithoutOverlapsNotEmpty(Relation rel, NameData attname, Datum attval, char typtype, Oid atttypid)
1153 : {
1154 : bool isempty;
1155 : RangeType *r;
1156 : MultirangeType *mr;
1157 :
1158 1081 : switch (typtype)
1159 : {
1160 619 : case TYPTYPE_RANGE:
1161 619 : r = DatumGetRangeTypeP(attval);
1162 619 : isempty = RangeIsEmpty(r);
1163 619 : break;
1164 462 : case TYPTYPE_MULTIRANGE:
1165 462 : mr = DatumGetMultirangeTypeP(attval);
1166 462 : isempty = MultirangeIsEmpty(mr);
1167 462 : break;
1168 0 : default:
1169 0 : elog(ERROR, "WITHOUT OVERLAPS column \"%s\" is not a range or multirange",
1170 : NameStr(attname));
1171 : }
1172 :
1173 : /* Report a CHECK_VIOLATION */
1174 1081 : if (isempty)
1175 42 : ereport(ERROR,
1176 : (errcode(ERRCODE_CHECK_VIOLATION),
1177 : errmsg("empty WITHOUT OVERLAPS value found in column \"%s\" in relation \"%s\"",
1178 : NameStr(attname), RelationGetRelationName(rel))));
1179 1039 : }
|