0001-Deduplicate-nbtcompare-s-scan-key-support-functions.patch.txt

text/plain

Filename: 0001-Deduplicate-nbtcompare-s-scan-key-support-functions.patch.txt
Type: text/plain
Part: 0
Message: Re: Adding skip scan (including MDAM style range skip scan) to nbtree
From 37e59d701698e985007236a374448a6cfcb02f18 Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
Date: Sun, 20 Oct 2024 15:34:59 +0200
Subject: [PATCH] Deduplicate nbtcompare's scan key support functions

This saves some 150 lines of duplicated trivial functions.
---
 src/backend/access/nbtree/nbtcompare.c | 357 ++++++-------------------
 src/include/c.h                        |   1 +
 2 files changed, 86 insertions(+), 272 deletions(-)

diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c
index 26ebbf776a..e6af77aae1 100644
--- a/src/backend/access/nbtree/nbtcompare.c
+++ b/src/backend/access/nbtree/nbtcompare.c
@@ -69,6 +69,91 @@
 #define A_GREATER_THAN_B	1
 #endif
 
+/*
+ * Macros to implement skip support generically across types
+ *
+ * This reduces code duplication for the 6 types we define compare operators
+ * for in this file: bool, int2, int4, int8, oid, and "char".
+ */
+
+#define decrement_fnname(typname) CppConcat(typname, _decrement)
+#define increment_fnname(typname) CppConcat(typname, _increment)
+#define sksup_fnname(typname) CppConcat3(bt, typname, skipsupport)
+
+#define discrete_type_decrement_impl(typ, typname, datname, minvalue) \
+static Datum \
+decrement_fnname(typname)(Relation rel, Datum existing, bool *underflow) \
+{ \
+	typ		t_existing = CppConcat(DatumGet, datname)(existing); \
+\
+	if (t_existing == minvalue) \
+	{ \
+		/* return value is undefined */ \
+		*underflow = true; \
+		return (Datum) 0; \
+	} \
+	\
+	*underflow = false; \
+	return CppConcat(datname, GetDatum)(t_existing - 1); \
+}
+
+#define discrete_type_increment_impl(typ, typname, datname, maxvalue) \
+static Datum \
+increment_fnname(typname)(Relation rel, Datum existing, bool *overflow) \
+{ \
+	typ		t_existing = CppConcat(DatumGet, datname)(existing); \
+\
+	if (t_existing == maxvalue) \
+	{ \
+		/* return value is undefined */ \
+		*overflow = true; \
+		return (Datum) 0; \
+	} \
+	\
+	*overflow = false; \
+	return CppConcat(datname, GetDatum)(t_existing + 1); \
+}
+
+#define discrete_type_skipsupport(typ, typname, datname, minvalue, maxvalue) \
+Datum \
+sksup_fnname(typname)(PG_FUNCTION_ARGS) \
+{ \
+	SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0); \
+\
+	sksup->decrement = decrement_fnname(typname); \
+	sksup->increment = increment_fnname(typname); \
+	sksup->low_elem = CppConcat(datname, GetDatum)(minvalue); \
+	sksup->high_elem = CppConcat(datname, GetDatum)(maxvalue); \
+\
+	PG_RETURN_VOID(); \
+}
+
+/* Actually generate the functions */
+#define impl_discrete_type_sksup(typ, typname, datumname, minvalue, maxvalue) \
+	discrete_type_decrement_impl(typ, typname, datumname, minvalue) \
+	discrete_type_increment_impl(typ, typname, datumname, minvalue) \
+	discrete_type_skipsupport(typ, typname, datumname, minvalue, maxvalue)
+
+/* Implement for various types */
+impl_discrete_type_sksup(int16, int2, Int16, PG_INT16_MIN, PG_INT16_MAX)
+impl_discrete_type_sksup(int32, int4, Int32, PG_INT32_MIN, PG_INT32_MAX)
+impl_discrete_type_sksup(int64, int8, Int64, PG_INT64_MIN, PG_INT64_MAX)
+impl_discrete_type_sksup(Oid, oid, ObjectId, InvalidOid, OID_MAX)
+impl_discrete_type_sksup(uint8, char, UInt8, 0, PG_UINT8_MAX)
+
+/*
+ * If bool is a #define (e.g. on _Bool), the macro substitution will fail,
+ * so we substitute the #define with a true typedef here, so that macro
+ * expansion will use bool instead of e.g. _Bool in the function names.
+ */
+#ifdef bool
+typedef bool substitute_bool;
+#undef bool
+typedef substitute_bool bool;
+#endif
+
+impl_discrete_type_sksup(bool, bool, Bool, false, true)
+
 
 Datum
 btboolcmp(PG_FUNCTION_ARGS)
