From 13bcebe36548b9cb96eaf3b6e24f6049c14757ac Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
Date: Thu, 8 Feb 2024 17:37:39 +0100
Subject: [PATCH v3 4/7] gen_node_support.pl: Add a TypMod type for signalling
 TypMod behaviour

Like Location, TypMod has its own default (-1). By using a type, we can
omit adding pg_node_attribute(default(-1)) markers to every typmod-valued
field, whilst still getting the benefits of a smaller size in serialization.
---
 src/backend/nodes/gen_node_support.pl |  8 ++++++-
 src/backend/nodes/outfuncs.c          |  2 +-
 src/backend/nodes/readfuncs.c         |  2 +-
 src/include/nodes/parsenodes.h        |  4 ++--
 src/include/nodes/pathnodes.h         |  2 +-
 src/include/nodes/primnodes.h         | 33 ++++++++++++++-------------
 6 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index ec850c3484..fda8c3a494 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -135,7 +135,8 @@ my @nodetag_only;
 # types that are copied by straight assignment
 my @scalar_types = qw(
   bits32 bool char double int int8 int16 int32 int64 long uint8 uint16 uint32 uint64
-  AclMode AttrNumber Cardinality Cost Index Oid RelFileNumber Selectivity Size StrategyNumber SubTransactionId TimeLineID XLogRecPtr
+  AclMode AttrNumber Cardinality Cost Index Oid RelFileNumber Selectivity Size StrategyNumber 
+  SubTransactionId TimeLineID XLogRecPtr TypMod
 );
 
 # collect enum types
@@ -1015,6 +1016,11 @@ _read${n}(void)
 			print $off "\tWRITE_LOCATION_FIELD($f);\n";
 			print $rff "\tREAD_LOCATION_FIELD($f);\n" unless $no_read;
 		}
+		elsif ($t eq 'TypMod')
+		{
+			print $off "\tWRITE_INT_FIELD_DEFAULT($f, -1);\n";
+			print $rff "\tREAD_INT_FIELD_DEFAULT($f, -1);\n" unless $no_read;
+		}
 		elsif ($t eq 'int'
 			|| $t eq 'int16'
 			|| $t eq 'int32'
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index eca3160104..3973c0e489 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -492,7 +492,7 @@ _outConst(StringInfo str, const Const *node, bool omitLocation)
 	WRITE_NODE_TYPE("CONST");
 
 	WRITE_OID_FIELD(consttype);
-	WRITE_INT_FIELD(consttypmod);
+	WRITE_INT_FIELD_DEFAULT(consttypmod, -1);
 	WRITE_OID_FIELD(constcollid);
 	WRITE_INT_FIELD(constlen);
 	WRITE_BOOL_FIELD(constbyval);
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 47f4ba2695..44ab140799 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -356,7 +356,7 @@ _readConst(void)
 	READ_LOCALS(Const);
 
 	READ_OID_FIELD(consttype);
-	READ_INT_FIELD(consttypmod);
+	READ_INT_FIELD_DEFAULT(consttypmod, -1);
 	READ_OID_FIELD(constcollid);
 	READ_INT_FIELD(constlen);
 	READ_BOOL_FIELD(constbyval);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index dd8aa30aaf..52d8504a9d 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -260,7 +260,7 @@ typedef struct TypeName
 	bool		setof;			/* is a set? */
 	bool		pct_type;		/* %TYPE specified? */
 	List	   *typmods;		/* type modifier expression(s) */
-	int32		typemod;		/* prespecified type modifier */
+	TypMod		typemod;		/* prespecified type modifier */
 	List	   *arrayBounds;	/* array bounds */
 	Location	location;		/* token location, or -1 if unknown */
 } TypeName;
@@ -1608,7 +1608,7 @@ typedef struct CTECycleClause
 	Location	location;
 	/* These fields are set during parse analysis: */
 	Oid			cycle_mark_type;	/* common type of _value and _default */
