Subject: Re: attndims, typndims still not enforced, but make the value within a sane threshold

From: Tom Lane <[email-masked]>
Date: Wed, 18 Sep 2024 10:10:57 -0400

jian he <[email-masked]> writes:
> Can we error out at the stage "create table", "create domain"
> time if the attndims or typndims is larger than MAXDIM (6) ?

The last time this was discussed, I think the conclusion was
we should remove attndims and typndims entirely on the grounds
that they're useless.  I certainly don't see a point in adding
more logic that could give the misleading impression that they
mean something.

			regards, tom lane

---

From: jian he <[email-masked]>
Date: Wed, 18 Sep 2024 22:35:46 +0800

> more logic that could give the misleading impression that they

https://commitfest.postgresql.org/43/
search "dim" or "pg_attribute", no relevant result,
i am assuming, nobody doing work to remove attndims and typndims entirely?
If so, I will try to make one.

---

From: jian he <[email-masked]>
Date: Fri, 20 Sep 2024 10:11:00 +0800

> > more logic that could give the misleading impression that they

attached patch removes attndims and typndims entirely.
some tests skipped in my local my machine, not skipped are all OK.
From 4a473172b576a02aa4ac46af5de752e1f42d8922 Mon Sep 17 00:00:00 2001
From: jian he <[email-masked]>
Date: Fri, 20 Sep 2024 09:48:36 +0800
Subject: [PATCH v1 1/1] remove pg_attribute attndims and pg_type typndims

---
 contrib/dblink/dblink.c                       |  8 +-
 contrib/pg_buffercache/pg_buffercache_pages.c | 18 ++---
 contrib/pg_visibility/pg_visibility.c         |  8 +-
 doc/src/sgml/catalogs.sgml                    | 23 ------
 src/backend/access/brin/brin_tuple.c          |  2 +-
 src/backend/access/common/tupdesc.c           | 20 +----
 src/backend/access/gin/ginutil.c              |  5 +-
 src/backend/access/gist/gistscan.c            |  4 +-
 src/backend/access/transam/twophase.c         | 10 +--
 src/backend/access/transam/xlogfuncs.c        |  4 +-
 src/backend/backup/basebackup_copy.c          | 10 +--
 src/backend/bootstrap/bootstrap.c             | 11 ---
 src/backend/catalog/genbki.pl                 |  2 -
 src/backend/catalog/heap.c                    |  3 -
 src/backend/catalog/index.c                   |  1 -
 src/backend/catalog/pg_publication.c          |  8 +-
 src/backend/catalog/pg_type.c                 |  3 -
 src/backend/catalog/toasting.c                |  6 +-
 src/backend/commands/explain.c                |  2 +-
 src/backend/commands/functioncmds.c           |  3 +-
 src/backend/commands/sequence.c               |  4 +-
 src/backend/commands/tablecmds.c              | 13 +--
 src/backend/commands/typecmds.c               | 11 ---
 src/backend/executor/execSRF.c                |  6 +-
 src/backend/executor/execTuples.c             |  6 +-
 src/backend/executor/nodeFunctionscan.c       |  6 +-
 src/backend/parser/parse_relation.c           |  9 +--
 src/backend/parser/parse_target.c             |  3 +-
 src/backend/parser/parse_type.c               |  1 +
 .../libpqwalreceiver/libpqwalreceiver.c       |  2 +-
 src/backend/replication/walsender.c           | 30 +++----
 src/backend/utils/adt/acl.c                   |  9 +--
 src/backend/utils/adt/genfile.c               | 12 +--
 src/backend/utils/adt/lockfuncs.c             | 33 ++++----
 src/backend/utils/adt/orderedsetaggs.c        |  3 +-
 src/backend/utils/adt/pgstatfuncs.c           | 79 +++++++++----------
 src/backend/utils/adt/tsvector_op.c           |  6 +-
 src/backend/utils/fmgr/funcapi.c              | 33 +++-----
 src/backend/utils/misc/guc_funcs.c            | 50 ++++++------
 src/include/access/tupdesc.h                  |  7 +-
 src/include/catalog/pg_attribute.h            |  5 --
 src/include/catalog/pg_type.h                 |  7 --
 src/pl/plpgsql/src/pl_comp.c                  |  4 +-
 .../injection_points/injection_stats_fixed.c  | 10 +--
 .../modules/test_predtest/test_predtest.c     | 16 ++--
 45 files changed, 198 insertions(+), 318 deletions(-)

diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index c1c82eb4dd..04938991f9 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -874,7 +874,7 @@ materializeResult(FunctionCallInfo fcinfo, PGconn *conn, PGresult *res)
 			 */
 			tupdesc = CreateTemplateTupleDesc(1);
 			TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
-							   TEXTOID, -1, 0);
+							   TEXTOID, -1);
 			ntuples = 1;
 			nfields = 1;
 		}
@@ -1048,7 +1048,7 @@ materializeQueryResult(FunctionCallInfo fcinfo,
 			 */
 			tupdesc = CreateTemplateTupleDesc(1);
 			TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
-							   TEXTOID, -1, 0);
+							   TEXTOID, -1);
 			attinmeta = TupleDescGetAttInMetadata(tupdesc);
 
 			oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
@@ -1534,9 +1534,9 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
 		 */
 		tupdesc = CreateTemplateTupleDesc(2);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "position",
-						   INT4OID, -1, 0);
+						   INT4OID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "colname",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 
 		/*
 		 * Generate attribute metadata needed later to produce tuples from raw
diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c
index 3ae0a018e1..a72e641e0c 100644
--- a/contrib/pg_buffercache/pg_buffercache_pages.c
+++ b/contrib/pg_buffercache/pg_buffercache_pages.c
@@ -106,25 +106,25 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
 		/* Construct a tuple descriptor for the result rows. */
 		tupledesc = CreateTemplateTupleDesc(expected_tupledesc->natts);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 1, "bufferid",
