From 21e1a0eddbfa41ae1239533d80ba9d2081cf0400 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Fri, 6 Dec 2024 10:18:07 +0800
Subject: [PATCH v2 1/1] remove pg_attribute attndims and pg_type typndims

discussion: https://postgr.es/m/CACJufxH0RxsxUQnAT2AVG08JFpA3C60L91_cEMM8JQd8P=12ow@mail.gmail.com
commitfest: https://commitfest.postgresql.org/50/5263/
---
 doc/src/sgml/catalogs.sgml          | 23 -----------------------
 src/backend/access/common/tupdesc.c | 17 ++++++-----------
 src/backend/access/gin/ginutil.c    |  2 +-
 src/backend/bootstrap/bootstrap.c   | 11 -----------
 src/backend/catalog/genbki.pl       |  3 ---
 src/backend/catalog/heap.c          |  5 ++---
 src/backend/catalog/index.c         |  1 -
 src/backend/catalog/pg_type.c       |  4 ++--
 src/backend/commands/tablecmds.c    | 13 +------------
 src/backend/commands/typecmds.c     | 21 ++++++++++-----------
 src/include/catalog/pg_attribute.h  |  6 ------
 src/include/catalog/pg_type.h       |  5 -----
 12 files changed, 22 insertions(+), 89 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index bf3cee08a9..82322e5737 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1210,17 +1210,6 @@
       </para></entry>
      </row>
 
-     <row>
-      <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>attndims</structfield> <type>int2</type>
-      </para>
-      <para>
-       Number of dimensions, if the column is an array type; otherwise 0.
-       (Presently, the number of dimensions of an array is not enforced,
-       so any nonzero value effectively means <quote>it's an array</quote>.)
-      </para></entry>
-     </row>
-
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>attbyval</structfield> <type>bool</type>
@@ -9505,18 +9494,6 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
       </para></entry>
      </row>
 
-     <row>
-      <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>typndims</structfield> <type>int4</type>
-      </para>
-      <para>
-       <structfield>typndims</structfield> is the number of array dimensions
-       for a domain over an array (that is, <structfield>typbasetype</structfield> is
-       an array type).
-       Zero for types other than domains over array types.
-      </para></entry>
-     </row>
-
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>typcollation</structfield> <type>oid</type>
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 47379fef22..64dcf33108 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -452,8 +452,6 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
 			return false;
 		if (attr1->attlen != attr2->attlen)
 			return false;
-		if (attr1->attndims != attr2->attndims)
-			return false;
 		if (attr1->atttypmod != attr2->atttypmod)
 			return false;
 		if (attr1->attbyval != attr2->attbyval)
@@ -575,9 +573,6 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
  * This is used to check whether two record types are compatible, whether
  * function return row types are the same, and other similar situations.
  *
- * (XXX There was some discussion whether attndims should be checked here, but
- * for now it has been decided not to.)
- *
  * Note: We deliberately do not check the tdtypmod field.  This allows
  * typcache.c to use this routine to see if a cached record type matches a
  * requested type.
@@ -665,9 +660,10 @@ TupleDescInitEntry(TupleDesc desc,
 	Assert(PointerIsValid(desc));
 	Assert(attributeNumber >= 1);
 	Assert(attributeNumber <= desc->natts);
-	Assert(attdim >= 0);
-	Assert(attdim <= PG_INT16_MAX);
+	Assert(attdim == 0);
 
+	if (attdim != 0)
+		elog(ERROR, "attdim should be zero");
 	/*
 	 * initialize the attribute fields
 	 */
@@ -689,7 +685,6 @@ TupleDescInitEntry(TupleDesc desc,
 	att->atttypmod = typmod;
 
 	att->attnum = attributeNumber;
-	att->attndims = attdim;
 
 	att->attnotnull = false;
 	att->atthasdef = false;
@@ -736,8 +731,9 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
 	Assert(PointerIsValid(desc));
 	Assert(attributeNumber >= 1);
 	Assert(attributeNumber <= desc->natts);
-	Assert(attdim >= 0);
-	Assert(attdim <= PG_INT16_MAX);
+
+	if (attdim != 0)
+		elog(ERROR, "attdim should be zero");
 
 	/* initialize the attribute fields */
 	att = TupleDescAttr(desc, attributeNumber - 1);
@@ -751,7 +747,6 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
 	att->atttypmod = typmod;
 
 	att->attnum = attributeNumber;
-	att->attndims = attdim;
 
 	att->attnotnull = false;
 	att->atthasdef = false;
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index 830d67fbc2..dfc493a385 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -121,7 +121,7 @@ initGinState(GinState *state, Relation index)
 			TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 2, NULL,
 							   attr->atttypid,
 							   attr->atttypmod,
-							   attr->attndims);
+							   0);
 			TupleDescInitEntryCollation(state->tupdesc[i], (AttrNumber) 2,
 										attr->attcollation);
 		}
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index a5217773ff..b06c3dd23b 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -538,11 +538,6 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
 		attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;
 		attrtypes[attnum]->attcompression = InvalidCompressionMethod;
 		attrtypes[attnum]->attcollation = Ap->am_typ.typcollation;