-	int			cycle_mark_typmod;
+	TypMod		cycle_mark_typmod;
 	Oid			cycle_mark_collation;
 	Oid			cycle_mark_neop;	/* <> operator for type */
 } CTECycleClause;
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 534692bee1..f7c2496a7f 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -3394,7 +3394,7 @@ typedef struct AggTransInfo
 	Oid			aggtranstype;
 
 	/* Additional data about transtype */
-	int32		aggtranstypmod;
+	TypMod		aggtranstypmod;
 	int			transtypeLen;
 	bool		transtypeByVal;
 
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 557be05657..94282497d7 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -29,8 +29,9 @@ typedef enum OverridingKind
 	OVERRIDING_SYSTEM_VALUE,
 } OverridingKind;
 
-
+/* Type aliases for gen_node_support */
 #define Location int
+#define TypMod int32
 
 /* ----------------------------------------------------------------
  *						node definitions
@@ -250,7 +251,7 @@ typedef struct Var
 	/* pg_type OID for the type of this var */
 	Oid			vartype pg_node_attr(query_jumble_ignore);
 	/* pg_attribute typmod value */
-	int32		vartypmod pg_node_attr(query_jumble_ignore);
+	TypMod		vartypmod pg_node_attr(query_jumble_ignore);
 	/* OID of collation, or InvalidOid if none */
 	Oid			varcollid pg_node_attr(query_jumble_ignore);
 
@@ -299,7 +300,7 @@ typedef struct Const
 	/* pg_type OID of the constant's datatype */
 	Oid			consttype;
 	/* typmod value, if any */
-	int32		consttypmod pg_node_attr(query_jumble_ignore);
+	TypMod		consttypmod pg_node_attr(query_jumble_ignore);
 	/* OID of collation, or InvalidOid if none */
 	Oid			constcollid pg_node_attr(query_jumble_ignore);
 	/* typlen of the constant's datatype */
@@ -365,7 +366,7 @@ typedef struct Param
 	int			paramid;		/* numeric ID for parameter */
 	Oid			paramtype;		/* pg_type OID of parameter's datatype */
 	/* typmod value, if known */
-	int32		paramtypmod pg_node_attr(query_jumble_ignore);
+	TypMod		paramtypmod pg_node_attr(query_jumble_ignore);
 	/* OID of collation, or InvalidOid if none */
 	Oid			paramcollid pg_node_attr(query_jumble_ignore);
 	/* token location, or -1 if unknown */
@@ -623,7 +624,7 @@ typedef struct SubscriptingRef
 	/* type of the SubscriptingRef's result */
 	Oid			refrestype pg_node_attr(query_jumble_ignore);
 	/* typmod of the result */
-	int32		reftypmod pg_node_attr(query_jumble_ignore);
+	TypMod		reftypmod pg_node_attr(query_jumble_ignore);
 	/* collation of result, or InvalidOid if none */
 	Oid			refcollid pg_node_attr(query_jumble_ignore);
 	/* expressions that evaluate to upper container indexes */
@@ -1009,7 +1010,7 @@ typedef struct SubPlan
 	char	   *plan_name;		/* A name assigned during planning */
 	/* Extra data useful for determining subplan's output type: */
 	Oid			firstColType;	/* Type of first column of subplan result */
-	int32		firstColTypmod; /* Typmod of first column of subplan result */
+	TypMod		firstColTypmod; /* Typmod of first column of subplan result */
 	Oid			firstColCollation;	/* Collation of first column of subplan
 									 * result */
 	/* Information about execution strategy: */
@@ -1067,7 +1068,7 @@ typedef struct FieldSelect
 	/* type of the field (result type of this node) */
 	Oid			resulttype pg_node_attr(query_jumble_ignore);
 	/* output typmod (usually -1) */
-	int32		resulttypmod pg_node_attr(query_jumble_ignore);
+	TypMod		resulttypmod pg_node_attr(query_jumble_ignore);
 	/* OID of collation of the field */
 	Oid			resultcollid pg_node_attr(query_jumble_ignore);
 } FieldSelect;
@@ -1121,7 +1122,7 @@ typedef struct RelabelType
 	Expr	   *arg;			/* input expression */
 	Oid			resulttype;		/* output type of coercion expression */
 	/* output typmod (usually -1) */
