129 EState *estate,
bool newIndex,
135 Datum *existing_values,
bool *existing_isnull,
191 foreach(l, indexoidlist)
209 relationDescs[
i] = indexDesc;
210 indexInfoArray[
i] = ii;
233 for (i = 0; i < numIndices; i++)
235 if (indexDescs[i] ==
NULL)
273 List *arbiterIndexes)
307 for (i = 0; i < numIndices; i++)
309 Relation indexRelation = relationDescs[
i];
312 bool satisfiesConstraint;
315 if (indexRelation ==
NULL)
318 indexInfo = indexInfoArray[
i];
322 indexRelation->
rd_index->indexrelid);
338 if (predicate ==
NIL)
347 if (!
ExecQual(predicate, econtext,
false))
374 if (!indexRelation->
rd_index->indisunique)
376 else if (noDupErr && (arbiterIndexes ==
NIL || arbiter))
378 else if (indexRelation->
rd_index->indimmediate)
383 satisfiesConstraint =
415 else if (!indexRelation->
rd_index->indimmediate)
426 satisfiesConstraint =
428 indexRelation, indexInfo,
429 tupleid, values, isnull,
431 waitMode, violationOK,
NULL);
436 !satisfiesConstraint)
445 if (indexRelation->
rd_index->indimmediate && specConflict)
446 *specConflict =
true;
473 List *arbiterIndexes)
485 bool checkedIndex =
false;
512 for (i = 0; i < numIndices; i++)
514 Relation indexRelation = relationDescs[
i];
516 bool satisfiesConstraint;
518 if (indexRelation ==
NULL)
521 indexInfo = indexInfoArray[
i];
531 if (arbiterIndexes !=
NIL &&
533 indexRelation->
rd_index->indexrelid))
536 if (!indexRelation->
rd_index->indimmediate)
538 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
539 errmsg(
"ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters"),
555 if (predicate ==
NIL)
564 if (!
ExecQual(predicate, econtext,
false))
578 satisfiesConstraint =
580 indexInfo, &invalidItemPtr,
581 values, isnull, estate,
false,
584 if (!satisfiesConstraint)
588 if (arbiterIndexes !=
NIL && !checkedIndex)
589 elog(
ERROR,
"unexpected failure to find arbiter index");
641 EState *estate,
bool newIndex,
649 int index_natts = index->
rd_index->indnatts;
676 for (i = 0; i < index_natts; i++)
688 for (i = 0; i < index_natts; i++)
720 index_scan =
index_beginscan(heap, index, &DirtySnapshot, index_natts, 0);
732 char *error_existing;
741 elog(
ERROR,
"found self tuple multiple times in index \"%s\"",
753 existing_values, existing_isnull);
778 DirtySnapshot.
xmin : DirtySnapshot.
xmax;
806 *conflictTid = tup->
t_self;
815 (
errcode(ERRCODE_EXCLUSION_VIOLATION),
816 errmsg(
"could not create exclusion constraint \"%s\"",
818 error_new && error_existing ?
819 errdetail(
"Key %s conflicts with key %s.",
820 error_new, error_existing) :
826 (
errcode(ERRCODE_EXCLUSION_VIOLATION),
827 errmsg(
"conflicting key value violates exclusion constraint \"%s\"",
829 error_new && error_existing ?
830 errdetail(
"Key %s conflicts with existing key %s.",
831 error_new, error_existing) :
832 errdetail(
"Key conflicts with existing key."),
865 EState *estate,
bool newIndex)
879 Datum *existing_values,
bool *existing_isnull,
882 int index_natts = index->
rd_index->indnatts;
885 for (i = 0; i < index_natts; i++)
888 if (existing_isnull[i])
#define ItemPointerIsValid(pointer)
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
List * ExecInsertIndexTuples(TupleTableSlot *slot, ItemPointer tupleid, EState *estate, bool noDupErr, bool *specConflict, List *arbiterIndexes)
bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique)
#define RelationGetDescr(relation)
#define RelationGetForm(relation)
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
int errcode(int sqlerrcode)
IndexInfo * BuildIndexInfo(Relation index)
List * lappend_oid(List *list, Oid datum)
bool ExecCheckIndexConstraints(TupleTableSlot *slot, EState *estate, ItemPointer conflictTid, List *arbiterIndexes)
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)
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
#define GetPerTupleExprContext(estate)
int errtableconstraint(Relation rel, const char *conname)
static bool index_recheck_constraint(Relation index, Oid *constr_procs, Datum *existing_values, bool *existing_isnull, Datum *new_values)
#define InitDirtySnapshot(snapshotdata)
void SpeculativeInsertionWait(TransactionId xid, uint32 token)
TransactionId GetCurrentTransactionId(void)
void ScanKeyEntryInitialize(ScanKey entry, int flags, AttrNumber attributeNumber, StrategyNumber strategy, Oid subtype, Oid collation, RegProcedure procedure, Datum argument)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
int errdetail(const char *fmt,...)
bool ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
#define RelationGetRelationName(relation)
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
void index_endscan(IndexScanDesc scan)
Datum OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
#define ereport(elevel, rest)
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool list_member_oid(const List *list, Oid datum)
void XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
static int list_length(const List *l)
TupleTableSlot * ecxt_scantuple
List * RelationGetIndexList(Relation relation)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
void index_close(Relation relation, LOCKMODE lockmode)
static Datum values[MAXATTR]
#define ItemPointerSetInvalid(pointer)
int errmsg(const char *fmt,...)
void list_free(List *list)
IndexInfo ** ri_IndexRelationInfo
void BuildSpeculativeIndexInfo(Relation index, IndexInfo *ii)
char * BuildIndexValueDescription(Relation indexRelation, Datum *values, bool *isnull)
void check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex)
#define TransactionIdIsValid(xid)
uint16 * ii_ExclusionStrats
#define RelationGetRelid(relation)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
RelationPtr ri_IndexRelationDescs
HeapTuple index_getnext(IndexScanDesc scan, ScanDirection direction)
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, int norderbys)
ResultRelInfo * es_result_relation_info