-		/* if an array type, assume 1-dimensional attribute */
-		if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0)
-			attrtypes[attnum]->attndims = 1;
-		else
-			attrtypes[attnum]->attndims = 0;
 	}
 	else
 	{
@@ -553,12 +548,6 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
 		attrtypes[attnum]->attstorage = TypInfo[typeoid].storage;
 		attrtypes[attnum]->attcompression = InvalidCompressionMethod;
 		attrtypes[attnum]->attcollation = TypInfo[typeoid].collation;
-		/* if an array type, assume 1-dimensional attribute */
-		if (TypInfo[typeoid].elem != InvalidOid &&
-			attrtypes[attnum]->attlen < 0)
-			attrtypes[attnum]->attndims = 1;
-		else
-			attrtypes[attnum]->attndims = 0;
 	}
 
 	/*
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index 94afdc5491..2f5579fa06 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -947,9 +947,6 @@ sub morph_row_for_pgattr
 	$row->{attalign} = $type->{typalign};
 	$row->{attstorage} = $type->{typstorage};
 
-	# set attndims if it's an array type
-	$row->{attndims} = $type->{typcategory} eq 'A' ? '1' : '0';
-
 	# collation-aware catalog columns must use C collation
 	$row->{attcollation} =
 	  $type->{typcollation} ne '0' ? $C_COLLATION_OID : 0;
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index d7b88b61dc..83fb91068c 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -742,7 +742,6 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
 		slot[slotCount]->tts_values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(attrs->attnum);
 		slot[slotCount]->tts_values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1);
 		slot[slotCount]->tts_values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(attrs->atttypmod);
-		slot[slotCount]->tts_values[Anum_pg_attribute_attndims - 1] = Int16GetDatum(attrs->attndims);
 		slot[slotCount]->tts_values[Anum_pg_attribute_attbyval - 1] = BoolGetDatum(attrs->attbyval);
 		slot[slotCount]->tts_values[Anum_pg_attribute_attalign - 1] = CharGetDatum(attrs->attalign);
 		slot[slotCount]->tts_values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(attrs->attstorage);
@@ -1062,7 +1061,7 @@ AddNewRelationType(const char *typeName,
 				   TYPALIGN_DOUBLE, /* alignment - must be the largest! */
 				   TYPSTORAGE_EXTENDED, /* fully TOASTable */
 				   -1,			/* typmod */
-				   0,			/* array dimensions for typBaseType */
+				   0,			/* no usage, must pass as zero */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* rowtypes never have a collation */
 }
