Teach datum_image_eq() about cstring datums.
authorPeter Geoghegan <pg@bowt.ie>
Tue, 12 Nov 2019 19:25:34 +0000 (11:25 -0800)
committerPeter Geoghegan <pg@bowt.ie>
Tue, 12 Nov 2019 19:25:34 +0000 (11:25 -0800)
Bring datum_image_eq() in line with datumIsEqual() by adding support for
comparing cstring datums.

An upcoming patch that adds deduplication to the nbtree AM will use
datum_image_eq().  datum_image_eq() will need to work with all datatypes
that can be used as the storage type of a B-Tree index column, including
cstring.  (cstring is used as the storage type for columns of type
"name" as a space-saving optimization.)

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

src/backend/utils/adt/datum.c

index 73703efe05a3aa42ff3f876d78fe719f18a58161..b20d0640ea236b4c5e0fabc5d61af20e3fe5c469 100644 (file)
@@ -263,6 +263,8 @@ datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
 bool
 datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
 {
+   Size        len1,
+               len2;
    bool        result = true;
 
    if (typByVal)
@@ -277,9 +279,6 @@ datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
    }
    else if (typLen == -1)
    {
-       Size        len1,
-                   len2;
-
        len1 = toast_raw_datum_size(value1);
        len2 = toast_raw_datum_size(value2);
        /* No need to de-toast if lengths don't match. */
@@ -304,6 +303,20 @@ datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
                pfree(arg2val);
        }
    }
+   else if (typLen == -2)
+   {
+       char       *s1,
+                  *s2;
+
+       /* Compare cstring datums */
+       s1 = DatumGetCString(value1);
+       s2 = DatumGetCString(value2);
+       len1 = strlen(s1) + 1;
+       len2 = strlen(s2) + 1;
+       if (len1 != len2)
+           return false;
+       result = (memcmp(s1, s2, len1) == 0);
+   }
    else
        elog(ERROR, "unexpected typLen: %d", typLen);