diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 7377912b41..c2efcb68d2 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -382,6 +382,7 @@ ConstructTupleDescriptor(Relation heapRelation,
 			to->atttypid = keyType;
 			to->attlen = typeTup->typlen;
 			to->atttypmod = exprTypmod(indexkey);
+			to->attndims = IsTrueArrayType(typeTup) ? 1 : 0;
 			to->attbyval = typeTup->typbyval;
 			to->attalign = typeTup->typalign;
 			to->attstorage = typeTup->typstorage;
@@ -467,6 +468,7 @@ ConstructTupleDescriptor(Relation heapRelation,
 
 			to->atttypid = keyType;
 			to->atttypmod = -1;
+			to->attndims = IsTrueArrayType(typeTup) ? 1 : 0;
 			to->attlen = typeTup->typlen;
 			to->attbyval = typeTup->typbyval;
 			to->attalign = typeTup->typalign;
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 23cecd99c9..13fb6acfcf 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -183,7 +183,8 @@ create_ctas_nodata(List *tlist, IntoClause *into)
 			col = makeColumnDef(colname,
 								exprType((Node *) tle->expr),
 								exprTypmod((Node *) tle->expr),
-								exprCollation((Node *) tle->expr));
+								exprCollation((Node *) tle->expr),
+								-1 /* detect array-ness */ );
 
 			/*
 			 * It's possible that the column is of a collatable type but the
@@ -492,10 +493,17 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
 		else
 			colname = NameStr(attribute->attname);
 
+		/*
+		 * Note: we pass ndims as -1 not attribute->attndims because (a) the
+		 * tupledesc we are given may not have accurate attndims, and (b) it
+		 * seems best for this path to give results matching
+		 * create_ctas_nodata.
+		 */
 		col = makeColumnDef(colname,
 							attribute->atttypid,
 							attribute->atttypmod,
-							attribute->attcollation);
+							attribute->attcollation,
+							-1 /* detect array-ness */ );
 
 		/*
 		 * It's possible that the column is of a collatable type but the
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index b13ee2b745..d5ca4ed5cb 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -178,15 +178,18 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
 		switch (i)
 		{
 			case SEQ_COL_LASTVAL:
-				coldef = makeColumnDef("last_value", INT8OID, -1, InvalidOid);
+				coldef = makeColumnDef("last_value", INT8OID, -1,
+									   InvalidOid, 0);
 				value[i - 1] = Int64GetDatumFast(seqdataform.last_value);
 				break;
 			case SEQ_COL_LOG:
-				coldef = makeColumnDef("log_cnt", INT8OID, -1, InvalidOid);
+				coldef = makeColumnDef("log_cnt", INT8OID, -1,
+									   InvalidOid, 0);
 				value[i - 1] = Int64GetDatum((int64) 0);
 				break;
 			case SEQ_COL_CALLED:
-				coldef = makeColumnDef("is_called", BOOLOID, -1, InvalidOid);
+				coldef = makeColumnDef("is_called", BOOLOID, -1,
+									   InvalidOid, 0);
 				value[i - 1] = BoolGetDatum(false);
 				break;
 		}
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d8f0a99ad9..c0b1de326c 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -2741,7 +2741,9 @@ MergeAttributes(List *columns, const List *supers, char relpersistence,
 			 * Create new column definition
 			 */
 			newdef = makeColumnDef(attributeName, attribute->atttypid,
-								   attribute->atttypmod, attribute->attcollation);
+								   attribute->atttypmod,
+								   attribute->attcollation,
+								   attribute->attndims);
 			newdef->storage = attribute->attstorage;
 			newdef->generated = attribute->attgenerated;
 			if (CompressionMethodIsValid(attribute->attcompression))
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index 6f0301555e..cd0919a935 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -64,7 +64,8 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace,
 			ColumnDef  *def = makeColumnDef(tle->resname,
 											exprType((Node *) tle->expr),
 											exprTypmod((Node *) tle->expr),
-											exprCollation((Node *) tle->expr));
+											exprCollation((Node *) tle->expr),
+											-1 /* detect array-ness */ );
 
 			/*
 			 * It's possible that the column is of a collatable type but the
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 007612563c..aad0e78e3d 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -512,15 +512,29 @@ makeTypeNameFromOid(Oid typeOid, int32 typmod)
  *	build a ColumnDef node to represent a simple column definition.
  *
  * Type and collation are specified by OID.
+ * Typmod must be given in numeric form.
+ *
+ * ndims can be positive to select that number of array dimensions,
+ * or 0 if it's not an array, or -1 for this function to detect whether
+ * it's an array type.  (In that case we will declare the column as having a
+ * single array dimension.  This might not accurately reproduce the source of,
+ * say, CREATE TABLE AS; but we don't have the information to do better.)
+ *
  * Other properties are all basic to start with.
  */
 ColumnDef *
-makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
+makeColumnDef(const char *colname, Oid typeOid, int32 typmod,
+			  Oid collOid, int ndims)
 {
 	ColumnDef  *n = makeNode(ColumnDef);
 
 	n->colname = pstrdup(colname);
 	n->typeName = makeTypeNameFromOid(typeOid, typmod);
+	if (ndims < 0)
+		ndims = OidIsValid(get_element_type(typeOid)) ? 1 : 0;
+	while (ndims-- > 0)
+		n->typeName->arrayBounds = lappend(n->typeName->arrayBounds,
+										   makeInteger(-1));
 	n->inhcount = 0;
 	n->is_local = true;
 	n->is_not_null = false;
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index ca028d2a66..d03bc06f3e 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1198,7 +1198,8 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
 		 * Create a new column definition
 		 */
 		def = makeColumnDef(NameStr(attribute->attname), attribute->atttypid,
-							attribute->atttypmod, attribute->attcollation);
+							attribute->atttypmod, attribute->attcollation,
+							attribute->attndims);
 
 		/*
 		 * Add to column list
@@ -1637,7 +1638,8 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
 			continue;
 
 		n = makeColumnDef(NameStr(attr->attname), attr->atttypid,
-						  attr->atttypmod, attr->attcollation);
+						  attr->atttypmod, attr->attcollation,
+						  attr->attndims);
 		n->is_from_type = true;
 
 		cxt->columns = lappend(cxt->columns, n);
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index 5473ce9a28..3747805f69 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -75,7 +75,8 @@ extern TypeName *makeTypeNameFromNameList(List *names);
 extern TypeName *makeTypeNameFromOid(Oid typeOid, int32 typmod);
 
 extern ColumnDef *makeColumnDef(const char *colname,
-								Oid typeOid, int32 typmod, Oid collOid);
+								Oid typeOid, int32 typmod, Oid collOid,
+								int ndims);
 
 extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args,
 							  Oid funccollid, Oid inputcollid, CoercionForm fformat);
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index e061389135..798448c82b 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -558,8 +558,54 @@ CREATE TABLE ctlt11 (LIKE ctlv1);
 CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL);
 CREATE TYPE ctlty1 AS (a int, b text);
 CREATE TABLE ctlt12 (LIKE ctlty1);
+/* Check that LIKE propagates attndims correctly */
+CREATE TABLE ctlarr1 (a int, b int[], c int[][]);
+CREATE TABLE ctlt13 (LIKE ctlarr1);
+SELECT attname, atttypid::regtype, attndims
+  FROM pg_attribute
+ WHERE attrelid = 'ctlarr1'::regclass AND attnum > 0
+ORDER BY attnum;
+ attname | atttypid  | attndims 
+---------+-----------+----------
+ a       | integer   |        0
+ b       | integer[] |        1
+ c       | integer[] |        2
+(3 rows)
+
+SELECT attname, atttypid::regtype, attndims
+  FROM pg_attribute
+ WHERE attrelid = 'ctlt13'::regclass AND attnum > 0
+ORDER BY attnum;
+ attname | atttypid  | attndims 
+---------+-----------+----------
+ a       | integer   |        0
+ b       | integer[] |        1
+ c       | integer[] |        2
+(3 rows)
+
+/*
+ * While we're here, check attndims consistency globally.
+ * Since this runs relatively late in the regression order, this will
+ * catch problems in system views and many types of indexes.
+ */
+SELECT relname, attname, attndims, typname
+  FROM pg_attribute a JOIN pg_type t ON (a.atttypid = t.oid)
+       JOIN pg_class c ON (a.attrelid = c.oid)
+ WHERE typsubscript = 'array_subscript_handler'::regproc AND attndims = 0;
+ relname | attname | attndims | typname 
+---------+---------+----------+---------
+(0 rows)
+
+SELECT relname, attname, attndims, typname
+  FROM pg_attribute a JOIN pg_type t ON (a.atttypid = t.oid)
+       JOIN pg_class c ON (a.attrelid = c.oid)
+ WHERE typsubscript != 'array_subscript_handler'::regproc AND attndims != 0;
+ relname | attname | attndims | typname 
+---------+---------+----------+---------
+(0 rows)
+
 DROP SEQUENCE ctlseq1;
 DROP TYPE ctlty1;
 DROP VIEW ctlv1;
-DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12;
+DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12, ctlarr1, ctlt13;
 NOTICE:  table "ctlt10" does not exist, skipping
diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql
index a41f8b83d7..6432ebb0e5 100644
--- a/src/test/regress/sql/create_table_like.sql
+++ b/src/test/regress/sql/create_table_like.sql
@@ -221,7 +221,37 @@ CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL);
 CREATE TYPE ctlty1 AS (a int, b text);
 CREATE TABLE ctlt12 (LIKE ctlty1);
 
+
+/* Check that LIKE propagates attndims correctly */
+
+CREATE TABLE ctlarr1 (a int, b int[], c int[][]);
+CREATE TABLE ctlt13 (LIKE ctlarr1);
+SELECT attname, atttypid::regtype, attndims
+  FROM pg_attribute
+ WHERE attrelid = 'ctlarr1'::regclass AND attnum > 0
+ORDER BY attnum;
+SELECT attname, atttypid::regtype, attndims
+  FROM pg_attribute
+ WHERE attrelid = 'ctlt13'::regclass AND attnum > 0
+ORDER BY attnum;
+
+/*
+ * While we're here, check attndims consistency globally.
+ * Since this runs relatively late in the regression order, this will
+ * catch problems in system views and many types of indexes.
+ */
+SELECT relname, attname, attndims, typname
+  FROM pg_attribute a JOIN pg_type t ON (a.atttypid = t.oid)
+       JOIN pg_class c ON (a.attrelid = c.oid)
+ WHERE typsubscript = 'array_subscript_handler'::regproc AND attndims = 0;
+
+SELECT relname, attname, attndims, typname
+  FROM pg_attribute a JOIN pg_type t ON (a.atttypid = t.oid)
+       JOIN pg_class c ON (a.attrelid = c.oid)
+ WHERE typsubscript != 'array_subscript_handler'::regproc AND attndims != 0;
+
+
 DROP SEQUENCE ctlseq1;
 DROP TYPE ctlty1;
 DROP VIEW ctlv1;
-DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12;
+DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12, ctlarr1, ctlt13;