@@ -79,51 +164,6 @@ btboolcmp(PG_FUNCTION_ARGS)
 	PG_RETURN_INT32((int32) a - (int32) b);
 }
 
-static Datum
-bool_decrement(Relation rel, Datum existing, bool *underflow)
-{
-	bool		bexisting = DatumGetBool(existing);
-
-	if (bexisting == false)
-	{
-		/* return value is undefined */
-		*underflow = true;
-		return (Datum) 0;
-	}
-
-	*underflow = false;
-	return BoolGetDatum(bexisting - 1);
-}
-
-static Datum
-bool_increment(Relation rel, Datum existing, bool *overflow)
-{
-	bool		bexisting = DatumGetBool(existing);
-
-	if (bexisting == true)
-	{
-		/* return value is undefined */
-		*overflow = true;
-		return (Datum) 0;
-	}
-
-	*overflow = false;
-	return BoolGetDatum(bexisting + 1);
-}
-
-Datum
-btboolskipsupport(PG_FUNCTION_ARGS)
-{
-	SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
-
-	sksup->decrement = bool_decrement;
-	sksup->increment = bool_increment;
-	sksup->low_elem = BoolGetDatum(false);
-	sksup->high_elem = BoolGetDatum(true);
-
-	PG_RETURN_VOID();
-}
-
 Datum
 btint2cmp(PG_FUNCTION_ARGS)
 {
@@ -151,51 +191,6 @@ btint2sortsupport(PG_FUNCTION_ARGS)
 	PG_RETURN_VOID();
 }
 
-static Datum
-int2_decrement(Relation rel, Datum existing, bool *underflow)
-{
-	int16		iexisting = DatumGetInt16(existing);
-
-	if (iexisting == PG_INT16_MIN)
-	{
-		/* return value is undefined */
-		*underflow = true;
-		return (Datum) 0;
-	}
-
-	*underflow = false;
-	return Int16GetDatum(iexisting - 1);
-}
-
-static Datum
-int2_increment(Relation rel, Datum existing, bool *overflow)
-{
-	int16		iexisting = DatumGetInt16(existing);
-
-	if (iexisting == PG_INT16_MAX)
-	{
-		/* return value is undefined */
-		*overflow = true;
-		return (Datum) 0;
-	}
-
-	*overflow = false;
-	return Int16GetDatum(iexisting + 1);
-}
-
-Datum
-btint2skipsupport(PG_FUNCTION_ARGS)
-{
-	SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
-
-	sksup->decrement = int2_decrement;
-	sksup->increment = int2_increment;
-	sksup->low_elem = Int16GetDatum(PG_INT16_MIN);
-	sksup->high_elem = Int16GetDatum(PG_INT16_MAX);
-
-	PG_RETURN_VOID();
-}
-
 Datum
 btint4cmp(PG_FUNCTION_ARGS)
 {
@@ -219,51 +214,6 @@ btint4sortsupport(PG_FUNCTION_ARGS)
 	PG_RETURN_VOID();
 }
 
-static Datum
-int4_decrement(Relation rel, Datum existing, bool *underflow)
-{
-	int32		iexisting = DatumGetInt32(existing);
-
-	if (iexisting == PG_INT32_MIN)
-	{
-		/* return value is undefined */
-		*underflow = true;
-		return (Datum) 0;
-	}
-
-	*underflow = false;
-	return Int32GetDatum(iexisting - 1);
-}
-
-static Datum
-int4_increment(Relation rel, Datum existing, bool *overflow)
-{
-	int32		iexisting = DatumGetInt32(existing);
-
-	if (iexisting == PG_INT32_MAX)
-	{
-		/* return value is undefined */
-		*overflow = true;
-		return (Datum) 0;
-	}
-
-	*overflow = false;
-	return Int32GetDatum(iexisting + 1);
-}
-
-Datum
-btint4skipsupport(PG_FUNCTION_ARGS)
-{
-	SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
-
-	sksup->decrement = int4_decrement;
-	sksup->increment = int4_increment;
-	sksup->low_elem = Int32GetDatum(PG_INT32_MIN);
-	sksup->high_elem = Int32GetDatum(PG_INT32_MAX);
-
-	PG_RETURN_VOID();
-}
-
 Datum
 btint8cmp(PG_FUNCTION_ARGS)
 {
@@ -307,51 +257,6 @@ btint8sortsupport(PG_FUNCTION_ARGS)
 	PG_RETURN_VOID();
 }
 
