From 14cd3e0ad4a7f05937b5c6df79d0d8c4963fcb07 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Sun, 28 Aug 2022 10:47:38 +0200
Subject: [PATCH v2 2/2] Convert *GetDatum() and DatumGet*() macros to inline
 functions

The previous macro implementations just cast the argument to a target
type but did not check whether the input type was appropriate.  The
function implementation can do better type checking of the input type.

Peter Eisentraut, reviewed by Aleksander Alekseev

Discussion: http://postgr.es/m/8528fb7e-0aa2-6b54-85fb-0c0886dbd6ed%40enterprisedb.com
---
 doc/src/sgml/xfunc.sgml             |   2 +-
 src/backend/utils/mb/mbutils.c      |  12 +-
 src/include/access/gin.h            |  14 +-
 src/include/funcapi.h               |  14 +-
 src/include/postgres.h              | 275 +++++++++++++++++++---------
 src/include/tsearch/ts_type.h       |  46 ++++-
 src/include/tsearch/ts_utils.h      |  14 +-
 src/include/utils/cash.h            |  14 +-
 src/include/utils/date.h            |  42 ++++-
 src/include/utils/expandeddatum.h   |  13 +-
 src/include/utils/expandedrecord.h  |  16 +-
 src/include/utils/geo_decls.h       |  98 ++++++++--
 src/include/utils/inet.h            |  49 ++++-
 src/include/utils/jsonb.h           |  31 +++-
 src/include/utils/jsonpath.h        |  14 +-
 src/include/utils/multirangetypes.h |  23 ++-
 src/include/utils/numeric.h         |  21 ++-
 src/include/utils/pg_lsn.h          |  13 +-
 src/include/utils/rangetypes.h      |  23 ++-
 src/include/utils/timestamp.h       |  44 ++++-
 src/include/utils/uuid.h            |  15 +-
 src/include/utils/varbit.h          |  21 ++-
 src/include/utils/xid8.h            |  14 +-
 src/include/utils/xml.h             |  13 +-
 24 files changed, 655 insertions(+), 186 deletions(-)

diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index b8cefb9c2c..cf5810b3c1 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -2763,7 +2763,7 @@ c_overpaid(PG_FUNCTION_ARGS)
      is  null.   <function>GetAttributeByName</function> returns a <type>Datum</type>
      value that you can convert to the proper data type by using the
      appropriate <function>DatumGet<replaceable>XXX</replaceable>()</function>
-     macro.  Note that the return value is meaningless if the null flag is
+     function.  Note that the return value is meaningless if the null flag is
      set; always check the null flag before trying to do anything with the
      result.
     </para>
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 0543c574c6..474ab476f5 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -409,8 +409,8 @@ pg_do_encoding_conversion(unsigned char *src, int len,
 	(void) OidFunctionCall6(proc,
 							Int32GetDatum(src_encoding),
 							Int32GetDatum(dest_encoding),
-							CStringGetDatum(src),
-							CStringGetDatum(result),
+							CStringGetDatum((char *) src),
+							CStringGetDatum((char *) result),
 							Int32GetDatum(len),
 							BoolGetDatum(false));
 
@@ -485,8 +485,8 @@ pg_do_encoding_conversion_buf(Oid proc,
 	result = OidFunctionCall6(proc,
 							  Int32GetDatum(src_encoding),
 							  Int32GetDatum(dest_encoding),
-							  CStringGetDatum(src),
-							  CStringGetDatum(dest),
+							  CStringGetDatum((char *) src),
+							  CStringGetDatum((char *) dest),
 							  Int32GetDatum(srclen),
 							  BoolGetDatum(noError));
 	return DatumGetInt32(result);
@@ -910,8 +910,8 @@ pg_unicode_to_server(pg_wchar c, unsigned char *s)
 	FunctionCall6(Utf8ToServerConvProc,
 				  Int32GetDatum(PG_UTF8),
 				  Int32GetDatum(server_encoding),
-				  CStringGetDatum(c_as_utf8),
-				  CStringGetDatum(s),
+				  CStringGetDatum((char *) c_as_utf8),
+				  CStringGetDatum((char *) s),
 				  Int32GetDatum(c_as_utf8_len),
 				  BoolGetDatum(false));
 }
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index aacc665fdc..fff861e219 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -62,8 +62,18 @@ typedef char GinTernaryValue;
 #define GIN_MAYBE		2		/* don't know if item is present / don't know
 								 * if matches */
 
-#define DatumGetGinTernaryValue(X) ((GinTernaryValue)(X))
-#define GinTernaryValueGetDatum(X) ((Datum)(X))
+static inline GinTernaryValue
+DatumGetGinTernaryValue(Datum X)
+{
+	return (GinTernaryValue) X;
+}
+
+static inline Datum
+GinTernaryValueGetDatum(GinTernaryValue X)
+{
+	return (Datum) X;
+}
+
 #define PG_RETURN_GIN_TERNARY_VALUE(x) return GinTernaryValueGetDatum(x)
 
 /* GUC parameters */
diff --git a/src/include/funcapi.h b/src/include/funcapi.h
index dc3d819a1c..8c2521a591 100644
--- a/src/include/funcapi.h
+++ b/src/include/funcapi.h
@@ -204,7 +204,7 @@ extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple);
  * Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple) - convert a
  *		HeapTupleHeader to a Datum.
  *
- * Macro declarations:
+ * Inline declarations:
  * HeapTupleGetDatum(HeapTuple tuple) - convert a HeapTuple to a Datum.
  *
  * Obsolete routines and macros:
@@ -217,10 +217,6 @@ extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple);
  *----------
  */
 
-#define HeapTupleGetDatum(tuple)		HeapTupleHeaderGetDatum((tuple)->t_data)
-/* obsolete version of above */
-#define TupleGetDatum(_slot, _tuple)	HeapTupleGetDatum(_tuple)
-
 extern TupleDesc RelationNameGetTupleDesc(const char *relname);
 extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases);
 
@@ -230,6 +226,14 @@ extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc);
 extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values);
 extern Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple);
 
+static inline Datum
+HeapTupleGetDatum(const HeapTupleData *tuple)
+{
+	return HeapTupleHeaderGetDatum(tuple->t_data);
+}
+/* obsolete version of above */
+#define TupleGetDatum(_slot, _tuple)	HeapTupleGetDatum(_tuple)
+
 
 /*----------
  *		Support for Set Returning Functions (SRFs)
diff --git a/src/include/postgres.h b/src/include/postgres.h
index 13903fa022..45c9f6563c 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -24,7 +24,7 @@
  *	  section	description
  *	  -------	------------------------------------------------
  *		1)		variable-length datatypes (TOAST support)
- *		2)		Datum type + support macros
+ *		2)		Datum type + support functions
  *		3)		miscellaneous
  *
  *	 NOTES
@@ -395,7 +395,7 @@ typedef struct
 
 
 /* ----------------------------------------------------------------
- *				Section 2:	Datum type + support macros
+ *				Section 2:	Datum type + support functions
  * ----------------------------------------------------------------
  */
 
