131 #define GetUpdatedColumns(relinfo, estate) \ 132 (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols) 133 #define GetExtraUpdatedColumns(relinfo, estate) \ 134 (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols) 140 EState *estate,
bool newIndex,
146 Datum *existing_values,
bool *existing_isnull,
207 foreach(l, indexoidlist)
225 relationDescs[
i] = indexDesc;
226 indexInfoArray[
i] = ii;
249 for (i = 0; i < numIndices; i++)
251 if (indexDescs[i] == NULL)
299 List *arbiterIndexes)
337 for (i = 0; i < numIndices; i++)
339 Relation indexRelation = relationDescs[
i];
344 bool satisfiesConstraint;
346 if (indexRelation == NULL)
349 indexInfo = indexInfoArray[
i];
365 if (predicate == NULL)
387 applyNoDupErr = noDupErr &&
388 (arbiterIndexes ==
NIL ||
390 indexRelation->
rd_index->indexrelid));
405 if (!indexRelation->
rd_index->indisunique)
407 else if (applyNoDupErr)
409 else if (indexRelation->
rd_index->indimmediate)
424 satisfiesConstraint =
458 else if (!indexRelation->
rd_index->indimmediate)
469 satisfiesConstraint =
471 indexRelation, indexInfo,
472 tupleid, values, isnull,
474 waitMode, violationOK, NULL);
479 !satisfiesConstraint)
488 if (indexRelation->
rd_index->indimmediate && specConflict)
489 *specConflict =
true;
516 List *arbiterIndexes)
527 bool checkedIndex =
false;
553 for (i = 0; i < numIndices; i++)
555 Relation indexRelation = relationDescs[
i];
557 bool satisfiesConstraint;
559 if (indexRelation == NULL)
562 indexInfo = indexInfoArray[
i];
572 if (arbiterIndexes !=
NIL &&
574 indexRelation->
rd_index->indexrelid))
577 if (!indexRelation->
rd_index->indimmediate)
579 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
580 errmsg(
"ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters"),
596 if (predicate == NULL)
617 satisfiesConstraint =
619 indexInfo, &invalidItemPtr,
620 values, isnull, estate,
false,
623 if (!satisfiesConstraint)
627 if (arbiterIndexes !=
NIL && !checkedIndex)
628 elog(
ERROR,
"unexpected failure to find arbiter index");
680 EState *estate,
bool newIndex,
714 for (i = 0; i < indnkeyatts; i++)
726 for (i = 0; i < indnkeyatts; i++)
758 index_scan =
index_beginscan(heap, index, &DirtySnapshot, indnkeyatts, 0);
759 index_rescan(index_scan, scankeys, indnkeyatts, NULL, 0);
768 char *error_existing;
777 elog(
ERROR,
"found self tuple multiple times in index \"%s\"",
788 existing_values, existing_isnull);
813 DirtySnapshot.
xmin : DirtySnapshot.
xmax;
829 &existing_slot->
tts_tid, reason_wait);
841 *conflictTid = existing_slot->
tts_tid;
850 (
errcode(ERRCODE_EXCLUSION_VIOLATION),
851 errmsg(
"could not create exclusion constraint \"%s\"",
853 error_new && error_existing ?
854 errdetail(
"Key %s conflicts with key %s.",
855 error_new, error_existing) :
861 (
errcode(ERRCODE_EXCLUSION_VIOLATION),
862 errmsg(
"conflicting key value violates exclusion constraint \"%s\"",
864 error_new && error_existing ?
865 errdetail(
"Key %s conflicts with existing key %s.",
866 error_new, error_existing) :
867 errdetail(
"Key conflicts with existing key."),
900 EState *estate,
bool newIndex)
914 Datum *existing_values,
bool *existing_isnull,
920 for (i = 0; i < indnkeyatts; i++)
923 if (existing_isnull[i])
950 bool hasexpression =
false;
970 hasexpression =
true;
999 if (!extraUpdatedCols)
1000 allUpdatedCols = updatedCols;
1002 allUpdatedCols =
bms_union(updatedCols, extraUpdatedCols);
1016 if (extraUpdatedCols)
1052 (
void *) allUpdatedCols);
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
#define ItemPointerIsValid(pointer)
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
#define IsA(nodeptr, _type_)
#define InitDirtySnapshot(snapshotdata)
ExprState * ii_PredicateState
#define RelationGetForm(relation)
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
int errcode(int sqlerrcode)
#define FirstLowInvalidHeapAttributeNumber
IndexInfo * BuildIndexInfo(Relation index)
static bool ExecQual(ExprState *state, ExprContext *econtext)
List * ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool update, bool noDupErr, bool *specConflict, List *arbiterIndexes)
List * lappend_oid(List *list, Oid datum)
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)
void SpeculativeInsertionWait(TransactionId xid, uint32 token)
TransactionId GetCurrentTransactionId(void)
#define GetExtraUpdatedColumns(relinfo, estate)
void ScanKeyEntryInitialize(ScanKey entry, int flags, AttrNumber attributeNumber, StrategyNumber strategy, Oid subtype, Oid collation, RegProcedure procedure, Datum argument)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
List * RelationGetIndexExpressions(Relation relation)
int errdetail(const char *fmt,...)
#define RelationGetRelationName(relation)
ExprState * ExecPrepareQual(List *qual, EState *estate)
#define IndexRelationGetNumberOfKeyAttributes(relation)
void index_endscan(IndexScanDesc scan)
Datum OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
static bool index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate, IndexInfo *indexInfo, Relation indexRelation)
#define ereport(elevel,...)
void bms_free(Bitmapset *a)
bool list_member_oid(const List *list, Oid datum)
#define GetUpdatedColumns(relinfo, estate)
void XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
#define Assert(condition)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
static int list_length(const List *l)
bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
TupleTableSlot * ecxt_scantuple
List * RelationGetIndexList(Relation relation)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
void index_close(Relation relation, LOCKMODE lockmode)
static bool index_expression_changed_walker(Node *node, Bitmapset *allUpdatedCols)
static Datum values[MAXATTR]
#define ItemPointerSetInvalid(pointer)
bool ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, ItemPointer conflictTid, List *arbiterIndexes)
int errmsg(const char *fmt,...)
void list_free(List *list)
IndexInfo ** ri_IndexRelationInfo
void BuildSpeculativeIndexInfo(Relation index, IndexInfo *ii)
bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
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)
AttrNumber ii_IndexAttrNumbers[INDEX_MAX_KEYS]
uint16 * ii_ExclusionStrats
bool bms_is_member(int x, const Bitmapset *a)
#define RelationGetRelid(relation)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
RelationPtr ri_IndexRelationDescs
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, int norderbys)