-	int32		resulttypmod pg_node_attr(query_jumble_ignore);
+	TypMod		resulttypmod pg_node_attr(query_jumble_ignore);
 	/* OID of collation, or InvalidOid if none */
 	Oid			resultcollid pg_node_attr(query_jumble_ignore);
 	/* how to display this node */
@@ -1171,7 +1172,7 @@ typedef struct ArrayCoerceExpr
 	Expr	   *elemexpr;		/* expression representing per-element work */
 	Oid			resulttype;		/* output type of coercion (an array type) */
 	/* output typmod (also element typmod) */
-	int32		resulttypmod pg_node_attr(query_jumble_ignore);
+	TypMod		resulttypmod pg_node_attr(query_jumble_ignore);
 	/* OID of collation, or InvalidOid if none */
 	Oid			resultcollid pg_node_attr(query_jumble_ignore);
 	/* how to display this node */
@@ -1291,7 +1292,7 @@ typedef struct CaseTestExpr
 	Expr		xpr;
 	Oid			typeId;			/* type for substituted value */
 	/* typemod for substituted value */
-	int32		typeMod pg_node_attr(query_jumble_ignore);
+	TypMod		typeMod pg_node_attr(query_jumble_ignore);
 	/* collation for the substituted value */
 	Oid			collation pg_node_attr(query_jumble_ignore);
 } CaseTestExpr;
@@ -1497,7 +1498,7 @@ typedef struct SQLValueFunction
 	 * include this Oid in the query jumbling.
 	 */
 	Oid			type pg_node_attr(query_jumble_ignore);
-	int32		typmod;
+	TypMod		typmod;
 	Location	location;		/* token location, or -1 if unknown */
 } SQLValueFunction;
 
@@ -1549,7 +1550,7 @@ typedef struct XmlExpr
 	bool		indent;
 	/* target type/typmod for XMLSERIALIZE */
 	Oid			type pg_node_attr(query_jumble_ignore);
-	int32		typmod pg_node_attr(query_jumble_ignore);
+	TypMod		typmod pg_node_attr(query_jumble_ignore);
 	/* token location, or -1 if unknown */
 	Location	location;
 } XmlExpr;
@@ -1599,7 +1600,7 @@ typedef struct JsonReturning
 	NodeTag		type;
 	JsonFormat *format;			/* output JSON format */
 	Oid			typid;			/* target type Oid */
-	int32		typmod;			/* target type modifier */
+	TypMod		typmod;			/* target type modifier */
 } JsonReturning;
 
 /*
@@ -1762,7 +1763,7 @@ typedef struct CoerceToDomain
 	Expr	   *arg;			/* input expression */
 	Oid			resulttype;		/* domain type ID (result type) */
 	/* output typmod (currently always -1) */
-	int32		resulttypmod pg_node_attr(query_jumble_ignore);
+	TypMod		resulttypmod pg_node_attr(query_jumble_ignore);
 	/* OID of collation, or InvalidOid if none */
 	Oid			resultcollid pg_node_attr(query_jumble_ignore);
 	/* how to display this node */
@@ -1785,7 +1786,7 @@ typedef struct CoerceToDomainValue
 	/* type for substituted value */
 	Oid			typeId;
 	/* typemod for substituted value */
-	int32		typeMod pg_node_attr(query_jumble_ignore);
+	TypMod		typeMod pg_node_attr(query_jumble_ignore);
 	/* collation for the substituted value */
 	Oid			collation pg_node_attr(query_jumble_ignore);
 	/* token location, or -1 if unknown */
@@ -1805,7 +1806,7 @@ typedef struct SetToDefault
 	/* type for substituted value */
 	Oid			typeId;
 	/* typemod for substituted value */
-	int32		typeMod pg_node_attr(query_jumble_ignore);
+	TypMod		typeMod pg_node_attr(query_jumble_ignore);
 	/* collation for the substituted value */
 	Oid			collation pg_node_attr(query_jumble_ignore);
 	/* token location, or -1 if unknown */
-- 
2.40.1

