diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index bac94a3..9ee45c7 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3417,36 +3417,104 @@ describeOneTableDetails(const char *schemaname,
 			PQclear(result);
 		}
 
-		/* print child tables (with additional info if partitions) */
-		if (pset.sversion >= 140000)
-			printfPQExpBuffer(&buf,
-							  "SELECT c.oid::pg_catalog.regclass, c.relkind,"
-							  " inhdetachpending,"
-							  " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n"
-							  "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
-							  "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
-							  "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT',"
-							  " c.oid::pg_catalog.regclass::pg_catalog.text;",
-							  oid);
-		else if (pset.sversion >= 100000)
-			printfPQExpBuffer(&buf,
-							  "SELECT c.oid::pg_catalog.regclass, c.relkind,"
-							  " false AS inhdetachpending,"
-							  " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n"
-							  "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
-							  "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
-							  "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT',"
-							  " c.oid::pg_catalog.regclass::pg_catalog.text;",
-							  oid);
-		else
-			printfPQExpBuffer(&buf,
-							  "SELECT c.oid::pg_catalog.regclass, c.relkind,"
-							  " false AS inhdetachpending, NULL\n"
-							  "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n"
-							  "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n"
-							  "ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;",
-							  oid);
-
+                /* print child tables (with additional info if partitions) */
+                if (pset.sversion >= 140000)
+                        printfPQExpBuffer(&buf,
+                                                        "WITH RECURSIVE partition_tree AS ( "
+                                                        "  SELECT c.oid::pg_catalog.regclass AS object_name, "
+                                                        "         c.oid,"
+                                                        "         0 AS level,"
+                                                        "         c.relkind,"
+                                                        "         i.inhdetachpending,"
+                                                        "         pg_get_expr(c.relpartbound, c.oid) AS relpartbound,"
+                                                        "         array[c.relname::text] AS path \n"
+                                                        "  FROM pg_catalog.pg_class c \n"
+                                                        "  JOIN pg_catalog.pg_inherits i ON c.oid = i.inhrelid \n"
+                                                        "  WHERE i.inhparent ='%s' \n"
+                                                        "  UNION ALL \n"
+                                                        "  SELECT c.oid::pg_catalog.regclass AS object_name,"
+                                                        "         c.oid,"
+                                                        "         pt.level + 1 AS level,"
+                                                        "         c.relkind,"
+                                                        "         i.inhdetachpending,"
+                                                        "         pg_get_expr(c.relpartbound, c.oid) AS relpartbound,"
+                                                        "         pt.path || c.relname::text \n"
+                                                        "  FROM pg_catalog.pg_class c \n"
+                                                        "  JOIN pg_catalog.pg_inherits i ON c.oid = i.inhrelid \n"
+                                                        "  JOIN partition_tree pt ON i.inhparent = pt.oid \n"
+                                                        " WHERE pt.level < 1 \n"
+                                                        ") \n"
+                                                        " SELECT REPEAT(E'\t', level) || object_name AS oid,"
+                                                        "       relkind,"
+                                                        "       inhdetachpending,"
+                                                        "       relpartbound as pg_get_expr \n"
+                                                        "FROM partition_tree t \n"
+                                                        "ORDER BY path, array_to_string(t.path || array[t.object_name::text], '.'), t.object_name, relpartbound = 'DEFAULT';",
+                                                        oid);
+                else if (pset.sversion >= 100000)
+                        printfPQExpBuffer(&buf,
+                                                        "WITH RECURSIVE partition_tree AS (\n"
+                                                        "  SELECT c.oid::pg_catalog.regclass AS partition_name,"
+                                                        "         c.oid,"
+                                                        "         0 AS level,"
+                                                        "        c.relkind,"
+                                                        "         false AS i.inhdetachpending,"
+                                                        "         pg_catalog.pg_get_expr(c.relpartbound, c.oid) AS relpartbound"
+                                                        "         array[c.relname::text] AS path \n"
+                                                        "  FROM pg_catalog.pg_class c "
+                                                        "  JOIN pg_catalog.pg_inherits i ON c.oid = i.inhrelid\n"
+                                                        "  WHERE i.inhparent = '%s'\n"
+                                                        "  UNION ALL"
+                                                        "  SELECT c.oid::pg_catalog.regclass AS partition_name,"
+                                                        "         c.oid,"
+                                                        "         pt.level + 1 AS level,"
+                                                        "         c.relkind,"
+                                                        "         false AS i.inhdetachpending,"
+                                                        "         pg_catalog.pg_get_expr(c.relpartbound, c.oid) AS relpartbound"
+                                                        "         pt.path || c.relname::text\n"
+                                                        "  FROM pg_catalog.pg_class c"
+                                                        "  JOIN pg_catalog.pg_inherits i ON c.oid = i.inhrelid"
+                                                        "  JOIN partition_tree pt ON i.inhparent = pt.oid"
+                                                        " WHERE pt.level < 1 \n"
+                                                        ")\n"
+                                                        "SELECT REPEAT(' ', level * 4) || partition_name AS oid,"
+                                                        " relkind,"
+                                                        " inhdetachpending,"
+                                                        " relpartbound as pg_get_expr\n"
+                                                        "FROM partition_tree\n"
+                                                        "ORDER BY partition_name::pg_catalog.text, level, relpartbound = 'DEFAULT';",
+                                                        oid);
+                else
+                        printfPQExpBuffer(&buf,
+                                                        "WITH RECURSIVE partition_tree AS (\n"
+                                                        "  SELECT c.oid::pg_catalog.regclass AS partition_name,"
+                                                        "         c.oid,"
+                                                        "         0 AS level,"
+                                                        "         c.relkind,"
+                                                        "         false AS i.inhdetachpending,"
+                                                        "         array[c.relname::text] AS path \n"
+                                                        "  FROM pg_catalog.pg_class c "
+                                                        "  JOIN pg_catalog.pg_inherits i ON c.oid = i.inhrelid\n"
+                                                        "  WHERE i.inhparent = '%s'\n"
+                                                        "  UNION ALL"
+                                                        "  SELECT c.oid::pg_catalog.regclass AS partition_name,"
+                                                        "         c.oid,"
+                                                        "         pt.level + 1 AS level,"
+                                                        "         c.relkind,"
+                                                        "         false AS i.inhdetachpending,"
+                                                        "         pt.path || c.relname::text\n"
+                                                        "  FROM pg_catalog.pg_class c"
+                                                        "  JOIN pg_catalog.pg_inherits i ON c.oid = i.inhrelid"
+                                                        "  JOIN partition_tree pt ON i.inhparent = pt.oid"
+                                                        " WHERE pt.level < 1 \n"
+                                                        ")\n"
+                                                        "SELECT REPEAT(' ', level * 4) || partition_name AS oid,"
+                                                        " relkind,"
+                                                        " inhdetachpending,"
+                                                        " NULL\n"
+                                                        "FROM partition_tree\n"
+                                                        "ORDER BY partition_name::pg_catalog.text, level, relpartbound = 'DEFAULT';",
+                                                        oid);
 		result = PSQLexec(buf.data);
 		if (!result)
 			goto error_return;