-						   INT4OID, -1, 0);
+						   INT4OID, -1);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 2, "relfilenode",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 3, "reltablespace",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 4, "reldatabase",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 5, "relforknumber",
-						   INT2OID, -1, 0);
+						   INT2OID, -1);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 6, "relblocknumber",
-						   INT8OID, -1, 0);
+						   INT8OID, -1);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 7, "isdirty",
-						   BOOLOID, -1, 0);
+						   BOOLOID, -1);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 8, "usage_count",
-						   INT2OID, -1, 0);
+						   INT2OID, -1);
 
 		if (expected_tupledesc->natts == NUM_BUFFERCACHE_PAGES_ELEM)
 			TupleDescInitEntry(tupledesc, (AttrNumber) 9, "pinning_backends",
-							   INT4OID, -1, 0);
+							   INT4OID, -1);
 
 		fctx->tupdesc = BlessTupleDesc(tupledesc);
 
diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index 724122b1bc..b1fd64b488 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -465,11 +465,11 @@ pg_visibility_tupdesc(bool include_blkno, bool include_pd)
 		++maxattr;
 	tupdesc = CreateTemplateTupleDesc(maxattr);
 	if (include_blkno)
-		TupleDescInitEntry(tupdesc, ++a, "blkno", INT8OID, -1, 0);
-	TupleDescInitEntry(tupdesc, ++a, "all_visible", BOOLOID, -1, 0);
-	TupleDescInitEntry(tupdesc, ++a, "all_frozen", BOOLOID, -1, 0);
+		TupleDescInitEntry(tupdesc, ++a, "blkno", INT8OID, -1);
+	TupleDescInitEntry(tupdesc, ++a, "all_visible", BOOLOID, -1);
+	TupleDescInitEntry(tupdesc, ++a, "all_frozen", BOOLOID, -1);
 	if (include_pd)
-		TupleDescInitEntry(tupdesc, ++a, "pd_all_visible", BOOLOID, -1, 0);
+		TupleDescInitEntry(tupdesc, ++a, "pd_all_visible", BOOLOID, -1);
 	Assert(a == maxattr);
 
 	return BlessTupleDesc(tupdesc);
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index bfb97865e1..460e478fd7 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>
@@ -9499,18 +9488,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/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c
index 997eb6d822..7d0dd21440 100644
--- a/src/backend/access/brin/brin_tuple.c
+++ b/src/backend/access/brin/brin_tuple.c
@@ -79,7 +79,7 @@ brtuple_disk_tupdesc(BrinDesc *brdesc)
 			for (j = 0; j < brdesc->bd_info[i]->oi_nstored; j++)
 				TupleDescInitEntry(tupdesc, attno++, NULL,
 								   brdesc->bd_info[i]->oi_typcache[j]->type_id,
-								   -1, 0);
+								   -1);
 		}
 
 		MemoryContextSwitchTo(oldcxt);
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 47379fef22..58557abaa5 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.
@@ -652,8 +647,7 @@ TupleDescInitEntry(TupleDesc desc,
 				   AttrNumber attributeNumber,
 				   const char *attributeName,
 				   Oid oidtypeid,
-				   int32 typmod,
-				   int attdim)
+				   int32 typmod)
 {
 	HeapTuple	tuple;
 	Form_pg_type typeForm;
@@ -665,8 +659,6 @@ TupleDescInitEntry(TupleDesc desc,
 	Assert(PointerIsValid(desc));
 	Assert(attributeNumber >= 1);
 	Assert(attributeNumber <= desc->natts);
-	Assert(attdim >= 0);
-	Assert(attdim <= PG_INT16_MAX);
 
 	/*
 	 * initialize the attribute fields
@@ -689,7 +681,6 @@ TupleDescInitEntry(TupleDesc desc,
 	att->atttypmod = typmod;
 
 	att->attnum = attributeNumber;
-	att->attndims = attdim;
 
 	att->attnotnull = false;
 	att->atthasdef = false;
@@ -727,8 +718,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
 						  AttrNumber attributeNumber,
 						  const char *attributeName,
 						  Oid oidtypeid,
-						  int32 typmod,
-						  int attdim)
+						  int32 typmod)
 {
 	Form_pg_attribute att;
 
@@ -736,8 +726,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
 	Assert(PointerIsValid(desc));
 	Assert(attributeNumber >= 1);
 	Assert(attributeNumber <= desc->natts);
-	Assert(attdim >= 0);
-	Assert(attdim <= PG_INT16_MAX);
+
 
 	/* initialize the attribute fields */
 	att = TupleDescAttr(desc, attributeNumber - 1);
@@ -751,7 +740,6 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
 	att->atttypmod = typmod;
 
 	att->attnum = attributeNumber;
-	att->attndims = attdim;
 
 	att->attnotnull = false;
 	att->atthasdef = false;
@@ -885,7 +873,7 @@ BuildDescFromLists(const List *names, const List *types, const List *typmods, co
 
 		attnum++;
 
-		TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
+		TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod);
 		TupleDescInitEntryCollation(desc, attnum, attcollation);
 	}
 
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index 830d67fbc2..2041e58369 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -117,11 +117,10 @@ initGinState(GinState *state, Relation index)
 			state->tupdesc[i] = CreateTemplateTupleDesc(2);
 
 			TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 1, NULL,
-							   INT2OID, -1, 0);
+							   INT2OID, -1);
 			TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 2, NULL,
 							   attr->atttypid,
-							   attr->atttypmod,
-							   attr->attndims);
+							   attr->atttypmod);
 			TupleDescInitEntryCollation(state->tupdesc[i], (AttrNumber) 2,
 										attr->attcollation);
 		}
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index de472e1637..353df42b4e 100644
--- a/src/backend/access/gist/gistscan.c
+++ b/src/backend/access/gist/gistscan.c
@@ -190,7 +190,7 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
 		{
 			TupleDescInitEntry(so->giststate->fetchTupdesc, attno, NULL,
 							   scan->indexRelation->rd_opcintype[attno - 1],
-							   -1, 0);
+							   -1);
 		}
 
 		for (; attno <= natts; attno++)
