PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
conflict.h File Reference
#include "nodes/execnodes.h"
#include "utils/timestamp.h"
Include dependency graph for conflict.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define CONFLICT_NUM_TYPES   (CT_DELETE_MISSING + 1)
 

Enumerations

enum  ConflictType {
  CT_INSERT_EXISTS , CT_UPDATE_ORIGIN_DIFFERS , CT_UPDATE_EXISTS , CT_UPDATE_MISSING ,
  CT_DELETE_ORIGIN_DIFFERS , CT_DELETE_MISSING
}
 

Functions

bool GetTupleTransactionInfo (TupleTableSlot *localslot, TransactionId *xmin, RepOriginId *localorigin, TimestampTz *localts)
 
void ReportApplyConflict (EState *estate, ResultRelInfo *relinfo, int elevel, ConflictType type, TupleTableSlot *searchslot, TupleTableSlot *localslot, TupleTableSlot *remoteslot, Oid indexoid, TransactionId localxmin, RepOriginId localorigin, TimestampTz localts)
 
void InitConflictIndexes (ResultRelInfo *relInfo)
 

Macro Definition Documentation

◆ CONFLICT_NUM_TYPES

#define CONFLICT_NUM_TYPES   (CT_DELETE_MISSING + 1)

Definition at line 51 of file conflict.h.

Enumeration Type Documentation

◆ ConflictType

Enumerator
CT_INSERT_EXISTS 
CT_UPDATE_ORIGIN_DIFFERS 
CT_UPDATE_EXISTS 
CT_UPDATE_MISSING 
CT_DELETE_ORIGIN_DIFFERS 
CT_DELETE_MISSING 

Definition at line 24 of file conflict.h.

25 {
26  /* The row to be inserted violates unique constraint */
28 
29  /* The row to be updated was modified by a different origin */
31 
32  /* The updated row value violates unique constraint */
34 
35  /* The row to be updated is missing */
37 
38  /* The row to be deleted was modified by a different origin */
40 
41  /* The row to be deleted is missing */
43 
44  /*
45  * Other conflicts, such as exclusion constraint violations, involve more
46  * complex rules than simple equality checks. These conflicts are left for
47  * future improvements.
48  */
49 } ConflictType;
ConflictType
Definition: conflict.h:25
@ CT_DELETE_MISSING
Definition: conflict.h:42
@ CT_UPDATE_ORIGIN_DIFFERS
Definition: conflict.h:30
@ CT_INSERT_EXISTS
Definition: conflict.h:27
@ CT_UPDATE_EXISTS
Definition: conflict.h:33
@ CT_UPDATE_MISSING
Definition: conflict.h:36
@ CT_DELETE_ORIGIN_DIFFERS
Definition: conflict.h:39

Function Documentation

◆ GetTupleTransactionInfo()

bool GetTupleTransactionInfo ( TupleTableSlot localslot,
TransactionId xmin,
RepOriginId localorigin,
TimestampTz localts 
)

Definition at line 61 of file conflict.c.

63 {
64  Datum xminDatum;
65  bool isnull;
66 
67  xminDatum = slot_getsysattr(localslot, MinTransactionIdAttributeNumber,
68  &isnull);
69  *xmin = DatumGetTransactionId(xminDatum);
70  Assert(!isnull);
71 
72  /*
73  * The commit timestamp data is not available if track_commit_timestamp is
74  * disabled.
75  */
77  {
78  *localorigin = InvalidRepOriginId;
79  *localts = 0;
80  return false;
81  }
82 
83  return TransactionIdGetCommitTsData(*xmin, localts, localorigin);
84 }
#define Assert(condition)
Definition: c.h:863
bool track_commit_timestamp
Definition: commit_ts.c:109
bool TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts, RepOriginId *nodeid)
Definition: commit_ts.c:274
#define InvalidRepOriginId
Definition: origin.h:33
uintptr_t Datum
Definition: postgres.h:64
static TransactionId DatumGetTransactionId(Datum X)
Definition: postgres.h:262
#define MinTransactionIdAttributeNumber
Definition: sysattr.h:22
static Datum slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: tuptable.h:416

References Assert, DatumGetTransactionId(), InvalidRepOriginId, MinTransactionIdAttributeNumber, slot_getsysattr(), track_commit_timestamp, and TransactionIdGetCommitTsData().

Referenced by apply_handle_delete_internal(), apply_handle_tuple_routing(), apply_handle_update_internal(), and CheckAndReportConflict().

◆ InitConflictIndexes()

