|
18 | 18 | #include "access/relscan.h"
|
19 | 19 | #include "access/tableam.h"
|
20 | 20 | #include "access/transam.h"
|
| 21 | +#include "access/detoast.h" |
21 | 22 | #include "access/xact.h"
|
22 | 23 | #include "commands/trigger.h"
|
23 | 24 | #include "executor/executor.h"
|
@@ -263,11 +264,33 @@ tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2,
|
263 | 264 | {
|
264 | 265 | typentry = lookup_type_cache(att->atttypid,
|
265 | 266 | TYPECACHE_EQ_OPR_FINFO);
|
| 267 | + /* |
| 268 | + * MTM-CRUTCH: vanilla bails out here if equality op can't be found, |
| 269 | + * i.e. type doesn't have btree nor hash opclasses, which means you |
| 270 | + * can't have e.g. box type as part of replica identity. That's |
| 271 | + * unfortunate for mtm as some regression tests (index_including_gist |
| 272 | + * for instance) do update/delete on geometric types without unique |
| 273 | + * index (full replica identity). |
| 274 | + * |
| 275 | + * Binary comparison done here is also dubious as generally equal |
| 276 | + * values might not be binary equal, but sane replication identities |
| 277 | + * should have btree opclass anyway. One more alternative would be to |
| 278 | + * try to search for 'same' strategy of R-tree gist, but it is |
| 279 | + * unreliable as gist strategies are not fixed... |
| 280 | + */ |
266 | 281 | if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
|
267 |
| - ereport(ERROR, |
268 |
| - (errcode(ERRCODE_UNDEFINED_FUNCTION), |
269 |
| - errmsg("could not identify an equality operator for type %s", |
270 |
| - format_type_be(att->atttypid)))); |
| 282 | + { |
| 283 | + if (att->attlen == -1) |
| 284 | + { |
| 285 | + struct varlena *vl1 = (struct varlena *) DatumGetPointer(slot1->tts_values[attrnum]); |
| 286 | + struct varlena *vl2 = (struct varlena *) DatumGetPointer(slot2->tts_values[attrnum]); |
| 287 | + return datumIsEqual(PointerGetDatum(detoast_attr(vl1)), |
| 288 | + PointerGetDatum(detoast_attr(vl2)), |
| 289 | + att->attbyval, -1); |
| 290 | + } |
| 291 | + return datumIsEqual(slot1->tts_values[attrnum], slot2->tts_values[attrnum], |
| 292 | + att->attbyval, att->attlen); |
| 293 | + } |
271 | 294 | eq[attrnum] = typentry;
|
272 | 295 | }
|
273 | 296 |
|
|
0 commit comments