@@ -199,7 +199,7 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
 			TupleDescInitEntry(so->giststate->fetchTupdesc, attno, NULL,
 							   TupleDescAttr(so->giststate->leafTupdesc,
 											 attno - 1)->atttypid,
-							   -1, 0);
+							   -1);
 		}
 		scan->xs_hitupdesc = so->giststate->fetchTupdesc;
 
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index e98286d768..4a38d50dd2 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -730,15 +730,15 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 		/* this had better match pg_prepared_xacts view in system_views.sql */
 		tupdesc = CreateTemplateTupleDesc(5);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "transaction",
-						   XIDOID, -1, 0);
+						   XIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "gid",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared",
-						   TIMESTAMPTZOID, -1, 0);
+						   TIMESTAMPTZOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 
 		funcctx->tuple_desc = BlessTupleDesc(tupdesc);
 
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 3e3d2bb618..29f4be3662 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -398,9 +398,9 @@ pg_walfile_name_offset(PG_FUNCTION_ARGS)
 	 */
 	resultTupleDesc = CreateTemplateTupleDesc(2);
 	TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "file_name",
-					   TEXTOID, -1, 0);
+					   TEXTOID, -1);
 	TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "file_offset",
-					   INT4OID, -1, 0);
+					   INT4OID, -1);
 
 	resultTupleDesc = BlessTupleDesc(resultTupleDesc);
 
diff --git a/src/backend/backup/basebackup_copy.c b/src/backend/backup/basebackup_copy.c
index 0b4ee5f2a2..10f241d5f5 100644
--- a/src/backend/backup/basebackup_copy.c
+++ b/src/backend/backup/basebackup_copy.c
@@ -349,13 +349,13 @@ SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli)
 	dest = CreateDestReceiver(DestRemoteSimple);
 
 	tupdesc = CreateTemplateTupleDesc(2);
-	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "recptr", TEXTOID, -1, 0);
+	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "recptr", TEXTOID, -1);
 
 	/*
 	 * int8 may seem like a surprising data type for this, but in theory int4
 	 * would not be wide enough for this, as TimeLineID is unsigned.
 	 */
-	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "tli", INT8OID, -1, 0);
+	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "tli", INT8OID, -1);
 
 	/* send RowDescription */
 	tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
@@ -385,9 +385,9 @@ SendTablespaceList(List *tablespaces)
 	dest = CreateDestReceiver(DestRemoteSimple);
 
 	tupdesc = CreateTemplateTupleDesc(3);
-	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "spcoid", OIDOID, -1, 0);
-	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "spclocation", TEXTOID, -1, 0);
-	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "size", INT8OID, -1, 0);
+	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "spcoid", OIDOID, -1);
+	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "spclocation", TEXTOID, -1);
+	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "size", INT8OID, -1);
 
 	/* send RowDescription */
 	tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 7637581a18..20d40befee 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -515,11 +515,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
 	{
@@ -530,12 +525,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..d6711713e0 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -947,8 +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} =
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 78e59384d1..ba6fb20ee1 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,6 @@ AddNewRelationType(const char *typeName,
 				   TYPALIGN_DOUBLE, /* alignment - must be the largest! */
 				   TYPSTORAGE_EXTENDED, /* fully TOASTable */
 				   -1,			/* typmod */
-				   0,			/* array dimensions for typBaseType */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* rowtypes never have a collation */
 }
@@ -1385,7 +1383,6 @@ 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 */
 				   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 b2b3ecb524..4935f95826 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_publication.c b/src/backend/catalog/pg_publication.c
index 7fe5fe2b86..71abb17fb8 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -1131,13 +1131,13 @@ pg_get_publication_tables(PG_FUNCTION_ARGS)
 		/* Construct a tuple descriptor for the result rows. */
 		tupdesc = CreateTemplateTupleDesc(NUM_PUBLICATION_TABLES_ELEM);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pubid",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "relid",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "attrs",
-						   INT2VECTOROID, -1, 0);
+						   INT2VECTOROID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "qual",
-						   PG_NODE_TREEOID, -1, 0);
+						   PG_NODE_TREEOID, -1);
 
 		funcctx->tuple_desc = BlessTupleDesc(tupdesc);
 		funcctx->user_fctx = (void *) table_infos;
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 395dec8ed8..388ae22645 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;
@@ -221,7 +220,6 @@ TypeCreate(Oid newTypeOid,
 		   char alignment,
 		   char storage,
 		   int32 typeMod,
-		   int32 typNDims,		/* Array dimensions for baseType */
 		   bool typeNotNull,
 		   Oid typeCollation)
 {
@@ -376,7 +374,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/catalog/toasting.c b/src/backend/catalog/toasting.c
index 738bc46ae8..b698efa75a 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -204,15 +204,15 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
 					   "chunk_id",
 					   OIDOID,
-					   -1, 0);
+					   -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2,
 					   "chunk_seq",
 					   INT4OID,
-					   -1, 0);
+					   -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 3,
 					   "chunk_data",
 					   BYTEAOID,
-					   -1, 0);
+					   -1);
 
 	/*
 	 * Ensure that the toast table doesn't itself get toasted, or we'll be
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index aaec439892..73d3352a55 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -417,7 +417,7 @@ ExplainResultDesc(ExplainStmt *stmt)
 	/* Need a tuple descriptor representing a single TEXT or XML column */
 	tupdesc = CreateTemplateTupleDesc(1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN",
-					   result_type, -1, 0);
+					   result_type, -1);
 	return tupdesc;
 }
 
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index d43b89d3ef..74e431d2b4 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -2400,8 +2400,7 @@ CallStmtResultDesc(CallStmt *stmt)
 							   i + 1,
 							   NameStr(att->attname),
 							   exprType(outarg),
-							   -1,
-							   0);
+							   -1);
 		}
 	}
 
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 0188e8bbd5..907a3f386c 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -1798,9 +1798,9 @@ pg_get_sequence_data(PG_FUNCTION_ARGS)
 
 	resultTupleDesc = CreateTemplateTupleDesc(PG_GET_SEQUENCE_DATA_COLS);
 	TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "last_value",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "is_called",
