January 9, 2020·4 min read·engineeringpostgresqlpgadminpartitioning

pgAdmin 4.17 fixes browsing of multilevel partitions

pgAdmin 4.17 makes multilevel partitioned tables visible in its browser. The change matters because a PostgreSQL partition can itself be a partitioned table with children of its own.

A partition can also be a partitioned table. PostgreSQL supports that hierarchy, but a graphical browser needs to follow the relationship through every level to show the database accurately. A tool that presents a partition only as a terminal child leaves out the objects beneath it. That is a problem when the hierarchy determines where rows go and which objects an administrator needs to inspect.

pgAdmin 4.17, announced on January 9, adds support for viewing multilevel partitioned tables. Its versioned release notes identify the change as issue 4633. Other partition-related fixes in the same release concern creating objects on partitions and selecting tablespaces for partitioned tables on PostgreSQL 12. These changes improve how the administration tool represents capabilities already available in the database.

I default to PostgreSQL for relational systems because its behavior is usually inspectable and its exceptions are documented. The same standard applies to the tools around it. A graphical representation of a schema should preserve the relationships that matter when reading its SQL definition.

Why a partition has children

The PostgreSQL 12.1 partitioning documentation describes declarative partitioning and subpartitioning. A partitioned table defines a partitioning method and key. PostgreSQL routes inserted rows to a partition according to that key and the partition bounds. An individual partition can repeat the arrangement with a further partitioning declaration.

For example, a table can group measurements by month and subdivide a particular month by temperature. This compact example follows the documented range-partitioning syntax:

CREATE TABLE measurements (
    recorded_on date NOT NULL,
    temperature integer NOT NULL
) PARTITION BY RANGE (recorded_on);

CREATE TABLE measurements_january PARTITION OF measurements
    FOR VALUES FROM ('2020-01-01') TO ('2020-02-01')
    PARTITION BY RANGE (temperature);

CREATE TABLE measurements_january_cold
    PARTITION OF measurements_january
    FOR VALUES FROM (MINVALUE) TO (0);

CREATE TABLE measurements_january_warm
    PARTITION OF measurements_january
    FOR VALUES FROM (0) TO (MAXVALUE);

measurements_january has two roles. It is a partition of measurements, and it is the partitioned parent of the two temperature partitions. An insert for January first follows the date range, then the temperature range. A temperature of zero belongs to the second temperature partition because a range's upper bound is exclusive and its lower bound is inclusive.

This is an illustrative schema, not a proposed temperature classification or a performance recommendation. Its purpose is to expose the intermediate table's dual role. A browser that can expand the top-level table but cannot continue through that intermediate partition fails to represent the complete hierarchy.

The distinction also affects maintenance. PostgreSQL permits attaching an existing table as a partition and detaching a partition into a standalone table. A partition can have its own indexes and constraints. Those operations depend on knowing which table owns the relationship being changed, so visibility of the intermediate level has operational value.

The browser follows the partition again

The January 6 implementation of issue 4633 changes how pgAdmin collects child nodes for partitions. It extracts a get_children_nodes method in the browser infrastructure and provides a partition-specific implementation. When a partition identifier is present, that implementation uses it as the table identifier for collecting children.

After collecting the normal child modules, the partition implementation also asks its own partition module for nodes. This additional traversal lets the browser discover partitions beneath a partition. The code retains backend-support checks, so child discovery still depends on the connected server's supported capabilities. The correction addresses the shape of the browser's traversal without changing PostgreSQL's storage or row-routing behavior.

That is a useful example of a management-tool compatibility problem. SQL support in the database does not automatically produce correct navigation in a client. The client has its own object model, including identifiers and child-node discovery. Supporting subpartitioning requires that model to recognize that a partition can lead to another collection of partitions.

The same commit extends the partition collection's displayed fields to include the default-partition flag and hash modulus and remainder. It also expands the explanatory text for creating, attaching, and detaching partitions. These are related interface changes, but the multilevel traversal is the part that corrects the missing structural relationship.

Visibility and execution remain separate

The release notes list issue 4842 as a fix for creating constraints, indexes, rules, and triggers on partitions. Issue 4950 allows selecting or modifying the tablespace for a partitioned table on PostgreSQL 12 and later. Neither description should be read as a change to the server's rules about which objects a partitioned parent can own. pgAdmin must generate SQL that the connected PostgreSQL version accepts.

PostgreSQL's documentation already explains why that distinction matters for indexes. Creating an index on a partitioned table automatically creates corresponding indexes on its partitions. The logical parent and its children participate in the operation, even though they have different responsibilities. An administration interface needs to preserve those distinctions when it displays existing objects and when it offers a creation action.

I value these fixes because they make an established PostgreSQL design easier to inspect through a second interface. They do not require treating every table as a candidate for partitioning. The documentation identifies costs in planning time and metadata memory as partition counts grow, especially when queries cannot prune most partitions. Subpartitioning adds objects that the operator and the query planner both need to understand.

For an existing multilevel schema, pgAdmin 4.17 closes a specific gap between the database structure and the browser tree. Its implementation follows the intermediate partition as a table and then discovers its partitions. That gives an administrator access to the next level of the hierarchy while leaving the database's partition definitions and routing rules in charge of the data.