void InitConflictIndexes ( ResultRelInfo relInfo)

Definition at line 136 of file conflict.c.

137 {
138  List *uniqueIndexes = NIL;
139 
140  for (int i = 0; i < relInfo->ri_NumIndices; i++)
141  {
142  Relation indexRelation = relInfo->ri_IndexRelationDescs[i];
143 
144  if (indexRelation == NULL)
145  continue;
146 
147  /* Detect conflict only for unique indexes */
148  if (!relInfo->ri_IndexRelationInfo[i]->ii_Unique)
149  continue;
150 
151  /* Don't support conflict detection for deferrable index */
152  if (!indexRelation->rd_index->indimmediate)
153  continue;
154 
155  uniqueIndexes = lappend_oid(uniqueIndexes,
156  RelationGetRelid(indexRelation));
157  }
158 
159  relInfo->ri_onConflictArbiterIndexes = uniqueIndexes;
160 }
int i
Definition: isn.c:72
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
#define NIL
Definition: pg_list.h:68
#define RelationGetRelid(relation)
Definition: rel.h:505
bool ii_Unique
Definition: execnodes.h:199
Definition: pg_list.h:54
Form_pg_index rd_index
Definition: rel.h:192
int ri_NumIndices
Definition: execnodes.h:462
List * ri_onConflictArbiterIndexes
Definition: execnodes.h:550
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:465
IndexInfo ** ri_IndexRelationInfo
Definition: execnodes.h:468

References i, IndexInfo::ii_Unique, lappend_oid(), NIL, RelationData::rd_index, RelationGetRelid, ResultRelInfo::ri_IndexRelationDescs, ResultRelInfo::ri_IndexRelationInfo, ResultRelInfo::ri_NumIndices, and ResultRelInfo::ri_onConflictArbiterIndexes.

Referenced by apply_handle_insert_internal(), apply_handle_tuple_routing(), and apply_handle_update_internal().

◆ ReportApplyConflict()

void ReportApplyConflict ( EState estate,
ResultRelInfo relinfo,
int  elevel,
ConflictType  type,
TupleTableSlot searchslot,
TupleTableSlot localslot,
TupleTableSlot remoteslot,
Oid  indexoid,
TransactionId  localxmin,
RepOriginId  localorigin,
TimestampTz  localts 
)

Definition at line 107 of file conflict.c.

112 {
113  Relation localrel = relinfo->ri_RelationDesc;
114 
115  Assert(!OidIsValid(indexoid) ||
117 
119 
120  ereport(elevel,
122  errmsg("conflict detected on relation \"%s.%s\": conflict=%s",
124  RelationGetRelationName(localrel),
126  errdetail_apply_conflict(estate, relinfo, type, searchslot,
127  localslot, remoteslot, indexoid,
128  localxmin, localorigin, localts));
129 }
Subscription * MySubscription
Definition: worker.c:299
#define OidIsValid(objectId)
Definition: c.h:780
static const char *const ConflictTypeNames[]
Definition: conflict.c:26
static int errcode_apply_conflict(ConflictType type)
Definition: conflict.c:166
static int errdetail_apply_conflict(EState *estate, ResultRelInfo *relinfo, ConflictType type, TupleTableSlot *searchslot, TupleTableSlot *localslot, TupleTableSlot *remoteslot, Oid indexoid, TransactionId localxmin, RepOriginId localorigin, TimestampTz localts)
Definition: conflict.c:195
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereport(elevel,...)
Definition: elog.h:149
bool CheckRelationOidLockedByMe(Oid relid, LOCKMODE lockmode, bool orstronger)
Definition: lmgr.c:346
#define RowExclusiveLock
Definition: lockdefs.h:38
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3366
void pgstat_report_subscription_conflict(Oid subid, ConflictType type)
#define RelationGetRelationName(relation)
Definition: rel.h:539
#define RelationGetNamespace(relation)
Definition: rel.h:546
Relation ri_RelationDesc
Definition: execnodes.h:459
const char * type

References Assert, CheckRelationOidLockedByMe(), ConflictTypeNames, ereport, errcode_apply_conflict(), errdetail_apply_conflict(), errmsg(), get_namespace_name(), MySubscription, Subscription::oid, OidIsValid, pgstat_report_subscription_conflict(), RelationGetNamespace, RelationGetRelationName, ResultRelInfo::ri_RelationDesc, RowExclusiveLock, and type.

Referenced by apply_handle_delete_internal(), apply_handle_tuple_routing(), apply_handle_update_internal(), and CheckAndReportConflict().