aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/datum.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/datum.c')
-rw-r--r--src/backend/utils/adt/datum.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c
index af5944d3954..81ea5a48e59 100644
--- a/src/backend/utils/adt/datum.c
+++ b/src/backend/utils/adt/datum.c
@@ -42,6 +42,8 @@
#include "postgres.h"
+#include "access/tuptoaster.h"
+#include "fmgr.h"
#include "utils/datum.h"
#include "utils/expandeddatum.h"
@@ -252,6 +254,61 @@ datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
}
/*-------------------------------------------------------------------------
+ * datum_image_eq
+ *
+ * Compares two datums for identical contents, based on byte images. Return
+ * true if the two datums are equal, false otherwise.
+ *-------------------------------------------------------------------------
+ */
+bool
+datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
+{
+ bool result = true;
+
+ 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. */
+ if (len1 != len2)
+ result = false;
+ else
+ {
+ struct varlena *arg1val;
+ struct varlena *arg2val;
+
+ arg1val = PG_DETOAST_DATUM_PACKED(value1);
+ arg2val = PG_DETOAST_DATUM_PACKED(value2);
+
+ result = (memcmp(VARDATA_ANY(arg1val),
+ VARDATA_ANY(arg2val),
+ len1 - VARHDRSZ) == 0);
+
+ /* Only free memory if it's a copy made here. */
+ if ((Pointer) arg1val != (Pointer) value1)
+ pfree(arg1val);
+ if ((Pointer) arg2val != (Pointer) value2)
+ pfree(arg2val);
+ }
+ }
+ else if (typByVal)
+ {
+ result = (value1 == value2);
+ }
+ else
+ {
+ result = (memcmp(DatumGetPointer(value1),
+ DatumGetPointer(value2),
+ typLen) == 0);
+ }
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------
* datumEstimateSpace
*
* Compute the amount of space that datumSerialize will require for a