aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2017-06-23 15:12:36 -0400
committerPeter Eisentraut <peter_e@gmx.net>2017-06-23 15:40:17 -0400
commit08859bb5c2cebc132629ca838113d27bb31b990c (patch)
tree8dcb2d337a50b81c70c9769306c66e9f6b107a7f /src/backend/executor
parent0b13b2a7712b6f91590b7589a314240a14520c2f (diff)
downloadpostgresql-08859bb5c2cebc132629ca838113d27bb31b990c.tar.gz
postgresql-08859bb5c2cebc132629ca838113d27bb31b990c.zip
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>
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execReplication.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index 6dae79a8f00..59f14e997f5 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -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;
}