-					   BOOLOID, -1, 0);
+					   BOOLOID, -1);
 	resultTupleDesc = BlessTupleDesc(resultTupleDesc);
 
 	init_sequence(relid, &elm, &seqrel);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 2d703aa22e..ccdde1e988 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1291,7 +1291,6 @@ BuildDescForRelation(const List *columns)
 	Oid			atttypid;
 	int32		atttypmod;
 	Oid			attcollation;
-	int			attdim;
 
 	/*
 	 * allocate a new tuple descriptor
@@ -1322,11 +1321,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,
@@ -1335,7 +1329,7 @@ BuildDescForRelation(const List *columns)
 							attname)));
 
 		TupleDescInitEntry(desc, attnum, attname,
-						   atttypid, atttypmod, attdim);
+						   atttypid, atttypmod);
 		att = TupleDescAttr(desc, attnum - 1);
 
 		/* Override TupleDescInitEntry's settings as requested */
@@ -13404,11 +13398,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 2a6550de90..d25027e2b3 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -599,7 +599,6 @@ DefineType(ParseState *pstate, List *names, List *parameters)
 				   alignment,	/* required alignment */
 				   storage,		/* TOAST strategy */
 				   -1,			/* typMod (Domains only) */
-				   0,			/* Array Dimensions of typbasetype */
 				   false,		/* Type NOT NULL */
 				   collation);	/* type's collation */
 	Assert(typoid == address.objectId);
@@ -641,7 +640,6 @@ 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 */
 			   false,			/* Type NOT NULL */
 			   collation);		/* type's collation */
 
@@ -719,7 +717,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;
@@ -1050,7 +1047,6 @@ DefineDomain(CreateDomainStmt *stmt)
 				   alignment,	/* required alignment */
 				   storage,		/* TOAST strategy */
 				   basetypeMod, /* typeMod value */
-				   typNDims,	/* Array dimensions for base type */
 				   typNotNull,	/* Type NOT NULL */
 				   domaincoll); /* type's collation */
 
@@ -1091,7 +1087,6 @@ DefineDomain(CreateDomainStmt *stmt)
 			   alignment,		/* see above */
 			   TYPSTORAGE_EXTENDED, /* ARRAY is always toastable */
 			   -1,				/* typMod (Domains only) */
-			   0,				/* Array dimensions of typbasetype */
 			   false,			/* Type NOT NULL */
 			   domaincoll);		/* type's collation */
 
@@ -1213,7 +1208,6 @@ DefineEnum(CreateEnumStmt *stmt)
 				   TYPALIGN_INT,	/* int alignment */
 				   TYPSTORAGE_PLAIN,	/* TOAST strategy always plain */
 				   -1,			/* typMod (Domains only) */
-				   0,			/* Array dimensions of typbasetype */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* type's collation */
 
@@ -1254,7 +1248,6 @@ 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 */
 			   false,			/* Type NOT NULL */
 			   InvalidOid);		/* type's collation */
 
@@ -1555,7 +1548,6 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
 				   alignment,	/* alignment */
 				   TYPSTORAGE_EXTENDED, /* TOAST strategy (always extended) */
 				   -1,			/* typMod (Domains only) */
-				   0,			/* Array dimensions of typbasetype */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* type's collation (ranges never have one) */
 	Assert(typoid == InvalidOid || typoid == address.objectId);
@@ -1622,7 +1614,6 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
 				   alignment,	/* alignment */
 				   'x',			/* TOAST strategy (always extended) */
 				   -1,			/* typMod (Domains only) */
-				   0,			/* Array dimensions of typbasetype */
 				   false,		/* Type NOT NULL */
 				   InvalidOid); /* type's collation (ranges never have one) */
 	Assert(multirangeOid == mltrngaddress.objectId);
@@ -1665,7 +1656,6 @@ 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 */
 			   false,			/* Type NOT NULL */
 			   InvalidOid);		/* typcollation */
 
@@ -1704,7 +1694,6 @@ 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 */
 			   false,			/* Type NOT NULL */
 			   InvalidOid);		/* typcollation */
 
diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c
index 862d3085f8..7c7f91de69 100644
--- a/src/backend/executor/execSRF.c
+++ b/src/backend/executor/execSRF.c
@@ -270,8 +270,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
 									   (AttrNumber) 1,
 									   "column",
 									   funcrettype,
-									   -1,
-									   0);
+									   -1);
 					rsinfo.setDesc = tupdesc;
 				}
 				MemoryContextSwitchTo(oldcontext);
@@ -774,8 +773,7 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node,
 							   (AttrNumber) 1,
 							   NULL,
 							   funcrettype,
-							   -1,
-							   0);
+							   -1);
 			sexpr->funcResultDesc = tupdesc;
 			sexpr->funcReturnsTuple = false;
 		}
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 00dc339615..549c7e4b6c 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -2063,8 +2063,7 @@ ExecTypeFromTLInternal(List *targetList, bool skipjunk)
 						   cur_resno,
 						   tle->resname,
 						   exprType((Node *) tle->expr),
-						   exprTypmod((Node *) tle->expr),
-						   0);
+						   exprTypmod((Node *) tle->expr));
 		TupleDescInitEntryCollation(typeInfo,
 									cur_resno,
 									exprCollation((Node *) tle->expr));
@@ -2097,8 +2096,7 @@ ExecTypeFromExprList(List *exprList)
 						   cur_resno,
 						   NULL,
 						   exprType(e),
-						   exprTypmod(e),
-						   0);
+						   exprTypmod(e));
 		TupleDescInitEntryCollation(typeInfo,
 									cur_resno,
 									exprCollation(e));
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c
index 3fdd1c51e1..07f0f357ee 100644
--- a/src/backend/executor/nodeFunctionscan.c
+++ b/src/backend/executor/nodeFunctionscan.c
@@ -409,8 +409,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
 								   (AttrNumber) 1,
 								   NULL,	/* don't care about the name here */
 								   funcrettype,
-								   -1,
-								   0);
+								   -1);
 				TupleDescInitEntryCollation(tupdesc,
 											(AttrNumber) 1,
 											exprCollation(funcexpr));