@@ -1385,7 +1384,7 @@ heap_create_with_catalog(const char *relname,
 				   TYPALIGN_DOUBLE, /* alignment - must be the largest! */
 				   TYPSTORAGE_EXTENDED, /* fully TOASTable */
 				   -1,			/* typmod */
-				   0,			/* array dimensions for typBaseType */
+				   0,			/* no usage, must pass as zero */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* rowtypes never have a collation */
 
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 1c3a9e06d3..f1273517bf 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -351,7 +351,6 @@ ConstructTupleDescriptor(Relation heapRelation,
 
 			to->atttypid = from->atttypid;
 			to->attlen = from->attlen;
-			to->attndims = from->attndims;
 			to->atttypmod = from->atttypmod;
 			to->attbyval = from->attbyval;
 			to->attalign = from->attalign;
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 395dec8ed8..dafde13971 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -118,7 +118,6 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
 	values[Anum_pg_type_typnotnull - 1] = BoolGetDatum(false);
 	values[Anum_pg_type_typbasetype - 1] = ObjectIdGetDatum(InvalidOid);
 	values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(-1);
-	values[Anum_pg_type_typndims - 1] = Int32GetDatum(0);
 	values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(InvalidOid);
 	nulls[Anum_pg_type_typdefaultbin - 1] = true;
 	nulls[Anum_pg_type_typdefault - 1] = true;
@@ -238,6 +237,8 @@ TypeCreate(Oid newTypeOid,
 	int			i;
 	ObjectAddress address;
 
+	if (typNDims != 0)
+		elog(ERROR, "typNDims should be zero");
 	/*
 	 * We assume that the caller validated the arguments individually, but did
 	 * not check for bad combinations.
@@ -376,7 +377,6 @@ TypeCreate(Oid newTypeOid,
 	values[Anum_pg_type_typnotnull - 1] = BoolGetDatum(typeNotNull);
 	values[Anum_pg_type_typbasetype - 1] = ObjectIdGetDatum(baseType);
 	values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(typeMod);
-	values[Anum_pg_type_typndims - 1] = Int32GetDatum(typNDims);
 	values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(typeCollation);
 
 	/*
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 6ccae4cb4a..abdfccf6bd 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1335,7 +1335,6 @@ BuildDescForRelation(const List *columns)
 	Oid			atttypid;
 	int32		atttypmod;
 	Oid			attcollation;
-	int			attdim;
 
 	/*
 	 * allocate a new tuple descriptor
@@ -1366,11 +1365,6 @@ BuildDescForRelation(const List *columns)
 			aclcheck_error_type(aclresult, atttypid);
 
 		attcollation = GetColumnDefCollation(NULL, entry, atttypid);
-		attdim = list_length(entry->typeName->arrayBounds);
-		if (attdim > PG_INT16_MAX)
-			ereport(ERROR,
-					errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-					errmsg("too many array dimensions"));
 
 		if (entry->typeName->setof)
 			ereport(ERROR,
@@ -1379,7 +1373,7 @@ BuildDescForRelation(const List *columns)
 							attname)));
 
 		TupleDescInitEntry(desc, attnum, attname,
-						   atttypid, atttypmod, attdim);
+						   atttypid, atttypmod, 0);
 		att = TupleDescAttr(desc, attnum - 1);
 
 		/* Override TupleDescInitEntry's settings as requested */
@@ -13769,11 +13763,6 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
 	attTup->atttypid = targettype;
 	attTup->atttypmod = targettypmod;
 	attTup->attcollation = targetcollid;
-	if (list_length(typeName->arrayBounds) > PG_INT16_MAX)
-		ereport(ERROR,
-				errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				errmsg("too many array dimensions"));
-	attTup->attndims = list_length(typeName->arrayBounds);
 	attTup->attlen = tform->typlen;
 	attTup->attbyval = tform->typbyval;
 	attTup->attalign = tform->typalign;
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index da591c0922..aa44abfb37 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -599,7 +599,7 @@ DefineType(ParseState *pstate, List *names, List *parameters)
 				   alignment,	/* required alignment */
 				   storage,		/* TOAST strategy */
 				   -1,			/* typMod (Domains only) */
-				   0,			/* Array Dimensions of typbasetype */
+				   0,			/* no usage, must pass as zero */
 				   false,		/* Type NOT NULL */
 				   collation);	/* type's collation */
 	Assert(typoid == address.objectId);
@@ -641,7 +641,7 @@ DefineType(ParseState *pstate, List *names, List *parameters)
 			   alignment,		/* see above */
 			   TYPSTORAGE_EXTENDED, /* ARRAY is always toastable */
 			   -1,				/* typMod (Domains only) */
-			   0,				/* Array dimensions of typbasetype */
+			   0,				/* no usage, must pass as zero */
 			   false,			/* Type NOT NULL */
 			   collation);		/* type's collation */
 
@@ -719,7 +719,6 @@ DefineDomain(CreateDomainStmt *stmt)
 	bool		saw_default = false;
 	bool		typNotNull = false;
 	bool		nullDefined = false;
-	int32		typNDims = list_length(stmt->typeName->arrayBounds);
 	HeapTuple	typeTup;
 	List	   *schema = stmt->constraints;
 	ListCell   *listptr;
@@ -1058,7 +1057,7 @@ DefineDomain(CreateDomainStmt *stmt)
 				   alignment,	/* required alignment */
 				   storage,		/* TOAST strategy */
 				   basetypeMod, /* typeMod value */
-				   typNDims,	/* Array dimensions for base type */
+				   0,			/* no usage, must pass as zero */
 				   typNotNull,	/* Type NOT NULL */
 				   domaincoll); /* type's collation */
 
