subpartition_indentation.diff
application/octet-stream
Filename: subpartition_indentation.diff
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/bin/psql/describe.c | 99 | 31 |
| src/test/regress/expected/subpartition_indentation.out | 100 | 0 |
| src/test/regress/sql/subpartition_indentation.sql | 46 | 0 |
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
+