mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
Fix replication with replica identity full
The comparison with the target rows on the subscriber side was done with datumIsEqual(), which can have false negatives. For instance, it didn't work reliably for text columns. So use the equality operator provided by the type cache instead. Also add more user documentation about replica identity requirements. Reported-by: Tatsuo Ishii <ishii@sraoss.co.jp>
This commit is contained in:
@ -24,12 +24,14 @@
|
||||
#include "parser/parsetree.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/datum.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/snapmgr.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/typcache.h"
|
||||
#include "utils/tqual.h"
|
||||
|
||||
|
||||
@ -224,13 +226,15 @@ tuple_equals_slot(TupleDesc desc, HeapTuple tup, TupleTableSlot *slot)
|
||||
Datum values[MaxTupleAttributeNumber];
|
||||
bool isnull[MaxTupleAttributeNumber];
|
||||
int attrnum;
|
||||
Form_pg_attribute att;
|
||||
|
||||
heap_deform_tuple(tup, desc, values, isnull);
|
||||
|
||||
/* Check equality of the attributes. */
|
||||
for (attrnum = 0; attrnum < desc->natts; attrnum++)
|
||||
{
|
||||
Form_pg_attribute att;
|
||||
TypeCacheEntry *typentry;
|
||||
|
||||
/*
|
||||
* If one value is NULL and other is not, then they are certainly not
|
||||
* equal
|
||||
@ -245,8 +249,17 @@ tuple_equals_slot(TupleDesc desc, HeapTuple tup, TupleTableSlot *slot)
|
||||
continue;
|
||||
|
||||
att = desc->attrs[attrnum];
|
||||
if (!datumIsEqual(values[attrnum], slot->tts_values[attrnum],
|
||||
att->attbyval, att->attlen))
|
||||
|
||||
typentry = lookup_type_cache(att->atttypid, TYPECACHE_EQ_OPR_FINFO);
|
||||
if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("could not identify an equality operator for type %s",
|
||||
format_type_be(att->atttypid))));
|
||||
|
||||
if (!DatumGetBool(FunctionCall2(&typentry->eq_opr_finfo,
|
||||
values[attrnum],
|
||||
slot->tts_values[attrnum])))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user