@@ -405,7 +405,7 @@ typedef struct
  *
  * sizeof(Datum) == sizeof(void *) == 4 or 8
  *
- * The macros below and the analogous macros for other types should be used to
+ * The functions below and the analogous functions for other types should be used to
  * convert between a Datum and the appropriate C type.
  */
 
@@ -434,8 +434,11 @@ typedef struct NullableDatum
  *
  * Note: any nonzero value will be considered true.
  */
-
-#define DatumGetBool(X) ((bool) ((X) != 0))
+static inline bool
+DatumGetBool(Datum X)
+{
+	return (X != 0);
+}
 
 /*
  * BoolGetDatum
@@ -443,162 +446,231 @@ typedef struct NullableDatum
  *
  * Note: any nonzero value will be considered true.
  */
-
-#define BoolGetDatum(X) ((Datum) ((X) ? 1 : 0))
+static inline Datum
+BoolGetDatum(bool X)
+{
+	return (Datum) (X ? 1 : 0);
+}
 
 /*
  * DatumGetChar
  *		Returns character value of a datum.
  */
-
-#define DatumGetChar(X) ((char) (X))
+static inline char
+DatumGetChar(Datum X)
+{
+	return (char) X;
+}
 
 /*
  * CharGetDatum
  *		Returns datum representation for a character.
  */
-
-#define CharGetDatum(X) ((Datum) (X))
+static inline Datum
+CharGetDatum(char X)
+{
+	return (Datum) X;
+}
 
 /*
  * Int8GetDatum
  *		Returns datum representation for an 8-bit integer.
  */
