Make _bt_keep_natts_fast() use datum_image_eq().
authorPeter Geoghegan <[email protected]>
Tue, 12 Nov 2019 21:08:41 +0000 (13:08 -0800)
committerPeter Geoghegan <[email protected]>
Tue, 12 Nov 2019 21:08:41 +0000 (13:08 -0800)
An upcoming patch that adds deduplication to the nbtree AM will rely on
_bt_keep_natts_fast() understanding that differences in TOAST input
state can never affect its answer.  In particular, two opclass-equal
datums (with opclasses deemed safe for deduplication) should never be
treated as unequal by _bt_keep_natts_fast() due to TOAST input
differences.

This also seems like a good idea on general principle.  nbtsplitloc.c
will now occasionally make better decisions about where to split a leaf
page.  The behavior of _bt_keep_natts_fast() is now somewhat closer to
the behavior of _bt_keep_natts().

Discussion: https://postgr.es/m/CAH2-Wzn3Ee49Gmxb7V1VJ3-AC8fWn-Fr8pfWQebHe8rYRxt5OQ@mail.gmail.com

src/backend/access/nbtree/nbtutils.c

index 6a3008dd48d8e7a471157441a300b90d2aeee486..7669a1a66f5a73891f3a7906ef4469d24ea6351a 100644 (file)
@@ -2303,9 +2303,7 @@ _bt_keep_natts(Relation rel, IndexTuple lastleft, IndexTuple firstright,
  * The approach taken here usually provides the same answer as _bt_keep_natts
  * will (for the same pair of tuples from a heapkeyspace index), since the
  * majority of btree opclasses can never indicate that two datums are equal
- * unless they're bitwise equal (once detoasted).  Similarly, result may
- * differ from the _bt_keep_natts result when either tuple has TOASTed datums,
- * though this is barely possible in practice.
+ * unless they're bitwise equal after detoasting.
  *
  * These issues must be acceptable to callers, typically because they're only
  * concerned about making suffix truncation as effective as possible without
@@ -2337,7 +2335,7 @@ _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
                        break;
 
                if (!isNull1 &&
-                       !datumIsEqual(datum1, datum2, att->attbyval, att->attlen))
+                       !datum_image_eq(datum1, datum2, att->attbyval, att->attlen))
                        break;
 
                keepnatts++;