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