-
-#define Int8GetDatum(X) ((Datum) (X))
+static inline Datum
+Int8GetDatum(int8 X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetUInt8
  *		Returns 8-bit unsigned integer value of a datum.
  */
-
-#define DatumGetUInt8(X) ((uint8) (X))
+static inline uint8
+DatumGetUInt8(Datum X)
+{
+	return (uint8) X;
+}
 
 /*
  * UInt8GetDatum
  *		Returns datum representation for an 8-bit unsigned integer.
  */
-
-#define UInt8GetDatum(X) ((Datum) (X))
+static inline Datum
+UInt8GetDatum(uint8 X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetInt16
  *		Returns 16-bit integer value of a datum.
  */
-
-#define DatumGetInt16(X) ((int16) (X))
+static inline int16
+DatumGetInt16(Datum X)
+{
+	return (int16) X;
+}
 
 /*
  * Int16GetDatum
  *		Returns datum representation for a 16-bit integer.
  */
-
-#define Int16GetDatum(X) ((Datum) (X))
+static inline Datum
+Int16GetDatum(int16 X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetUInt16
  *		Returns 16-bit unsigned integer value of a datum.
  */
-
-#define DatumGetUInt16(X) ((uint16) (X))
+static inline uint16
+DatumGetUInt16(Datum X)
+{
+	return (uint16) X;
+}
 
 /*
  * UInt16GetDatum
  *		Returns datum representation for a 16-bit unsigned integer.
  */
-
-#define UInt16GetDatum(X) ((Datum) (X))
+static inline Datum
+UInt16GetDatum(uint16 X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetInt32
  *		Returns 32-bit integer value of a datum.
  */
-
-#define DatumGetInt32(X) ((int32) (X))
+static inline int32
+DatumGetInt32(Datum X)
+{
+	return (int32) X;
+}
 
 /*
  * Int32GetDatum
  *		Returns datum representation for a 32-bit integer.
  */
-
-#define Int32GetDatum(X) ((Datum) (X))
+static inline Datum
+Int32GetDatum(int32 X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetUInt32
  *		Returns 32-bit unsigned integer value of a datum.
  */
-
-#define DatumGetUInt32(X) ((uint32) (X))
+static inline uint32
+DatumGetUInt32(Datum X)
+{
+	return (uint32) X;
+}
 
 /*
  * UInt32GetDatum
  *		Returns datum representation for a 32-bit unsigned integer.
  */
-
-#define UInt32GetDatum(X) ((Datum) (X))
+static inline Datum
+UInt32GetDatum(uint32 X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetObjectId
  *		Returns object identifier value of a datum.
  */
-
-#define DatumGetObjectId(X) ((Oid) (X))
+static inline Oid
+DatumGetObjectId(Datum X)
+{
+	return (Oid) X;
+}
 
 /*
  * ObjectIdGetDatum
  *		Returns datum representation for an object identifier.
  */
-
-#define ObjectIdGetDatum(X) ((Datum) (X))
+static inline Datum
+ObjectIdGetDatum(Oid X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetTransactionId
  *		Returns transaction identifier value of a datum.
  */
-
-#define DatumGetTransactionId(X) ((TransactionId) (X))
+static inline TransactionId
+DatumGetTransactionId(Datum X)
+{
+	return (TransactionId) X;
+}
 
 /*
  * TransactionIdGetDatum
  *		Returns datum representation for a transaction identifier.
  */
-
-#define TransactionIdGetDatum(X) ((Datum) (X))
+static inline Datum
+TransactionIdGetDatum(TransactionId X)
+{
+	return (Datum) X;
+}
 
 /*
  * MultiXactIdGetDatum
  *		Returns datum representation for a multixact identifier.
  */
-
-#define MultiXactIdGetDatum(X) ((Datum) (X))
+static inline Datum
+MultiXactIdGetDatum(MultiXactId X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetCommandId
  *		Returns command identifier value of a datum.
  */
-
-#define DatumGetCommandId(X) ((CommandId) (X))
+static inline CommandId
+DatumGetCommandId(Datum X)
+{
+	return (CommandId) X;
+}
 
 /*
  * CommandIdGetDatum
  *		Returns datum representation for a command identifier.
  */
-
-#define CommandIdGetDatum(X) ((Datum) (X))
+static inline Datum
+CommandIdGetDatum(CommandId X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetPointer
  *		Returns pointer value of a datum.
  */
-
-#define DatumGetPointer(X) ((Pointer) (X))
+static inline Pointer
+DatumGetPointer(Datum X)
+{
+	return (Pointer) X;
+}
 
 /*
  * PointerGetDatum
  *		Returns datum representation for a pointer.
  */
-
-#define PointerGetDatum(X) ((Datum) (X))
+static inline Datum
+PointerGetDatum(const void *X)
+{
+	return (Datum) X;
+}
 
 /*
  * DatumGetCString
@@ -607,8 +679,11 @@ typedef struct NullableDatum
  * Note: C string is not a full-fledged Postgres type at present,
  * but type input functions use this conversion for their inputs.
  */
-
-#define DatumGetCString(X) ((char *) DatumGetPointer(X))
+static inline char *
+DatumGetCString(Datum X)
+{
+	return (char *) DatumGetPointer(X);
+}
 
 /*
  * CStringGetDatum
@@ -619,15 +694,21 @@ typedef struct NullableDatum
  * Note: CString is pass-by-reference; caller must ensure the pointed-to
  * value has adequate lifetime.
  */
-
-#define CStringGetDatum(X) PointerGetDatum(X)
+static inline Datum
+CStringGetDatum(const char *X)
+{
+	return PointerGetDatum(X);
+}
 
 /*
  * DatumGetName
  *		Returns name value of a datum.
  */
-
-#define DatumGetName(X) ((Name) DatumGetPointer(X))
+static inline Name
+DatumGetName(Datum X)
+{
+	return (Name) DatumGetPointer(X);
+}
 
 /*
  * NameGetDatum
@@ -636,21 +717,27 @@ typedef struct NullableDatum
  * Note: Name is pass-by-reference; caller must ensure the pointed-to
  * value has adequate lifetime.
  */
-
-#define NameGetDatum(X) CStringGetDatum(NameStr(*(X)))
+static inline Datum
+NameGetDatum(const NameData *X)
+{
+	return CStringGetDatum(NameStr(*X));
+}
 
 /*
  * DatumGetInt64
  *		Returns 64-bit integer value of a datum.
  *
- * Note: this macro hides whether int64 is pass by value or by reference.
+ * Note: this function hides whether int64 is pass by value or by reference.
  */
-
+static inline int64
+DatumGetInt64(Datum X)
+{
 #ifdef USE_FLOAT8_BYVAL
-#define DatumGetInt64(X) ((int64) (X))
+	return (int64) X;
 #else
-#define DatumGetInt64(X) (* ((int64 *) DatumGetPointer(X)))
+	return *((int64 *) DatumGetPointer(X));
 #endif
+}
 
 /*
  * Int64GetDatum
@@ -659,25 +746,32 @@ typedef struct NullableDatum
  * Note: if int64 is pass by reference, this function returns a reference
  * to palloc'd space.
  */
-
 #ifdef USE_FLOAT8_BYVAL
-#define Int64GetDatum(X) ((Datum) (X))
+static inline Datum
+Int64GetDatum(int64 X)
+{
+	return (Datum) X;
+}
 #else
 extern Datum Int64GetDatum(int64 X);
 #endif
 
+
 /*
  * DatumGetUInt64
  *		Returns 64-bit unsigned integer value of a datum.
  *
- * Note: this macro hides whether int64 is pass by value or by reference.
+ * Note: this function hides whether int64 is pass by value or by reference.
  */
-
+static inline uint64
+DatumGetUInt64(Datum X)
+{
 #ifdef USE_FLOAT8_BYVAL
-#define DatumGetUInt64(X) ((uint64) (X))
+	return (uint64) X;
 #else
-#define DatumGetUInt64(X) (* ((uint64 *) DatumGetPointer(X)))
+	return *((uint64 *) DatumGetPointer(X));
 #endif
+}
 
 /*
  * UInt64GetDatum
@@ -686,12 +780,15 @@ extern Datum Int64GetDatum(int64 X);
  * Note: if int64 is pass by reference, this function returns a reference
  * to palloc'd space.
  */
-
+static inline Datum
+UInt64GetDatum(uint64 X)
+{
 #ifdef USE_FLOAT8_BYVAL
-#define UInt64GetDatum(X) ((Datum) (X))
+	return (Datum) X;
 #else
-#define UInt64GetDatum(X) Int64GetDatum((int64) (X))
+	return Int64GetDatum((int64) X);
 #endif
+}
 
 /*
  * Float <-> Datum conversions
@@ -739,13 +836,12 @@ Float4GetDatum(float4 X)
  * DatumGetFloat8
  *		Returns 8-byte floating point value of a datum.
  *
- * Note: this macro hides whether float8 is pass by value or by reference.
+ * Note: this function hides whether float8 is pass by value or by reference.
  */
-
-#ifdef USE_FLOAT8_BYVAL
 static inline float8
 DatumGetFloat8(Datum X)
 {
+#ifdef USE_FLOAT8_BYVAL
 	union
 	{
 		int64		value;
@@ -754,10 +850,10 @@ DatumGetFloat8(Datum X)
 
 	myunion.value = DatumGetInt64(X);
 	return myunion.retval;
-}
 #else
-#define DatumGetFloat8(X) (* ((float8 *) DatumGetPointer(X)))
+	return *((float8 *) DatumGetPointer(X));
 #endif
+}
 
 /*
  * Float8GetDatum
@@ -766,7 +862,6 @@ DatumGetFloat8(Datum X)
  * Note: if float8 is pass by reference, this function returns a reference
  * to palloc'd space.
  */
-
 #ifdef USE_FLOAT8_BYVAL
 static inline Datum
 Float8GetDatum(float8 X)
@@ -789,22 +884,34 @@ extern Datum Float8GetDatum(float8 X);
  * Int64GetDatumFast
  * Float8GetDatumFast
  *
- * These macros are intended to allow writing code that does not depend on
+ * These functions are intended to allow writing code that does not depend on
  * whether int64 and float8 are pass-by-reference types, while not
  * sacrificing performance when they are.  The argument must be a variable
  * that will exist and have the same value for as long as the Datum is needed.
  * In the pass-by-ref case, the address of the variable is taken to use as
  * the Datum.  In the pass-by-val case, these will be the same as the non-Fast
- * macros.
+ * functions.
  */
 
+static inline Datum
+Int64GetDatumFast(int64 X)
+{
+#ifdef USE_FLOAT8_BYVAL
+	return Int64GetDatum(X);
+#else
+	return PointerGetDatum(&X);
+#endif
+}
+
+static inline Datum
+Float8GetDatumFast(float8 X)
+{
 #ifdef USE_FLOAT8_BYVAL
-#define Int64GetDatumFast(X)  Int64GetDatum(X)
-#define Float8GetDatumFast(X) Float8GetDatum(X)
+	return Float8GetDatum(X);
 #else
-#define Int64GetDatumFast(X)  PointerGetDatum(&(X))
-#define Float8GetDatumFast(X) PointerGetDatum(&(X))
+	return PointerGetDatum(&X);
 #endif
+}
 
 
 /* ----------------------------------------------------------------
diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h
index 689b2d1cfb..f1ec84702d 100644
--- a/src/include/tsearch/ts_type.h
+++ b/src/include/tsearch/ts_type.h
@@ -111,12 +111,27 @@ typedef TSVectorData *TSVector;
 #define POSDATAPTR(x,e) (_POSVECPTR(x,e)->pos)
 
 /*
- * fmgr interface macros
+ * fmgr interface functions
  */
 
-#define DatumGetTSVector(X)			((TSVector) PG_DETOAST_DATUM(X))
-#define DatumGetTSVectorCopy(X)		((TSVector) PG_DETOAST_DATUM_COPY(X))
-#define TSVectorGetDatum(X)			PointerGetDatum(X)
+static inline TSVector
+DatumGetTSVector(Datum X)
+{
+	return (TSVector) PG_DETOAST_DATUM(X);
+}
+
+static inline TSVector
+DatumGetTSVectorCopy(Datum X)
+{
+	return (TSVector) PG_DETOAST_DATUM_COPY(X);
+}
+
+static inline Datum
+TSVectorGetDatum(const TSVectorData *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_TSVECTOR(n)		DatumGetTSVector(PG_GETARG_DATUM(n))
 #define PG_GETARG_TSVECTOR_COPY(n)	DatumGetTSVectorCopy(PG_GETARG_DATUM(n))
 #define PG_RETURN_TSVECTOR(x)		return TSVectorGetDatum(x)
@@ -227,14 +242,29 @@ typedef TSQueryData *TSQuery;
 #define GETOPERAND(x)	( (char*)GETQUERY(x) + ((TSQuery)(x))->size * sizeof(QueryItem) )
 
 /*
- * fmgr interface macros
+ * fmgr interface functions
  * Note, TSQuery type marked as plain storage, so it can't be toasted
  * but PG_DETOAST_DATUM_COPY is used for simplicity
  */
 
-#define DatumGetTSQuery(X)			((TSQuery) DatumGetPointer(X))
-#define DatumGetTSQueryCopy(X)		((TSQuery) PG_DETOAST_DATUM_COPY(X))
-#define TSQueryGetDatum(X)			PointerGetDatum(X)
+static inline TSQuery
+DatumGetTSQuery(Datum X)
+{
+	return (TSQuery) DatumGetPointer(X);
+}
+
+static inline TSQuery
+DatumGetTSQueryCopy(Datum X)
+{
+	return (TSQuery) PG_DETOAST_DATUM_COPY(X);
+}
+
+static inline Datum
+TSQueryGetDatum(const TSQueryData *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_TSQUERY(n)		DatumGetTSQuery(PG_GETARG_DATUM(n))
 #define PG_GETARG_TSQUERY_COPY(n)	DatumGetTSQueryCopy(PG_GETARG_DATUM(n))
 #define PG_RETURN_TSQUERY(x)		return TSQueryGetDatum(x)
diff --git a/src/include/tsearch/ts_utils.h b/src/include/tsearch/ts_utils.h
index c36c711dae..26cc415aa8 100644
--- a/src/include/tsearch/ts_utils.h
+++ b/src/include/tsearch/ts_utils.h
@@ -243,8 +243,18 @@ typedef uint64 TSQuerySign;
 
 #define TSQS_SIGLEN  (sizeof(TSQuerySign)*BITS_PER_BYTE)
 
-#define TSQuerySignGetDatum(X)		Int64GetDatum((int64) (X))
-#define DatumGetTSQuerySign(X)		((TSQuerySign) DatumGetInt64(X))
+static inline Datum
+TSQuerySignGetDatum(TSQuerySign X)
+{
+	return Int64GetDatum((int64) X);
+}
+
+static inline TSQuerySign
+DatumGetTSQuerySign(Datum X)
+{
+	return (TSQuerySign) DatumGetInt64(X);
+}
+
 #define PG_RETURN_TSQUERYSIGN(X)	return TSQuerySignGetDatum(X)
 #define PG_GETARG_TSQUERYSIGN(n)	DatumGetTSQuerySign(PG_GETARG_DATUM(n))
 
diff --git a/src/include/utils/cash.h b/src/include/utils/cash.h
index 2e332d83b1..55d45fadd4 100644
--- a/src/include/utils/cash.h
+++ b/src/include/utils/cash.h
@@ -17,8 +17,18 @@
 typedef int64 Cash;
 
 /* Cash is pass-by-reference if and only if int64 is */
-#define DatumGetCash(X)		((Cash) DatumGetInt64(X))
-#define CashGetDatum(X)		Int64GetDatum(X)
+static inline Cash
+DatumGetCash(Datum X)
+{
+	return DatumGetInt64(X);
+}
+
+static inline Datum
+CashGetDatum(Cash X)
+{
+	return Int64GetDatum(X);
+}
+
 #define PG_GETARG_CASH(n)	DatumGetCash(PG_GETARG_DATUM(n))
 #define PG_RETURN_CASH(x)	return CashGetDatum(x)
 
diff --git a/src/include/utils/date.h b/src/include/utils/date.h
index 3991da41f0..0bbe889128 100644
--- a/src/include/utils/date.h
+++ b/src/include/utils/date.h
@@ -45,18 +45,46 @@ typedef struct
 #define MAX_TIME_PRECISION 6
 
 /*
- * Macros for fmgr-callable functions.
+ * Functions for fmgr-callable functions.
  *
  * For TimeADT, we make use of the same support routines as for int64.
  * Therefore TimeADT is pass-by-reference if and only if int64 is!
  */
-#define DatumGetDateADT(X)	  ((DateADT) DatumGetInt32(X))
-#define DatumGetTimeADT(X)	  ((TimeADT) DatumGetInt64(X))
-#define DatumGetTimeTzADTP(X) ((TimeTzADT *) DatumGetPointer(X))
+static inline DateADT
+DatumGetDateADT(Datum X)
+{
+	return (DateADT) DatumGetInt32(X);
+}
+
+static inline TimeADT
+DatumGetTimeADT(Datum X)
+{
+	return (TimeADT) DatumGetInt64(X);
+}
+
+static inline TimeTzADT *
+DatumGetTimeTzADTP(Datum X)
+{
+	return (TimeTzADT *) DatumGetPointer(X);
+}
 
-#define DateADTGetDatum(X)	  Int32GetDatum(X)
-#define TimeADTGetDatum(X)	  Int64GetDatum(X)
-#define TimeTzADTPGetDatum(X) PointerGetDatum(X)
+static inline Datum
+DateADTGetDatum(DateADT X)
+{
+	return Int32GetDatum(X);
+}
+
+static inline Datum
+TimeADTGetDatum(TimeADT X)
+{
+	return Int64GetDatum(X);
+}
+
+static inline Datum
+TimeTzADTPGetDatum(const TimeTzADT *X)
+{
+	return PointerGetDatum(X);
+}
 
 #define PG_GETARG_DATEADT(n)	 DatumGetDateADT(PG_GETARG_DATUM(n))
 #define PG_GETARG_TIMEADT(n)	 DatumGetTimeADT(PG_GETARG_DATUM(n))
diff --git a/src/include/utils/expandeddatum.h b/src/include/utils/expandeddatum.h
index ffdb0c45bd..c4818eb054 100644
--- a/src/include/utils/expandeddatum.h
+++ b/src/include/utils/expandeddatum.h
@@ -133,8 +133,17 @@ struct ExpandedObjectHeader
  * (More of these might be worth inlining later.)
  */
 
-#define EOHPGetRWDatum(eohptr)	PointerGetDatum((eohptr)->eoh_rw_ptr)
-#define EOHPGetRODatum(eohptr)	PointerGetDatum((eohptr)->eoh_ro_ptr)
+static inline Datum
+EOHPGetRWDatum(const struct ExpandedObjectHeader *eohptr)
+{
+	return PointerGetDatum(eohptr->eoh_rw_ptr);
+}
+
+static inline Datum
+EOHPGetRODatum(const struct ExpandedObjectHeader *eohptr)
+{
+	return PointerGetDatum(eohptr->eoh_ro_ptr);
+}
 
 /* Does the Datum represent a writable expanded object? */
 #define DatumIsReadWriteExpandedObject(d, isnull, typlen) \
diff --git a/src/include/utils/expandedrecord.h b/src/include/utils/expandedrecord.h
index be60e2ce53..aaf5b6bfd1 100644
--- a/src/include/utils/expandedrecord.h
+++ b/src/include/utils/expandedrecord.h
@@ -138,10 +138,20 @@ typedef struct ExpandedRecordHeader
 	MemoryContextCallback er_mcb;
 } ExpandedRecordHeader;
 
-/* fmgr macros for expanded record objects */
+/* fmgr functions and macros for expanded record objects */
+static inline Datum
+ExpandedRecordGetDatum(const ExpandedRecordHeader *erh)
+{
+	return EOHPGetRWDatum(&erh->hdr);
+}
+
+static inline Datum
+ExpandedRecordGetRODatum(const ExpandedRecordHeader *erh)
+{
+	return EOHPGetRODatum(&erh->hdr);
+}
+
 #define PG_GETARG_EXPANDED_RECORD(n)  DatumGetExpandedRecord(PG_GETARG_DATUM(n))
-#define ExpandedRecordGetDatum(erh)   EOHPGetRWDatum(&(erh)->hdr)
-#define ExpandedRecordGetRODatum(erh) EOHPGetRODatum(&(erh)->hdr)
 #define PG_RETURN_EXPANDED_RECORD(x)  PG_RETURN_DATUM(ExpandedRecordGetDatum(x))
 
 /* assorted other macros */
diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h
index 719030777e..05726778ad 100644
--- a/src/include/utils/geo_decls.h
+++ b/src/include/utils/geo_decls.h
@@ -166,48 +166,112 @@ typedef struct
 } CIRCLE;
 
 /*
- * fmgr interface macros
+ * fmgr interface functions
  *
  * Path and Polygon are toastable varlena types, the others are just
  * fixed-size pass-by-reference types.
  */
 
-#define DatumGetPointP(X)	 ((Point *) DatumGetPointer(X))
-#define PointPGetDatum(X)	 PointerGetDatum(X)
+static inline Point *
+DatumGetPointP(Datum X)
+{
+	return (Point *) DatumGetPointer(X);
+}
+static inline Datum
+PointPGetDatum(const Point *X)
+{
+	return PointerGetDatum(X);
+}
 #define PG_GETARG_POINT_P(n) DatumGetPointP(PG_GETARG_DATUM(n))
 #define PG_RETURN_POINT_P(x) return PointPGetDatum(x)
 
-#define DatumGetLsegP(X)	((LSEG *) DatumGetPointer(X))
-#define LsegPGetDatum(X)	PointerGetDatum(X)
+static inline LSEG *
+DatumGetLsegP(Datum X)
+{
+	return (LSEG *) DatumGetPointer(X);
+}
+static inline Datum
+LsegPGetDatum(const LSEG *X)
+{
+	return PointerGetDatum(X);
+}
 #define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n))
 #define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x)
 
-#define DatumGetPathP(X)		 ((PATH *) PG_DETOAST_DATUM(X))
-#define DatumGetPathPCopy(X)	 ((PATH *) PG_DETOAST_DATUM_COPY(X))
-#define PathPGetDatum(X)		 PointerGetDatum(X)
+static inline PATH *
+DatumGetPathP(Datum X)
+{
+	return (PATH *) PG_DETOAST_DATUM(X);
+}
+static inline PATH *
+DatumGetPathPCopy(Datum X)
+{
+	return (PATH *) PG_DETOAST_DATUM_COPY(X);
+}
+static inline Datum
+PathPGetDatum(const PATH *X)
+{
+	return PointerGetDatum(X);
+}
 #define PG_GETARG_PATH_P(n)		 DatumGetPathP(PG_GETARG_DATUM(n))
 #define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n))
 #define PG_RETURN_PATH_P(x)		 return PathPGetDatum(x)
 
-#define DatumGetLineP(X)	((LINE *) DatumGetPointer(X))
-#define LinePGetDatum(X)	PointerGetDatum(X)
+static inline LINE *
+DatumGetLineP(Datum X)
+{
+	return (LINE *) DatumGetPointer(X);
+}
+static inline Datum
+LinePGetDatum(const LINE *X)
+{
+	return PointerGetDatum(X);
+}
 #define PG_GETARG_LINE_P(n) DatumGetLineP(PG_GETARG_DATUM(n))
 #define PG_RETURN_LINE_P(x) return LinePGetDatum(x)
 
-#define DatumGetBoxP(X)    ((BOX *) DatumGetPointer(X))
-#define BoxPGetDatum(X)    PointerGetDatum(X)
+static inline BOX *
+DatumGetBoxP(Datum X)
+{
+	return (BOX *) DatumGetPointer(X);
+}
+static inline Datum
+BoxPGetDatum(const BOX *X)
+{
+	return PointerGetDatum(X);
+}
 #define PG_GETARG_BOX_P(n) DatumGetBoxP(PG_GETARG_DATUM(n))
 #define PG_RETURN_BOX_P(x) return BoxPGetDatum(x)
 
-#define DatumGetPolygonP(X)			((POLYGON *) PG_DETOAST_DATUM(X))
-#define DatumGetPolygonPCopy(X)		((POLYGON *) PG_DETOAST_DATUM_COPY(X))
-#define PolygonPGetDatum(X)			PointerGetDatum(X)
+static inline POLYGON *
+DatumGetPolygonP(Datum X)
+{
+	return (POLYGON *) PG_DETOAST_DATUM(X);
+}
+static inline POLYGON *
+DatumGetPolygonPCopy(Datum X)
+{
+	return (POLYGON *) PG_DETOAST_DATUM_COPY(X);
+}
+static inline Datum
+PolygonPGetDatum(const POLYGON *X)
+{
+	return PointerGetDatum(X);
+}
 #define PG_GETARG_POLYGON_P(n)		DatumGetPolygonP(PG_GETARG_DATUM(n))
 #define PG_GETARG_POLYGON_P_COPY(n) DatumGetPolygonPCopy(PG_GETARG_DATUM(n))
 #define PG_RETURN_POLYGON_P(x)		return PolygonPGetDatum(x)
 
-#define DatumGetCircleP(X)	  ((CIRCLE *) DatumGetPointer(X))
-#define CirclePGetDatum(X)	  PointerGetDatum(X)
+static inline CIRCLE *
+DatumGetCircleP(Datum X)
+{
+	return (CIRCLE *) DatumGetPointer(X);
+}
+static inline Datum
+CirclePGetDatum(const CIRCLE *X)
+{
+	return PointerGetDatum(X);
+}
 #define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n))
 #define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x)
 
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
index b1ec9723df..5438cfaba5 100644
--- a/src/include/utils/inet.h
+++ b/src/include/utils/inet.h
@@ -119,23 +119,58 @@ typedef struct macaddr8
 /*
  * fmgr interface macros
  */
-#define DatumGetInetPP(X)	((inet *) PG_DETOAST_DATUM_PACKED(X))
-#define InetPGetDatum(X)	PointerGetDatum(X)
+static inline inet *
+DatumGetInetPP(Datum X)
+{
+	return (inet *) PG_DETOAST_DATUM_PACKED(X);
+}
+
+static inline Datum
+InetPGetDatum(const inet *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_INET_PP(n) DatumGetInetPP(PG_GETARG_DATUM(n))
 #define PG_RETURN_INET_P(x) return InetPGetDatum(x)
+
 /* obsolescent variants */
-#define DatumGetInetP(X)	((inet *) PG_DETOAST_DATUM(X))
+static inline inet *
+DatumGetInetP(Datum X)
+{
+	return (inet *) PG_DETOAST_DATUM(X);
+}
 #define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n))
 
 /* macaddr is a fixed-length pass-by-reference datatype */
-#define DatumGetMacaddrP(X)    ((macaddr *) DatumGetPointer(X))
-#define MacaddrPGetDatum(X)    PointerGetDatum(X)
+static inline macaddr *
+DatumGetMacaddrP(Datum X)
+{
+	return (macaddr *) DatumGetPointer(X);
+}
+
+static inline Datum
+MacaddrPGetDatum(const macaddr *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n))
 #define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x)
 
 /* macaddr8 is a fixed-length pass-by-reference datatype */
-#define DatumGetMacaddr8P(X)	((macaddr8 *) DatumGetPointer(X))
-#define Macaddr8PGetDatum(X)	PointerGetDatum(X)
+static inline macaddr8 *
+DatumGetMacaddr8P(Datum X)
+{
+	return (macaddr8 *) DatumGetPointer(X);
+}
+
+static inline Datum
+Macaddr8PGetDatum(const macaddr8 *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_MACADDR8_P(n) DatumGetMacaddr8P(PG_GETARG_DATUM(n))
 #define PG_RETURN_MACADDR8_P(x) return Macaddr8PGetDatum(x)
 
diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h
index bae466b523..536d00b3b4 100644
--- a/src/include/utils/jsonb.h
+++ b/src/include/utils/jsonb.h
@@ -67,14 +67,6 @@ typedef enum
 #define JGINFLAG_HASHED 0x10	/* OR'd into flag if value was hashed */
 #define JGIN_MAXLENGTH	125		/* max length of text part before hashing */
 
-/* Convenience macros */
-#define DatumGetJsonbP(d)	((Jsonb *) PG_DETOAST_DATUM(d))
-#define DatumGetJsonbPCopy(d)	((Jsonb *) PG_DETOAST_DATUM_COPY(d))
-#define JsonbPGetDatum(p)	PointerGetDatum(p)
-#define PG_GETARG_JSONB_P(x)	DatumGetJsonbP(PG_GETARG_DATUM(x))
-#define PG_GETARG_JSONB_P_COPY(x)	DatumGetJsonbPCopy(PG_GETARG_DATUM(x))
-#define PG_RETURN_JSONB_P(x)	PG_RETURN_POINTER(x)
-
 typedef struct JsonbPair JsonbPair;
 typedef struct JsonbValue JsonbValue;
 
@@ -393,6 +385,29 @@ typedef enum					/* type categories for datum_to_jsonb */
 	JSONBTYPE_OTHER				/* all else */
 } JsonbTypeCategory;
 
+/* Convenience macros */
+static inline Jsonb *
+DatumGetJsonbP(Datum d)
+{
+	return (Jsonb *) PG_DETOAST_DATUM(d);
+}
+
+static inline Jsonb *
+DatumGetJsonbPCopy(Datum d)
+{
+	return (Jsonb *) PG_DETOAST_DATUM_COPY(d);
+}
+
+static inline Datum
+JsonbPGetDatum(const Jsonb *p)
+{
+	return PointerGetDatum(p);
+}
+
+#define PG_GETARG_JSONB_P(x)	DatumGetJsonbP(PG_GETARG_DATUM(x))
+#define PG_GETARG_JSONB_P_COPY(x)	DatumGetJsonbPCopy(PG_GETARG_DATUM(x))
+#define PG_RETURN_JSONB_P(x)	PG_RETURN_POINTER(x)
+
 /* Support functions */
 extern uint32 getJsonbOffset(const JsonbContainer *jc, int index);
 extern uint32 getJsonbLength(const JsonbContainer *jc, int index);
diff --git a/src/include/utils/jsonpath.h b/src/include/utils/jsonpath.h
index 8e79b8dc9f..ea32a8f072 100644
--- a/src/include/utils/jsonpath.h
+++ b/src/include/utils/jsonpath.h
@@ -32,8 +32,18 @@ typedef struct
 #define JSONPATH_LAX		(0x80000000)
 #define JSONPATH_HDRSZ		(offsetof(JsonPath, data))
 
-#define DatumGetJsonPathP(d)			((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM(d)))
-#define DatumGetJsonPathPCopy(d)		((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM_COPY(d)))
+static inline JsonPath *
+DatumGetJsonPathP(Datum d)
+{
+	return (JsonPath *) PG_DETOAST_DATUM(d);
+}
+
+static inline JsonPath *
+DatumGetJsonPathPCopy(Datum d)
+{
+	return (JsonPath *) PG_DETOAST_DATUM_COPY(d);
+}
+
 #define PG_GETARG_JSONPATH_P(x)			DatumGetJsonPathP(PG_GETARG_DATUM(x))
 #define PG_GETARG_JSONPATH_P_COPY(x)	DatumGetJsonPathPCopy(PG_GETARG_DATUM(x))
 #define PG_RETURN_JSONPATH_P(p)			PG_RETURN_POINTER(p)
diff --git a/src/include/utils/multirangetypes.h b/src/include/utils/multirangetypes.h
index 915330f990..23bce0005f 100644
--- a/src/include/utils/multirangetypes.h
+++ b/src/include/utils/multirangetypes.h
@@ -42,11 +42,26 @@ typedef struct
 #define MultirangeIsEmpty(mr)  ((mr)->rangeCount == 0)
 
 /*
- * fmgr macros for multirange type objects
+ * fmgr functions for multirange type objects
  */
-#define DatumGetMultirangeTypeP(X)		((MultirangeType *) PG_DETOAST_DATUM(X))
-#define DatumGetMultirangeTypePCopy(X)	((MultirangeType *) PG_DETOAST_DATUM_COPY(X))
-#define MultirangeTypePGetDatum(X)		PointerGetDatum(X)
+static inline MultirangeType *
+DatumGetMultirangeTypeP(Datum X)
+{
+	return (MultirangeType *) PG_DETOAST_DATUM(X);
+}
+
+static inline MultirangeType *
+DatumGetMultirangeTypePCopy(Datum X)
+{
+	return (MultirangeType *) PG_DETOAST_DATUM_COPY(X);
+}
+
+static inline Datum
+MultirangeTypePGetDatum(const MultirangeType *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_MULTIRANGE_P(n)		DatumGetMultirangeTypeP(PG_GETARG_DATUM(n))
 #define PG_GETARG_MULTIRANGE_P_COPY(n)	DatumGetMultirangeTypePCopy(PG_GETARG_DATUM(n))
 #define PG_RETURN_MULTIRANGE_P(x)		return MultirangeTypePGetDatum(x)
diff --git a/src/include/utils/numeric.h b/src/include/utils/numeric.h
index 3caa74dfe7..88c62c5348 100644
--- a/src/include/utils/numeric.h
+++ b/src/include/utils/numeric.h
@@ -56,9 +56,24 @@ typedef struct NumericData *Numeric;
  * fmgr interface macros
  */
 
-#define DatumGetNumeric(X)		  ((Numeric) PG_DETOAST_DATUM(X))
-#define DatumGetNumericCopy(X)	  ((Numeric) PG_DETOAST_DATUM_COPY(X))
-#define NumericGetDatum(X)		  PointerGetDatum(X)
+static inline Numeric
+DatumGetNumeric(Datum X)
+{
+	return (Numeric) PG_DETOAST_DATUM(X);
+}
+
+static inline Numeric
+DatumGetNumericCopy(Datum X)
+{
+	return (Numeric) PG_DETOAST_DATUM_COPY(X);
+}
+
+static inline Datum
+NumericGetDatum(Numeric X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_NUMERIC(n)	  DatumGetNumeric(PG_GETARG_DATUM(n))
 #define PG_GETARG_NUMERIC_COPY(n) DatumGetNumericCopy(PG_GETARG_DATUM(n))
 #define PG_RETURN_NUMERIC(x)	  return NumericGetDatum(x)
diff --git a/src/include/utils/pg_lsn.h b/src/include/utils/pg_lsn.h
index 7b708f1073..5313afbfe2 100644
--- a/src/include/utils/pg_lsn.h
+++ b/src/include/utils/pg_lsn.h
@@ -18,8 +18,17 @@
 #include "access/xlogdefs.h"
 #include "fmgr.h"
 
-#define DatumGetLSN(X) ((XLogRecPtr) DatumGetInt64(X))
-#define LSNGetDatum(X) (Int64GetDatum((int64) (X)))
+static inline XLogRecPtr
+DatumGetLSN(Datum X)
+{
+	return (XLogRecPtr) DatumGetInt64(X);
+}
+
+static inline Datum
+LSNGetDatum(XLogRecPtr X)
+{
+	return Int64GetDatum((int64) X);
+}
 
 #define PG_GETARG_LSN(n)	 DatumGetLSN(PG_GETARG_DATUM(n))
 #define PG_RETURN_LSN(x)	 return LSNGetDatum(x)
diff --git a/src/include/utils/rangetypes.h b/src/include/utils/rangetypes.h
index 993fad4fc2..661e4892ec 100644
--- a/src/include/utils/rangetypes.h
+++ b/src/include/utils/rangetypes.h
@@ -68,11 +68,26 @@ typedef struct
 } RangeBound;
 
 /*
- * fmgr macros for range type objects
+ * fmgr functions for range type objects
  */
-#define DatumGetRangeTypeP(X)		((RangeType *) PG_DETOAST_DATUM(X))
-#define DatumGetRangeTypePCopy(X)	((RangeType *) PG_DETOAST_DATUM_COPY(X))
-#define RangeTypePGetDatum(X)		PointerGetDatum(X)
+static inline RangeType *
+DatumGetRangeTypeP(Datum X)
+{
+	return (RangeType *) PG_DETOAST_DATUM(X);
+}
+
+static inline RangeType *
+DatumGetRangeTypePCopy(Datum X)
+{
+	return (RangeType *) PG_DETOAST_DATUM_COPY(X);
+}
+
+static inline Datum
+RangeTypePGetDatum(const RangeType *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_RANGE_P(n)		DatumGetRangeTypeP(PG_GETARG_DATUM(n))
 #define PG_GETARG_RANGE_P_COPY(n)	DatumGetRangeTypePCopy(PG_GETARG_DATUM(n))
 #define PG_RETURN_RANGE_P(x)		return RangeTypePGetDatum(x)
diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h
index edf3a97318..3602638bdc 100644
--- a/src/include/utils/timestamp.h
+++ b/src/include/utils/timestamp.h
@@ -19,18 +19,46 @@
 
 
 /*
- * Macros for fmgr-callable functions.
+ * Functions for fmgr-callable functions.
  *
  * For Timestamp, we make use of the same support routines as for int64.
  * Therefore Timestamp is pass-by-reference if and only if int64 is!
  */
-#define DatumGetTimestamp(X)  ((Timestamp) DatumGetInt64(X))
-#define DatumGetTimestampTz(X)	((TimestampTz) DatumGetInt64(X))
-#define DatumGetIntervalP(X)  ((Interval *) DatumGetPointer(X))
-
-#define TimestampGetDatum(X) Int64GetDatum(X)
-#define TimestampTzGetDatum(X) Int64GetDatum(X)
-#define IntervalPGetDatum(X) PointerGetDatum(X)
+static inline Timestamp
+DatumGetTimestamp(Datum X)
+{
+	return (Timestamp) DatumGetInt64(X);
+}
+
+static inline TimestampTz
+DatumGetTimestampTz(Datum X)
+{
+	return (TimestampTz) DatumGetInt64(X);
+}
+
+static inline Interval *
+DatumGetIntervalP(Datum X)
+{
+	return (Interval *) DatumGetPointer(X);
+}
+
+static inline Datum
+TimestampGetDatum(Timestamp X)
+{
+	return Int64GetDatum(X);
+}
+
+static inline Datum
+TimestampTzGetDatum(TimestampTz X)
+{
+	return Int64GetDatum(X);
+}
+
+static inline Datum
+IntervalPGetDatum(const Interval *X)
+{
+	return PointerGetDatum(X);
+}
 
 #define PG_GETARG_TIMESTAMP(n) DatumGetTimestamp(PG_GETARG_DATUM(n))
 #define PG_GETARG_TIMESTAMPTZ(n) DatumGetTimestampTz(PG_GETARG_DATUM(n))
diff --git a/src/include/utils/uuid.h b/src/include/utils/uuid.h
index 0029da4e7f..69f4332d0f 100644
--- a/src/include/utils/uuid.h
+++ b/src/include/utils/uuid.h
@@ -23,9 +23,20 @@ typedef struct pg_uuid_t
 } pg_uuid_t;
 
 /* fmgr interface macros */
-#define UUIDPGetDatum(X)		PointerGetDatum(X)
+static inline Datum
+UUIDPGetDatum(const pg_uuid_t *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_RETURN_UUID_P(X)		return UUIDPGetDatum(X)
-#define DatumGetUUIDP(X)		((pg_uuid_t *) DatumGetPointer(X))
+
+static inline pg_uuid_t *
+DatumGetUUIDP(Datum X)
+{
+	return (pg_uuid_t *) DatumGetPointer(X);
+}
+
 #define PG_GETARG_UUID_P(X)		DatumGetUUIDP(PG_GETARG_DATUM(X))
 
 #endif							/* UUID_H */
diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h
index 039ba860cf..e65e7f65e7 100644
--- a/src/include/utils/varbit.h
+++ b/src/include/utils/varbit.h
@@ -41,9 +41,24 @@ typedef struct
  * BIT and BIT VARYING are toastable varlena types.  They are the same
  * as far as representation goes, so we just have one set of macros.
  */
-#define DatumGetVarBitP(X)		   ((VarBit *) PG_DETOAST_DATUM(X))
-#define DatumGetVarBitPCopy(X)	   ((VarBit *) PG_DETOAST_DATUM_COPY(X))
-#define VarBitPGetDatum(X)		   PointerGetDatum(X)
+static inline VarBit *
+DatumGetVarBitP(Datum X)
+{
+	return (VarBit *) PG_DETOAST_DATUM(X);
+}
+
+static inline VarBit *
+DatumGetVarBitPCopy(Datum X)
+{
+	return (VarBit *) PG_DETOAST_DATUM_COPY(X);
+}
+
+static inline Datum
+VarBitPGetDatum(const VarBit *X)
+{
+	return PointerGetDatum(X);
+}
+
 #define PG_GETARG_VARBIT_P(n)	   DatumGetVarBitP(PG_GETARG_DATUM(n))
 #define PG_GETARG_VARBIT_P_COPY(n) DatumGetVarBitPCopy(PG_GETARG_DATUM(n))
 #define PG_RETURN_VARBIT_P(x)	   return VarBitPGetDatum(x)
diff --git a/src/include/utils/xid8.h b/src/include/utils/xid8.h
index b702fc1a91..9c5ce241db 100644
--- a/src/include/utils/xid8.h
+++ b/src/include/utils/xid8.h
@@ -14,8 +14,18 @@
 
 #include "access/transam.h"
 
-#define DatumGetFullTransactionId(X) (FullTransactionIdFromU64(DatumGetUInt64(X)))
-#define FullTransactionIdGetDatum(X) (UInt64GetDatum(U64FromFullTransactionId(X)))
+static inline FullTransactionId
+DatumGetFullTransactionId(Datum X)
+{
+	return FullTransactionIdFromU64(DatumGetUInt64(X));
+}
+
+static inline Datum
+FullTransactionIdGetDatum(FullTransactionId X)
+{
+	return UInt64GetDatum(U64FromFullTransactionId(X));
+}
+
 #define PG_GETARG_FULLTRANSACTIONID(X) DatumGetFullTransactionId(PG_GETARG_DATUM(X))
 #define PG_RETURN_FULLTRANSACTIONID(X) return FullTransactionIdGetDatum(X)
 
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 6620a62619..c71174d204 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -47,8 +47,17 @@ typedef enum
 /* struct PgXmlErrorContext is private to xml.c */
 typedef struct PgXmlErrorContext PgXmlErrorContext;
 
-#define DatumGetXmlP(X)		((xmltype *) PG_DETOAST_DATUM(X))
-#define XmlPGetDatum(X)		PointerGetDatum(X)
+static inline xmltype *
+DatumGetXmlP(Datum X)
+{
+	return (xmltype *) PG_DETOAST_DATUM(X);
+}
+
+static inline Datum
+XmlPGetDatum(const xmltype *X)
+{
+	return PointerGetDatum(X);
+}
 
 #define PG_GETARG_XML_P(n)	DatumGetXmlP(PG_GETARG_DATUM(n))
 #define PG_RETURN_XML_P(x)	PG_RETURN_POINTER(x)
-- 
2.37.2