-static Datum
-int8_decrement(Relation rel, Datum existing, bool *underflow)
-{
-	int64		iexisting = DatumGetInt64(existing);
-
-	if (iexisting == PG_INT64_MIN)
-	{
-		/* return value is undefined */
-		*underflow = true;
-		return (Datum) 0;
-	}
-
-	*underflow = false;
-	return Int64GetDatum(iexisting - 1);
-}
-
-static Datum
-int8_increment(Relation rel, Datum existing, bool *overflow)
-{
-	int64		iexisting = DatumGetInt64(existing);
-
-	if (iexisting == PG_INT64_MAX)
-	{
-		/* return value is undefined */
-		*overflow = true;
-		return (Datum) 0;
-	}
-
-	*overflow = false;
-	return Int64GetDatum(iexisting + 1);
-}
-
-Datum
-btint8skipsupport(PG_FUNCTION_ARGS)
-{
-	SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
-
-	sksup->decrement = int8_decrement;
-	sksup->increment = int8_increment;
-	sksup->low_elem = Int64GetDatum(PG_INT64_MIN);
-	sksup->high_elem = Int64GetDatum(PG_INT64_MAX);
-
-	PG_RETURN_VOID();
-}
-
 Datum
 btint48cmp(PG_FUNCTION_ARGS)
 {
@@ -473,51 +378,6 @@ btoidsortsupport(PG_FUNCTION_ARGS)
 	PG_RETURN_VOID();
 }
 
-static Datum
-oid_decrement(Relation rel, Datum existing, bool *underflow)
-{
-	Oid			oexisting = DatumGetObjectId(existing);
-
-	if (oexisting == InvalidOid)
-	{
-		/* return value is undefined */
-		*underflow = true;
-		return (Datum) 0;
-	}
-
-	*underflow = false;
-	return ObjectIdGetDatum(oexisting - 1);
-}
-
-static Datum
-oid_increment(Relation rel, Datum existing, bool *overflow)
-{
-	Oid			oexisting = DatumGetObjectId(existing);
-
-	if (oexisting == OID_MAX)
-	{
-		/* return value is undefined */
-		*overflow = true;
-		return (Datum) 0;
-	}
-
-	*overflow = false;
-	return ObjectIdGetDatum(oexisting + 1);
-}
-
-Datum
-btoidskipsupport(PG_FUNCTION_ARGS)
-{
-	SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
-
-	sksup->decrement = oid_decrement;
-	sksup->increment = oid_increment;
-	sksup->low_elem = ObjectIdGetDatum(InvalidOid);
-	sksup->high_elem = ObjectIdGetDatum(OID_MAX);
-
-	PG_RETURN_VOID();
-}
-
 Datum
 btoidvectorcmp(PG_FUNCTION_ARGS)
 {
@@ -551,50 +411,3 @@ btcharcmp(PG_FUNCTION_ARGS)
 	/* Be careful to compare chars as unsigned */
 	PG_RETURN_INT32((int32) ((uint8) a) - (int32) ((uint8) b));
 }
-
-static Datum
-char_decrement(Relation rel, Datum existing, bool *underflow)
-{
-	uint8		cexisting = UInt8GetDatum(existing);
-
-	if (cexisting == 0)
-	{
-		/* return value is undefined */
-		*underflow = true;
-		return (Datum) 0;
-	}
-
-	*underflow = false;
-	return CharGetDatum((uint8) cexisting - 1);
-}
-
-static Datum
-char_increment(Relation rel, Datum existing, bool *overflow)
-{
-	uint8		cexisting = UInt8GetDatum(existing);
-
-	if (cexisting == UCHAR_MAX)
-	{
-		/* return value is undefined */
-		*overflow = true;
-		return (Datum) 0;
-	}
-
-	*overflow = false;
-	return CharGetDatum((uint8) cexisting + 1);
-}
-
-Datum
-btcharskipsupport(PG_FUNCTION_ARGS)
-{
-	SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
-
-	sksup->decrement = char_decrement;
-	sksup->increment = char_increment;
-
-	/* btcharcmp compares chars as unsigned */
-	sksup->low_elem = UInt8GetDatum(0);
-	sksup->high_elem = UInt8GetDatum(UCHAR_MAX);
-
-	PG_RETURN_VOID();
-}
diff --git a/src/include/c.h b/src/include/c.h
index 55dec71a6d..cbf6499151 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -329,6 +329,7 @@
 #define CppAsString(identifier) #identifier
 #define CppAsString2(x)			CppAsString(x)
 #define CppConcat(x, y)			x##y
+#define CppConcat3(x, y, z)		x##y##z
 
 /*
  * VA_ARGS_NARGS
-- 
2.46.0