@@ -1099,7 +1098,7 @@ DefineDomain(CreateDomainStmt *stmt)
 			   alignment,		/* see above */
 			   TYPSTORAGE_EXTENDED, /* ARRAY is always toastable */
 			   -1,				/* typMod (Domains only) */
-			   0,				/* Array dimensions of typbasetype */
+			   0,				/* no usage, must pass as zero */
 			   false,			/* Type NOT NULL */
 			   domaincoll);		/* type's collation */
 
@@ -1221,7 +1220,7 @@ DefineEnum(CreateEnumStmt *stmt)
 				   TYPALIGN_INT,	/* int alignment */
 				   TYPSTORAGE_PLAIN,	/* TOAST strategy always plain */
 				   -1,			/* typMod (Domains only) */
-				   0,			/* Array dimensions of typbasetype */
+				   0,			/* no usage, must pass as zero */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* type's collation */
 
@@ -1262,7 +1261,7 @@ DefineEnum(CreateEnumStmt *stmt)
 			   TYPALIGN_INT,	/* enums have int align, so do their arrays */
 			   TYPSTORAGE_EXTENDED, /* ARRAY is always toastable */
 			   -1,				/* typMod (Domains only) */
-			   0,				/* Array dimensions of typbasetype */
+			   0,				/* no usage, must pass as zero */
 			   false,			/* Type NOT NULL */
 			   InvalidOid);		/* type's collation */
 
@@ -1563,7 +1562,7 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
 				   alignment,	/* alignment */
 				   TYPSTORAGE_EXTENDED, /* TOAST strategy (always extended) */
 				   -1,			/* typMod (Domains only) */
-				   0,			/* Array dimensions of typbasetype */
+				   0,			/* no usage, must pass as zero */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* type's collation (ranges never have one) */
 	Assert(typoid == InvalidOid || typoid == address.objectId);
@@ -1630,7 +1629,7 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
 				   alignment,	/* alignment */
 				   'x',			/* TOAST strategy (always extended) */
 				   -1,			/* typMod (Domains only) */
-				   0,			/* Array dimensions of typbasetype */
+				   0,			/* no usage, must pass as zero */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* type's collation (ranges never have one) */
 	Assert(multirangeOid == mltrngaddress.objectId);
@@ -1673,7 +1672,7 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
 			   alignment,		/* alignment - same as range's */
 			   TYPSTORAGE_EXTENDED, /* ARRAY is always toastable */
 			   -1,				/* typMod (Domains only) */
-			   0,				/* Array dimensions of typbasetype */
+			   0,				/* no usage, must pass as zero */
 			   false,			/* Type NOT NULL */
 			   InvalidOid);		/* typcollation */
 
@@ -1712,7 +1711,7 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
 			   alignment,		/* alignment - same as range's */
 			   'x',				/* ARRAY is always toastable */
 			   -1,				/* typMod (Domains only) */
-			   0,				/* Array dimensions of typbasetype */
+			   0,				/* no usage, must pass as zero */
 			   false,			/* Type NOT NULL */
 			   InvalidOid);		/* typcollation */
 
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 1c62b8bfcb..2a6e594930 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -90,12 +90,6 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
 	 */
 	int32		atttypmod BKI_DEFAULT(-1);
 
-	/*
-	 * attndims is the declared number of dimensions, if an array type,
-	 * otherwise zero.
-	 */
-	int16		attndims;
-
 	/*
 	 * attbyval is a copy of the typbyval field from pg_type for this
 	 * attribute.  See atttypid comments above.
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index e925969732..7b9d02c0e5 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -214,11 +214,6 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati
 	 */
 	int32		typtypmod BKI_DEFAULT(-1);
 
-	/*
-	 * typndims is the declared number of dimensions for an array domain type
-	 * (i.e., typbasetype is an array type).  Otherwise zero.
-	 */
-	int32		typndims BKI_DEFAULT(0);
 
 	/*
 	 * Collation: 0 if type cannot use collations, nonzero (typically

base-commit: 792b2c7e6d926e61e8ff3b33d3e22d7d74e7a437
-- 
2.34.1

