41 "ConflictLogDestNames length mismatch");
69 {.attname =
"schemaname", .atttypid =
TEXTOID},
70 {.attname =
"relname", .atttypid =
TEXTOID},
71 {.attname =
"conflict_type", .atttypid =
TEXTOID},
72 {.attname =
"remote_xid", .atttypid =
XIDOID},
73 {.attname =
"remote_commit_lsn", .atttypid =
LSNOID},
75 {.attname =
"remote_origin", .atttypid =
TEXTOID},
76 {.attname =
"replica_identity_full", .atttypid =
BOOLOID},
77 {.attname =
"replica_identity", .atttypid =
JSONOID},
78 {.attname =
"remote_tuple", .atttypid =
JSONOID},
82#define NUM_CONFLICT_ATTRS ((AttrNumber) lengthof(ConflictLogSchema))
198 (
errmsg(
"created conflict log table \"%s\" for subscription \"%s\"",
225 errmsg(
"unrecognized conflict_log_destination value: \"%s\"", dest),
226 errhint(
"Valid values are \"log\", \"table\", and \"all\".")));
300 errmsg(
"conflict detected on relation \"%s.%s\": conflict=%s",
316 for (
int i = 0;
i <
relInfo->ri_NumIndices;
i++)
320 if (indexRelation ==
NULL)
324 if (!
relInfo->ri_IndexRelationInfo[
i]->ii_Unique)
328 if (!indexRelation->
rd_index->indimmediate)
437 if (err_msg->
len == 0)
472 appendStringInfo(&
err_detail,
_(
"Key already exists in unique index \"%s\", modified by origin \"%s\" in transaction %u at %s: %s."),
492 appendStringInfo(&
err_detail,
_(
"Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s: %s."),
497 appendStringInfo(&
err_detail,
_(
"Key already exists in unique index \"%s\", modified by a non-existent origin in transaction %u at %s."),
659 if (err_msg->
len > 0)
Subscription * MySubscription
const char * timestamptz_to_str(TimestampTz t)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
static Datum values[MAXATTR]
#define Assert(condition)
#define StaticAssertDecl(condition, errmessage)
#define OidIsValid(objectId)
bool track_commit_timestamp
bool TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts, ReplOriginId *nodeid)
const char *const ConflictLogDestNames[]
static const ConflictLogColumnDef ConflictLogSchema[]
#define NUM_CONFLICT_ATTRS
static TupleDesc create_conflict_log_table_tupdesc(void)
bool GetTupleTransactionInfo(TupleTableSlot *localslot, TransactionId *xmin, ReplOriginId *localorigin, TimestampTz *localts)
void ReportApplyConflict(EState *estate, ResultRelInfo *relinfo, int elevel, ConflictType type, TupleTableSlot *searchslot, TupleTableSlot *remoteslot, List *conflicttuples)
static const char *const ConflictTypeNames[]
static char * build_index_value_desc(EState *estate, Relation localrel, TupleTableSlot *slot, Oid indexoid)
static void append_tuple_value_detail(StringInfo buf, List *tuple_values)
static void get_tuple_desc(EState *estate, ResultRelInfo *relinfo, ConflictType type, char **key_desc, TupleTableSlot *localslot, char **local_desc, TupleTableSlot *remoteslot, char **remote_desc, TupleTableSlot *searchslot, char **search_desc, Oid indexoid)
static void errdetail_apply_conflict(EState *estate, ResultRelInfo *relinfo, ConflictType type, TupleTableSlot *searchslot, TupleTableSlot *localslot, TupleTableSlot *remoteslot, Oid indexoid, TransactionId localxmin, ReplOriginId localorigin, TimestampTz localts, StringInfo err_msg)
void InitConflictIndexes(ResultRelInfo *relInfo)
static int errcode_apply_conflict(ConflictType type)
Oid create_conflict_log_table(Oid subid, char *subname, Oid subowner)
ConflictLogDest GetConflictLogDest(const char *dest)
@ CT_MULTIPLE_UNIQUE_CONFLICTS
@ CT_UPDATE_ORIGIN_DIFFERS
@ CT_DELETE_ORIGIN_DIFFERS
@ CONFLICT_LOG_DEST_TABLE
int errcode(int sqlerrcode)
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int errhint(const char *fmt,...) pg_attribute_printf(1
#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)
Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid reltypeid, Oid reloftypeid, Oid ownerid, Oid accessmtd, TupleDesc tupdesc, List *cooked_constraints, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, bool allow_system_table_mods, bool is_internal, Oid relrewrite, ObjectAddress *typaddress)
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_qualified_objname(Oid nspid, char *objname)
char * get_namespace_name(Oid nspid)
bool replorigin_by_oid(ReplOriginId roident, bool missing_ok, char **roname)
#define InvalidReplOriginId
#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)
int pg_strcasecmp(const char *s1, const char *s2)
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 resetStringInfo(StringInfo str)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
#define MinTransactionIdAttributeNumber
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
void NewRelationCreateToastTable(Oid relOid, Datum reloptions)
void FreeTupleDesc(TupleDesc tupdesc)
TupleDesc CreateTemplateTupleDesc(int natts)
void TupleDescFinalize(TupleDesc tupdesc)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
#define TTS_IS_VIRTUAL(slot)
static Datum slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
void CommandCounterIncrement(void)