@@ -481,8 +480,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
 							   ++attno,
 							   NULL,	/* don't care about the name here */
 							   INT8OID,
-							   -1,
-							   0);
+							   -1);
 		}
 
 		Assert(attno == natts);
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 8075b1b8a1..55e9f20604 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1873,8 +1873,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
 							   chooseScalarFunctionAlias(funcexpr, funcname,
 														 alias, nfuncs),
 							   funcrettype,
-							   exprTypmod(funcexpr),
-							   0);
+							   exprTypmod(funcexpr));
 			TupleDescInitEntryCollation(tupdesc,
 										(AttrNumber) 1,
 										exprCollation(funcexpr));
@@ -1919,8 +1918,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
 								   (AttrNumber) i,
 								   attrname,
 								   attrtype,
-								   attrtypmod,
-								   0);
+								   attrtypmod);
 				TupleDescInitEntryCollation(tupdesc,
 											(AttrNumber) i,
 											attrcollation);
@@ -1999,8 +1997,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
 							   (AttrNumber) ++natts,
 							   "ordinality",
 							   INT8OID,
-							   -1,
-							   0);
+							   -1);
 			/* no need to set collation */
 		}
 
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 76bf88c3ca..584d700092 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -1563,8 +1563,7 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
 			TupleDescInitEntry(tupleDesc, i,
 							   label,
 							   exprType(varnode),
-							   exprTypmod(varnode),
-							   0);
+							   exprTypmod(varnode));
 			TupleDescInitEntryCollation(tupleDesc, i,
 										exprCollation(varnode));
 			i++;
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index c1a937a43b..3a6261c1df 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -19,6 +19,7 @@
 #include "catalog/pg_type.h"
 #include "lib/stringinfo.h"
 #include "nodes/makefuncs.h"
+#include "nodes/print.h"
 #include "parser/parse_type.h"
 #include "parser/parser.h"
 #include "utils/array.h"
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 97f957cd87..50e21616b3 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -1193,7 +1193,7 @@ libpqrcv_processTuples(PGresult *pgres, WalRcvExecResult *walres,
 	walres->tupledesc = CreateTemplateTupleDesc(nRetTypes);
 	for (coln = 0; coln < nRetTypes; coln++)
 		TupleDescInitEntry(walres->tupledesc, (AttrNumber) coln + 1,
-						   PQfname(pgres, coln), retTypes[coln], -1, 0);
+						   PQfname(pgres, coln), retTypes[coln], -1);
 	attinmeta = TupleDescGetAttInMetadata(walres->tupledesc);
 
 	/* No point in doing more here if there were no tuples returned. */
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index c5f1009f37..bfa6d37799 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -451,13 +451,13 @@ IdentifySystem(void)
 	/* need a tuple descriptor representing four columns */
 	tupdesc = CreateTemplateTupleDesc(4);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "systemid",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "timeline",
-							  INT8OID, -1, 0);
+							  INT8OID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "xlogpos",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 4, "dbname",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 
 	/* prepare for projection of tuples */
 	tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
@@ -497,12 +497,12 @@ ReadReplicationSlot(ReadReplicationSlotCmd *cmd)
 
 	tupdesc = CreateTemplateTupleDesc(READ_REPLICATION_SLOT_COLS);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "slot_type",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "restart_lsn",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	/* TimeLineID is unsigned, so int4 is not wide enough. */
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "restart_tli",
-							  INT8OID, -1, 0);
+							  INT8OID, -1);
 
 	memset(nulls, true, READ_REPLICATION_SLOT_COLS * sizeof(bool));
 
@@ -603,8 +603,8 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
 	 * the name of the history file, 2nd is the contents.
 	 */
 	tupdesc = CreateTemplateTupleDesc(2);
-	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "filename", TEXTOID, -1, 0);
-	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "content", TEXTOID, -1, 0);
+	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "filename", TEXTOID, -1);
+	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "content", TEXTOID, -1);
 
 	TLHistoryFileName(histfname, cmd->timeline);
 	TLHistoryFilePath(path, cmd->timeline);
@@ -1017,9 +1017,9 @@ StartReplication(StartReplicationCmd *cmd)
 		 */
 		tupdesc = CreateTemplateTupleDesc(2);
 		TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "next_tli",
-								  INT8OID, -1, 0);
+								  INT8OID, -1);
 		TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "next_tli_startpos",
-								  TEXTOID, -1, 0);
+								  TEXTOID, -1);
 
 		/* prepare for projection of tuple */
 		tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
@@ -1360,13 +1360,13 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 	 */
 	tupdesc = CreateTemplateTupleDesc(4);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "slot_name",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "consistent_point",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "snapshot_name",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 4, "output_plugin",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 
 	/* prepare for projection of tuples */
 	tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 2a716cc6b7..50174e1c56 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -1794,14 +1794,13 @@ aclexplode(PG_FUNCTION_ARGS)
 		 */
 		tupdesc = CreateTemplateTupleDesc(4);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "grantor",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "grantee",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "privilege_type",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "is_grantable",
-						   BOOLOID, -1, 0);
-
+						   BOOLOID, -1);
 		funcctx->tuple_desc = BlessTupleDesc(tupdesc);
 
 		/* allocate memory for user context */
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 24b95c32b7..a547802d0c 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -443,17 +443,17 @@ pg_stat_file(PG_FUNCTION_ARGS)
 	 */
 	tupdesc = CreateTemplateTupleDesc(6);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
-					   "size", INT8OID, -1, 0);
+					   "size", INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2,
-					   "access", TIMESTAMPTZOID, -1, 0);
+					   "access", TIMESTAMPTZOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 3,
-					   "modification", TIMESTAMPTZOID, -1, 0);
+					   "modification", TIMESTAMPTZOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 4,
-					   "change", TIMESTAMPTZOID, -1, 0);
+					   "change", TIMESTAMPTZOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5,
-					   "creation", TIMESTAMPTZOID, -1, 0);
+					   "creation", TIMESTAMPTZOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 6,
-					   "isdir", BOOLOID, -1, 0);
+					   "isdir", BOOLOID, -1);
 	BlessTupleDesc(tupdesc);
 
 	memset(isnull, false, sizeof(isnull));
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index e790f856ab..1bc526bf7a 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -114,38 +114,37 @@ pg_lock_status(PG_FUNCTION_ARGS)
 		/* this had better match function's declaration in pg_proc.h */
 		tupdesc = CreateTemplateTupleDesc(NUM_LOCK_STATUS_COLUMNS);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "locktype",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "relation",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "page",
