116 conflicttuple->slot, remoteslot,
117 conflicttuple->indexoid,
119 conflicttuple->origin,
127 errmsg(
"conflict detected on relation \"%s.%s\": conflict=%s",
147 if (indexRelation == NULL)
155 if (!indexRelation->
rd_index->indimmediate)
176 return errcode(ERRCODE_UNIQUE_VIOLATION);
261 char *key_desc = NULL;
262 char *local_desc = NULL;
263 char *remote_desc = NULL;
264 char *search_desc = NULL;
268 localslot, &local_desc,
269 remoteslot, &remote_desc,
270 searchslot, &search_desc,
284 if (err_msg->
len == 0)
296 appendStringInfo(&err_detail,
_(
"Key already exists in unique index \"%s\", modified locally in transaction %u at %s"),
300 appendStringInfo(&err_detail,
_(
"Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s"),
312 appendStringInfo(&err_detail,
_(
"Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s"),
317 appendStringInfo(&err_detail,
_(
"Key already exists in unique index \"%s\", modified in transaction %u"),
327 appendStringInfo(&err_detail,
_(
"Updating the row that was modified locally in transaction %u at %s"),
330 appendStringInfo(&err_detail,
_(
"Updating the row that was modified by a different origin \"%s\" in transaction %u at %s"),
335 appendStringInfo(&err_detail,
_(
"Updating the row that was modified by a non-existent origin in transaction %u at %s"),
340 search_desc),
false);
354 appendStringInfo(&err_detail,
_(
"The row to be updated was deleted locally in transaction %u at %s"),
357 appendStringInfo(&err_detail,
_(
"The row to be updated was deleted by a different origin \"%s\" in transaction %u at %s"),
362 appendStringInfo(&err_detail,
_(
"The row to be updated was deleted by a non-existent origin in transaction %u at %s"),
381 appendStringInfo(&err_detail,
_(
"Deleting the row that was modified locally in transaction %u at %s"),
384 appendStringInfo(&err_detail,
_(
"Deleting the row that was modified by a different origin \"%s\" in transaction %u at %s"),
389 appendStringInfo(&err_detail,
_(
"Deleting the row that was modified by a non-existent origin in transaction %u at %s"),
394 search_desc),
false);
413 if (err_msg->
len > 0)
439 Assert((localslot && local_desc) || (remoteslot && remote_desc) ||
440 (searchslot && search_desc));
468 *local_desc =
psprintf(
_(
"local row %s"), desc);
485 tupdesc, modifiedCols,
489 *remote_desc =
psprintf(
_(
"remote row %s"), desc);
518 *search_desc =
psprintf(
_(
"replica identity %s"), desc);
520 *search_desc =
psprintf(
_(
"replica identity full %s"), desc);
Subscription * MySubscription
const char * timestamptz_to_str(TimestampTz t)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
static Datum values[MAXATTR]
#define OidIsValid(objectId)
bool track_commit_timestamp
bool TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts, RepOriginId *nodeid)
void ReportApplyConflict(EState *estate, ResultRelInfo *relinfo, int elevel, ConflictType type, TupleTableSlot *searchslot, TupleTableSlot *remoteslot, List *conflicttuples)
static void errdetail_apply_conflict(EState *estate, ResultRelInfo *relinfo, ConflictType type, TupleTableSlot *searchslot, TupleTableSlot *localslot, TupleTableSlot *remoteslot, Oid indexoid, TransactionId localxmin, RepOriginId localorigin, TimestampTz localts, StringInfo err_msg)
static const char *const ConflictTypeNames[]
static char * build_index_value_desc(EState *estate, Relation localrel, TupleTableSlot *slot, Oid indexoid)
void InitConflictIndexes(ResultRelInfo *relInfo)
static int errcode_apply_conflict(ConflictType type)
static void get_tuple_desc(EState *estate, ResultRelInfo *relinfo, ConflictType type, char **key_desc, TupleTableSlot *searchslot, char **search_desc, TupleTableSlot *localslot, char **local_desc, TupleTableSlot *remoteslot, char **remote_desc, Oid indexoid)
bool GetTupleTransactionInfo(TupleTableSlot *localslot, TransactionId *xmin, RepOriginId *localorigin, TimestampTz *localts)
static void append_tuple_value_detail(StringInfo buf, List *tuple_values, bool need_newline)
@ CT_MULTIPLE_UNIQUE_CONFLICTS
@ CT_UPDATE_ORIGIN_DIFFERS
@ CT_DELETE_ORIGIN_DIFFERS
int errdetail_internal(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
Bitmapset * ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
#define GetPerTupleExprContext(estate)
char * BuildIndexValueDescription(Relation indexRelation, const Datum *values, const bool *isnull)
Assert(PointerIsAligned(start, uint64))
IndexInfo * BuildIndexInfo(Relation index)
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
List * lappend_oid(List *list, Oid datum)
bool CheckRelationOidLockedByMe(Oid relid, LOCKMODE lockmode, bool orstronger)
char * get_rel_name(Oid relid)
char * get_namespace_name(Oid nspid)
bool replorigin_by_oid(RepOriginId roident, bool missing_ok, char **roname)
#define InvalidRepOriginId
#define foreach_ptr(type, var, lst)
#define list_make3(x1, x2, x3)
#define list_make2(x1, x2)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define ERRCODE_T_R_SERIALIZATION_FAILURE
void pgstat_report_subscription_conflict(Oid subid, ConflictType type)
static TransactionId DatumGetTransactionId(Datum X)
char * psprintf(const char *fmt,...)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationGetNamespace(relation)
Oid GetRelationIdentityOrPK(Relation rel)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
List * ri_onConflictArbiterIndexes
RelationPtr ri_IndexRelationDescs
IndexInfo ** ri_IndexRelationInfo
#define MinTransactionIdAttributeNumber
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
#define TTS_IS_VIRTUAL(slot)
static Datum slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)