@@ -3495,7 +3563,7 @@ describeOneTableDetails(const char *schemaname,
 					appendPQExpBuffer(&buf, " %s", PQgetvalue(result, i, 3));
 				if (child_relkind == RELKIND_PARTITIONED_TABLE ||
 					child_relkind == RELKIND_PARTITIONED_INDEX)
-					appendPQExpBufferStr(&buf, ", PARTITIONED");
+					appendPQExpBufferStr(&buf, ", CONTAINS SUBPARTITIONS");
 				else if (child_relkind == RELKIND_FOREIGN_TABLE)
 					appendPQExpBufferStr(&buf, ", FOREIGN");
 				if (strcmp(PQgetvalue(result, i, 2), "t") == 0)
diff --git a/src/test/regress/expected/subpartition_indentation.out b/src/test/regress/expected/subpartition_indentation.out
new file mode 100644
index 0000000..7239685
--- /dev/null
+++ b/src/test/regress/expected/subpartition_indentation.out
@@ -0,0 +1,100 @@
+--
+-- Tests for psql subpartition indentation in \d+ [table]
+--
+
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+CREATE TABLE
+                                      Partitioned table "public.p_quarter_check"
+ Column |         Type          | Collation | Nullable | Default | Storage  | Compression | Stats target | Description 
+--------+-----------------------+-----------+----------+---------+----------+-------------+--------------+-------------
+ id     | integer               |           | not null |         | plain    |             |              | 
+ dept   | character varying(10) |           |          |         | extended |             |              | 
+ name   | character varying(20) |           |          |         | extended |             |              | 
+ in_d   | date                  |           | not null |         | plain    |             |              | 
+ etc    | text                  |           |          |         | extended |             |              | 
+Partition key: RANGE (in_d)
+Partitions: in_p_q1 FOR VALUES FROM ('2023-01-01') TO ('2023-04-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202301 FOR VALUES FROM ('2023-01-01') TO ('2023-02-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202302 FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202303 FOR VALUES FROM ('2023-03-01') TO ('2023-04-01'), CONTAINS SUBPARTITIONES,
+            in_p_q2 FOR VALUES FROM ('2023-04-01') TO ('2023-07-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202304 FOR VALUES FROM ('2023-04-01') TO ('2023-05-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202305 FOR VALUES FROM ('2023-05-01') TO ('2023-06-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202306 FOR VALUES FROM ('2023-06-01') TO ('2023-07-01'), CONTAINS SUBPARTITIONES,
+            in_p_q3 FOR VALUES FROM ('2023-07-01') TO ('2023-10-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202307 FOR VALUES FROM ('2023-07-01') TO ('2023-08-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202308 FOR VALUES FROM ('2023-08-01') TO ('2023-09-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202309 FOR VALUES FROM ('2023-09-01') TO ('2023-10-01'), CONTAINS SUBPARTITIONES,
+            in_p_q4 FOR VALUES FROM ('2023-10-01') TO ('2024-01-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202310 FOR VALUES FROM ('2023-10-01') TO ('2023-11-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202311 FOR VALUES FROM ('2023-11-01') TO ('2023-12-01'), CONTAINS SUBPARTITIONES,
+                in_p_m202312 FOR VALUES FROM ('2023-12-01') TO ('2024-01-01'), CONTAINS SUBPARTITIONES
+
+                                          Partitioned table "public.in_p_q1"
+ Column |         Type          | Collation | Nullable | Default | Storage  | Compression | Stats target | Description 
+--------+-----------------------+-----------+----------+---------+----------+-------------+--------------+-------------
+ id     | integer               |           | not null |         | plain    |             |              | 
+ dept   | character varying(10) |           |          |         | extended |             |              | 
+ name   | character varying(20) |           |          |         | extended |             |              | 
+ in_d   | date                  |           | not null |         | plain    |             |              | 
+ etc    | text                  |           |          |         | extended |             |              | 
+Partition of: p_quarter_check FOR VALUES FROM ('2023-01-01') TO ('2023-04-01')
+Partition constraint: ((in_d IS NOT NULL) AND (in_d >= '2023-01-01'::date) AND (in_d < '2023-04-01'::date))
+Partition key: RANGE (in_d)
+Partitions: in_p_m202301 FOR VALUES FROM ('2023-01-01') TO ('2023-02-01'), CONTAINS SUBPARTITIONES,
+                in_p_w202301 FOR VALUES FROM ('2023-01-01') TO ('2023-01-08'),
+                in_p_w202302 FOR VALUES FROM ('2023-01-08') TO ('2023-01-15'),
+                in_p_w202303 FOR VALUES FROM ('2023-01-15') TO ('2023-01-22'),
+                in_p_w202304 FOR VALUES FROM ('2023-01-22') TO ('2023-01-29'),
+                in_p_w202305 FOR VALUES FROM ('2023-01-29') TO ('2023-02-01'),
+            in_p_m202302 FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'), CONTAINS SUBPARTITIONES,
+            in_p_m202303 FOR VALUES FROM ('2023-03-01') TO ('2023-04-01'), CONTAINS SUBPARTITIONES
+
+                                        Partitioned table "public.in_p_m202301"
+ Column |         Type          | Collation | Nullable | Default | Storage  | Compression | Stats target | Description 
+--------+-----------------------+-----------+----------+---------+----------+-------------+--------------+-------------
+ id     | integer               |           | not null |         | plain    |             |              | 
+ dept   | character varying(10) |           |          |         | extended |             |              | 
+ name   | character varying(20) |           |          |         | extended |             |              | 
+ in_d   | date                  |           | not null |         | plain    |             |              | 
+ etc    | text                  |           |          |         | extended |             |              | 
+Partition of: in_p_q1 FOR VALUES FROM ('2023-01-01') TO ('2023-02-01')
+Partition constraint: ((in_d IS NOT NULL) AND (in_d >= '2023-01-01'::date) AND (in_d < '2023-04-01'::date) AND (in_d IS NOT NULL) AND (in_d >= '2023-01-01'::date) AND (in_d < '2023-02-01'::date))
+Partition key: RANGE (in_d)
+Partitions: in_p_w202301 FOR VALUES FROM ('2023-01-01') TO ('2023-01-08'),
+            in_p_w202302 FOR VALUES FROM ('2023-01-08') TO ('2023-01-15'),
+            in_p_w202303 FOR VALUES FROM ('2023-01-15') TO ('2023-01-22'),
+            in_p_w202304 FOR VALUES FROM ('2023-01-22') TO ('2023-01-29'),
+            in_p_w202305 FOR VALUES FROM ('2023-01-29') TO ('2023-02-01')
+
+                                              Table "public.in_p_w202301"
+ Column |         Type          | Collation | Nullable | Default | Storage  | Compression | Stats target | Description 
+--------+-----------------------+-----------+----------+---------+----------+-------------+--------------+-------------
+ id     | integer               |           | not null |         | plain    |             |              | 
+ dept   | character varying(10) |           |          |         | extended |             |              | 
+ name   | character varying(20) |           |          |         | extended |             |              | 
+ in_d   | date                  |           | not null |         | plain    |             |              | 
+ etc    | text                  |           |          |         | extended |             |              | 
+Partition of: in_p_m202301 FOR VALUES FROM ('2023-01-01') TO ('2023-01-08')
+Partition constraint: ((in_d IS NOT NULL) AND (in_d >= '2023-01-01'::date) AND (in_d < '2023-04-01'::date) AND (in_d IS NOT NULL) AND (in_d >= '2023-01-01'::date) AND (in_d < '2023-02-01'::date) AND (in_d IS NOT NULL) AND (in_d >= '2023-01-01'::date) AND (in_d < '2023-01-08'::date))
+Access method: heap
diff --git a/src/test/regress/sql/subpartition_indentation.sql b/src/test/regress/sql/subpartition_indentation.sql
new file mode 100644
index 0000000..1303ae7
--- /dev/null
+++ b/src/test/regress/sql/subpartition_indentation.sql
@@ -0,0 +1,46 @@
+--
+-- Tests for psql subpartition indentation in \d+ [table]
+--
+
+-- Test partition table & subpartition table create
+create table p_quarter_check(
+    id int not null
+  , dept varchar(10)
+  , name varchar(20)
+  , in_d date not null
+  , etc text)
+  partition by range(in_d) ;
+
+create table in_p_q1 partition of p_quarter_check for values from ('20230101') to ('20230401') PARTITION BY range (in_d) ;
+create table in_p_q2 partition of p_quarter_check for values from ('20230401') to ('20230701') PARTITION BY range (in_d) ;
+create table in_p_q3 partition of p_quarter_check for values from ('20230701') to ('20231001') PARTITION BY range (in_d) ;
+create table in_p_q4 partition of p_quarter_check for values from ('20231001') to ('20240101') PARTITION BY range (in_d) ;
+
+create table in_p_m202301 partition of in_p_q1 for values from ('20230101') to ('20230201') PARTITION BY range (in_d) ; 
+create table in_p_m202302 partition of in_p_q1 for values from ('20230201') to ('20230301') PARTITION BY range (in_d) ; 
+create table in_p_m202303 partition of in_p_q1 for values from ('20230301') to ('20230401') PARTITION BY range (in_d) ; 
+
+create table in_p_m202304 partition of in_p_q2 for values from ('20230401') to ('20230501') PARTITION BY range (in_d);
+create table in_p_m202305 partition of in_p_q2 for values from ('20230501') to ('20230601') PARTITION BY range (in_d);
+create table in_p_m202306 partition of in_p_q2 for values from ('20230601') to ('20230701') PARTITION BY range (in_d);
+
+create table in_p_m202307 partition of in_p_q3 for values from ('20230701') to ('20230801') PARTITION BY range (in_d);
+create table in_p_m202308 partition of in_p_q3 for values from ('20230801') to ('20230901') PARTITION BY range (in_d);
+create table in_p_m202309 partition of in_p_q3 for values from ('20230901') to ('20231001') PARTITION BY range (in_d);
+
+create table in_p_m202310 partition of in_p_q4 for values from ('20231001') to ('20231101') PARTITION BY range (in_d); 
+create table in_p_m202311 partition of in_p_q4 for values from ('20231101') to ('20231201') PARTITION BY range (in_d);
+create table in_p_m202312 partition of in_p_q4 for values from ('20231201') to ('20240101') PARTITION BY range (in_d);
+
+create table in_p_w202301 partition of in_p_m202301 for values from ('20230101') to ('20230108') ;
+create table in_p_w202302 partition of in_p_m202301 for values from ('20230108') to ('20230115') ;
+create table in_p_w202303 partition of in_p_m202301 for values from ('20230115') to ('20230122') ;
+create table in_p_w202304 partition of in_p_m202301 for values from ('20230122') to ('20230129') ;
+create table in_p_w202305 partition of in_p_m202301 for values from ('20230129') to ('20230201') ;
+
+-- Test partition indentation
+\d+ p_quarter_check
+\d+ in_p_q1
+\d+ in_p_m202301
+\d+ in_p_w202301
+