-						   INT4OID, -1, 0);
+						   INT4OID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "tuple",
-						   INT2OID, -1, 0);
+						   INT2OID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 6, "virtualxid",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 7, "transactionid",
-						   XIDOID, -1, 0);
+						   XIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 8, "classid",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 9, "objid",
-						   OIDOID, -1, 0);
+						   OIDOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 10, "objsubid",
-						   INT2OID, -1, 0);
+						   INT2OID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 11, "virtualtransaction",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 12, "pid",
-						   INT4OID, -1, 0);
+						   INT4OID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 13, "mode",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 14, "granted",
-						   BOOLOID, -1, 0);
+						   BOOLOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 15, "fastpath",
-						   BOOLOID, -1, 0);
+						   BOOLOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 16, "waitstart",
-						   TIMESTAMPTZOID, -1, 0);
-
+						   TIMESTAMPTZOID, -1);
 		funcctx->tuple_desc = BlessTupleDesc(tupdesc);
 
 		/*
diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c
index 04b3f31827..34cb6d319a 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -230,8 +230,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
 								   (AttrNumber) ++natts,
 								   "flag",
 								   INT4OID,
-								   -1,
-								   0);
+								   -1);
 
 				FreeTupleDesc(qstate->tupdesc);
 				qstate->tupdesc = newdesc;
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 9c23ac7c8c..c5eb9cd130 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -715,10 +715,9 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_SUBXACT_COLS);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subxact_count",
-					   INT4OID, -1, 0);
+					   INT4OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subxact_overflow",
-					   BOOLOID, -1, 0);
-
+					   BOOLOID, -1);
 	BlessTupleDesc(tupdesc);
 
 	if ((local_beentry = pgstat_get_local_beentry_by_proc_number(procNumber)) != NULL)
@@ -1478,24 +1477,23 @@ pg_stat_get_wal(PG_FUNCTION_ARGS)
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_WAL_COLS);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes",
-					   NUMERICOID, -1, 0);
+					   NUMERICOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_buffers_full",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_write",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "wal_sync",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "wal_write_time",
-					   FLOAT8OID, -1, 0);
+					   FLOAT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 8, "wal_sync_time",
-					   FLOAT8OID, -1, 0);
+					   FLOAT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 9, "stats_reset",
-					   TIMESTAMPTZOID, -1, 0);
-
+					   TIMESTAMPTZOID, -1);
 	BlessTupleDesc(tupdesc);
 
 	/* Get statistics about WAL activity */
@@ -1837,20 +1835,19 @@ pg_stat_get_archiver(PG_FUNCTION_ARGS)
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(7);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
-					   TEXTOID, -1, 0);
+					   TEXTOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
-					   TIMESTAMPTZOID, -1, 0);
+					   TIMESTAMPTZOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
-					   TEXTOID, -1, 0);
+					   TEXTOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
-					   TIMESTAMPTZOID, -1, 0);
+					   TIMESTAMPTZOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
-					   TIMESTAMPTZOID, -1, 0);
-
+					   TIMESTAMPTZOID, -1);
 	BlessTupleDesc(tupdesc);
 
 	/* Get statistics about the archiver process */
@@ -1907,25 +1904,25 @@ pg_stat_get_replication_slot(PG_FUNCTION_ARGS)
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_REPLICATION_SLOT_COLS);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "slot_name",
-					   TEXTOID, -1, 0);
+					   TEXTOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "spill_txns",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "spill_count",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "spill_bytes",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stream_txns",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stream_count",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 8, "total_txns",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_bytes",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 10, "stats_reset",
-					   TIMESTAMPTZOID, -1, 0);
+					   TIMESTAMPTZOID, -1);
 	BlessTupleDesc(tupdesc);
 
 	namestrcpy(&slotname, text_to_cstring(slotname_text));
@@ -1981,25 +1978,25 @@ pg_stat_get_subscription_stats(PG_FUNCTION_ARGS)
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_SUBSCRIPTION_STATS_COLS);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subid",
-					   OIDOID, -1, 0);
+					   OIDOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "apply_error_count",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sync_error_count",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "confl_insert_exists",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "confl_update_origin_differs",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 6, "confl_update_exists",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 7, "confl_update_missing",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 8, "confl_delete_origin_differs",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 9, "confl_delete_missing",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 10, "stats_reset",
-					   TIMESTAMPTZOID, -1, 0);
+					   TIMESTAMPTZOID, -1);
 	BlessTupleDesc(tupdesc);
 
 	if (!subentry)
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index 687adcbd69..3f22aefa66 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -644,11 +644,11 @@ tsvector_unnest(PG_FUNCTION_ARGS)
 
 		tupdesc = CreateTemplateTupleDesc(3);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "lexeme",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "positions",
-						   INT2ARRAYOID, -1, 0);
+						   INT2ARRAYOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "weights",
-						   TEXTARRAYOID, -1, 0);
+						   TEXTARRAYOID, -1);
 		if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 			elog(ERROR, "return type must be a row type");
 		funcctx->tuple_desc = tupdesc;
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 05d763fa06..e59fe7496b 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -334,8 +334,7 @@ get_expr_result_type(Node *expr,
 			TupleDescInitEntry(tupdesc, i,
 							   colname,
 							   exprType(col),
-							   exprTypmod(col),
-							   0);
+							   exprTypmod(col));
 			TupleDescInitEntryCollation(tupdesc, i,
 										exprCollation(col));
 			i++;
@@ -978,32 +977,28 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
 				TupleDescInitEntry(tupdesc, i + 1,
 								   NameStr(att->attname),
 								   poly_actuals.anyelement_type,
-								   -1,
-								   0);
+								   -1);
 				TupleDescInitEntryCollation(tupdesc, i + 1, anycollation);
 				break;
 			case ANYARRAYOID:
 				TupleDescInitEntry(tupdesc, i + 1,
 								   NameStr(att->attname),
 								   poly_actuals.anyarray_type,
-								   -1,
-								   0);
+								   -1);
 				TupleDescInitEntryCollation(tupdesc, i + 1, anycollation);
 				break;
 			case ANYRANGEOID:
 				TupleDescInitEntry(tupdesc, i + 1,
 								   NameStr(att->attname),
 								   poly_actuals.anyrange_type,
-								   -1,
-								   0);
+								   -1);
 				/* no collation should be attached to a range type */
 				break;
 			case ANYMULTIRANGEOID:
 				TupleDescInitEntry(tupdesc, i + 1,
 								   NameStr(att->attname),
 								   poly_actuals.anymultirange_type,
-								   -1,
-								   0);
+								   -1);
 				/* no collation should be attached to a multirange type */
 				break;
 			case ANYCOMPATIBLEOID:
@@ -1011,32 +1006,28 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
 				TupleDescInitEntry(tupdesc, i + 1,
 								   NameStr(att->attname),
 								   anyc_actuals.anyelement_type,
-								   -1,
-								   0);
+								   -1);
 				TupleDescInitEntryCollation(tupdesc, i + 1, anycompatcollation);
 				break;
 			case ANYCOMPATIBLEARRAYOID:
 				TupleDescInitEntry(tupdesc, i + 1,
 								   NameStr(att->attname),
 								   anyc_actuals.anyarray_type,
-								   -1,
-								   0);
+								   -1);
 				TupleDescInitEntryCollation(tupdesc, i + 1, anycompatcollation);
 				break;
 			case ANYCOMPATIBLERANGEOID:
 				TupleDescInitEntry(tupdesc, i + 1,
 								   NameStr(att->attname),
 								   anyc_actuals.anyrange_type,
-								   -1,
-								   0);
+								   -1);
 				/* no collation should be attached to a range type */
 				break;
 			case ANYCOMPATIBLEMULTIRANGEOID:
 				TupleDescInitEntry(tupdesc, i + 1,
 								   NameStr(att->attname),
 								   anyc_actuals.anymultirange_type,
-								   -1,
-								   0);
+								   -1);
 				/* no collation should be attached to a multirange type */
 				break;
 			default:
@@ -1849,8 +1840,7 @@ build_function_result_tupdesc_d(char prokind,
 		TupleDescInitEntry(desc, i + 1,
 						   outargnames[i],
 						   outargtypes[i],
-						   -1,
-						   0);
+						   -1);
 	}
 
 	return desc;
@@ -1968,8 +1958,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases)
 						   (AttrNumber) 1,
 						   attname,
 						   typeoid,
-						   -1,
-						   0);
+						   -1);
 	}
 	else if (functypclass == TYPEFUNC_RECORD)
 	{
diff --git a/src/backend/utils/misc/guc_funcs.c b/src/backend/utils/misc/guc_funcs.c
index 9c9edd3d2f..43d3ef3f21 100644
--- a/src/backend/utils/misc/guc_funcs.c
+++ b/src/backend/utils/misc/guc_funcs.c
@@ -400,11 +400,11 @@ GetPGVariableResultDesc(const char *name)
 		/* need a tuple descriptor representing three TEXT columns */
 		tupdesc = CreateTemplateTupleDesc(3);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 	}
 	else
 	{
@@ -416,7 +416,7 @@ GetPGVariableResultDesc(const char *name)
 		/* need a tuple descriptor representing a single TEXT column */
 		tupdesc = CreateTemplateTupleDesc(1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 	}
 	return tupdesc;
 }
@@ -438,7 +438,7 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest)
 	/* need a tuple descriptor representing a single TEXT column */
 	tupdesc = CreateTemplateTupleDesc(1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname,
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 
 	/* prepare for projection of tuples */
 	tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
@@ -468,11 +468,11 @@ ShowAllGUCConfig(DestReceiver *dest)
 	/* need a tuple descriptor representing three TEXT columns */
 	tupdesc = CreateTemplateTupleDesc(3);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "name",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "setting",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "description",
-							  TEXTOID, -1, 0);
+							  TEXTOID, -1);
 
 	/* prepare for projection of tuples */
 	tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
@@ -874,39 +874,39 @@ show_all_settings(PG_FUNCTION_ARGS)
 		 */
 		tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "unit",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "category",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "short_desc",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 6, "extra_desc",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 7, "context",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 8, "vartype",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 9, "source",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 10, "min_val",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 11, "max_val",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 12, "enumvals",
-						   TEXTARRAYOID, -1, 0);
+						   TEXTARRAYOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 13, "boot_val",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 14, "reset_val",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 15, "sourcefile",
-						   TEXTOID, -1, 0);
+						   TEXTOID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 16, "sourceline",
-						   INT4OID, -1, 0);
+						   INT4OID, -1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 17, "pending_restart",
-						   BOOLOID, -1, 0);
+						   BOOLOID, -1);
 
 		/*
 		 * Generate attribute metadata needed later to produce tuples from raw
diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h
index 8930a28d66..6b8006a1ae 100644
--- a/src/include/access/tupdesc.h
+++ b/src/include/access/tupdesc.h
@@ -133,16 +133,13 @@ extern void TupleDescInitEntry(TupleDesc desc,
 							   AttrNumber attributeNumber,
 							   const char *attributeName,
 							   Oid oidtypeid,
-							   int32 typmod,
-							   int attdim);
+							   int32 typmod);
 
 extern void TupleDescInitBuiltinEntry(TupleDesc desc,
 									  AttrNumber attributeNumber,
 									  const char *attributeName,
 									  Oid oidtypeid,
-									  int32 typmod,
-									  int attdim);
-
+									  int32 typmod);
 extern void TupleDescInitEntryCollation(TupleDesc desc,
 										AttrNumber attributeNumber,
 										Oid collationid);
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 1c62b8bfcb..337dee92e0 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -90,11 +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
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index e925969732..951e89a538 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -214,12 +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
 	 * DEFAULT_COLLATION_OID) for collatable base types, possibly some other
@@ -378,7 +372,6 @@ extern ObjectAddress TypeCreate(Oid newTypeOid,
 								char alignment,
 								char storage,
 								int32 typeMod,
-								int32 typNDims,
 								bool typeNotNull,
 								Oid typeCollation);
 
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index f1bce708d6..cc41c179df 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -1980,8 +1980,8 @@ build_row_from_vars(PLpgSQL_variable **vars, int numvars)
 
 		TupleDescInitEntry(row->rowtupdesc, i + 1,
 						   var->refname,
-						   typoid, typmod,
-						   0);
+						   typoid, typmod);
+
 		TupleDescInitEntryCollation(row->rowtupdesc, i + 1, typcoll);
 	}
 
diff --git a/src/test/modules/injection_points/injection_stats_fixed.c b/src/test/modules/injection_points/injection_stats_fixed.c
index 2fed178b7a..63d7e8424c 100644
--- a/src/test/modules/injection_points/injection_stats_fixed.c
+++ b/src/test/modules/injection_points/injection_stats_fixed.c
@@ -181,15 +181,15 @@ injection_points_stats_fixed(PG_FUNCTION_ARGS)
 	/* Initialise attributes information in the tuple descriptor */
 	tupdesc = CreateTemplateTupleDesc(5);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "numattach",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "numdetach",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 3, "numrun",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 4, "numcached",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5, "numloaded",
-					   INT8OID, -1, 0);
+					   INT8OID, -1);
 	BlessTupleDesc(tupdesc);
 
 	values[0] = Int64GetDatum(stats->numattach);
diff --git a/src/test/modules/test_predtest/test_predtest.c b/src/test/modules/test_predtest/test_predtest.c
index 678b13ca30..a4daa004c8 100644
--- a/src/test/modules/test_predtest/test_predtest.c
+++ b/src/test/modules/test_predtest/test_predtest.c
@@ -215,21 +215,21 @@ test_predtest(PG_FUNCTION_ARGS)
 
 	tupdesc = CreateTemplateTupleDesc(8);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
-					   "strong_implied_by", BOOLOID, -1, 0);
+					   "strong_implied_by", BOOLOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2,
-					   "weak_implied_by", BOOLOID, -1, 0);
+					   "weak_implied_by", BOOLOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 3,
-					   "strong_refuted_by", BOOLOID, -1, 0);
+					   "strong_refuted_by", BOOLOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 4,
-					   "weak_refuted_by", BOOLOID, -1, 0);
+					   "weak_refuted_by", BOOLOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 5,
-					   "s_i_holds", BOOLOID, -1, 0);
+					   "s_i_holds", BOOLOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 6,
-					   "w_i_holds", BOOLOID, -1, 0);
+					   "w_i_holds", BOOLOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 7,
-					   "s_r_holds", BOOLOID, -1, 0);
+					   "s_r_holds", BOOLOID, -1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 8,
-					   "w_r_holds", BOOLOID, -1, 0);
+					   "w_r_holds", BOOLOID, -1);
 	tupdesc = BlessTupleDesc(tupdesc);
 
 	values[0] = BoolGetDatum(strong_implied_by);
-- 
2.34.1

---

From: Junwang Zhao <[email-masked]>
Date: Fri, 20 Sep 2024 11:51:49 +0800

> some tests skipped in my local my machine, not skipped are all OK.

Should you also bump the catalog version?

-- 
Regards
Junwang Zhao

---

From: Michael Paquier <[email-masked]>
Date: Fri, 20 Sep 2024 13:30:46 +0900

> Should you also bump the catalog version?

No need to worry about that when sending a patch because committers
take care of that when merging a patch into the tree.  Doing that in
each patch submitted just creates more conflicts and work for patch
authors because they'd need to recolve conflicts each time a
catversion bump happens.  And that can happen on a daily basis
sometimes depending on what is committed.
--
Michael

---

From: Tom Lane <[email-masked]>
Date: Fri, 20 Sep 2024 00:38:16 -0400

> sometimes depending on what is committed.

Right.  Sometimes the committer forgets to do that :-(, which is
not great but it's not normally a big problem either.  We've concluded
it's better to err in that direction than impose additional work
on patch submitters.

If you feel concerned about the point, best practice is to include a
mention that catversion bump is needed in your draft commit message.

			regards, tom lane

---

From: Junwang Zhao <[email-masked]>
Date: Fri, 20 Sep 2024 15:14:20 +0800

Hi Tom and Michael,

> mention that catversion bump is needed in your draft commit message.

Got it, thanks for both of your explanations.

-- 
Regards
Junwang Zhao

---

From: Bruce Momjian <[email-masked]>
Date: Fri, 20 Sep 2024 09:27:47 -0400

> some tests skipped in my local my machine, not skipped are all OK.

I have been hoping for a patch links this because I feel the existence
of these system columns is deceptive since we don't honor them properly.

-- 
  Bruce Momjian  <[email-masked]>        https://momjian.us
  EDB                                      https://enterprisedb.com

  When a patient asks the doctor, "Am I going to die?", he means 
  "Am I going to die soon?"

---

From: Andrew Dunstan <[email-masked]>
Date: Mon, 23 Sep 2024 15:30:42 -0400

> it's better to err in that direction than impose additional work

FWIW, I have a git pre-commit hook that helps avoid that. Essentially it 
checks to see if there are changes in src/include/catalog but not in 
catversion.h. That's not a 100% check, but it probably catches the vast 
majority of changes that would require a catversion bump.

cheers

andrew

--
Andrew Dunstan
EDB: https://www.enterprisedb.com

---

From: Kirill Reshke <[email-masked]>
Date: Thu, 5 Dec 2024 18:24:35 +0500

> attached patch removes attndims and typndims entirely.

LGTM?
I see no open items in this thread. Are there any issues about v1?

-- 
Best regards,
Kirill Reshke