mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-06 21:49:19 +02:00
Fix infelicities in describeOneTableDetails' partitioned-table handling.
describeOneTableDetails issued a partition-constraint-fetching query for every table, even ones it knows perfectly well are not partitions. To add insult to injury, it then proceeded to leak the empty PGresult if the table wasn't a partition. Doing that a lot of times might amount to a meaningful leak, so this seems like a back-patchable bug. Fix that, and also fix a related PGresult leak in the partition-parent case (though that leak would occur only if we got no row, which is unexpected). Minor code beautification too, to make this code look more like the pre-existing code around it. Back-patch the whole change into v12. However, the fact that we already know whether the table is a partition dates only to commit 1af25ca0c; back-patching the relevant changes from that is probably more churn than is justified in released branches. Hence, in v11 and v10, just do the minimum to fix the PGresult leaks. Noted while messing around with adjacent code for yesterday's \d improvements.
This commit is contained in:
parent
fb5344c969
commit
d16e514bef
@ -2102,37 +2102,32 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make footers */
|
/* Make footers */
|
||||||
if (pset.sversion >= 100000)
|
|
||||||
|
if (tableinfo.ispartition)
|
||||||
{
|
{
|
||||||
/* Get the partition information */
|
/* Footer information for a partition child table */
|
||||||
PGresult *result;
|
PGresult *result;
|
||||||
char *parent_name;
|
|
||||||
char *partdef;
|
|
||||||
char *partconstraintdef = NULL;
|
|
||||||
|
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT inhparent::pg_catalog.regclass,\n"
|
"SELECT inhparent::pg_catalog.regclass,\n"
|
||||||
" pg_catalog.pg_get_expr(c.relpartbound, inhrelid)");
|
" pg_catalog.pg_get_expr(c.relpartbound, c.oid)");
|
||||||
/* If verbose, also request the partition constraint definition */
|
/* If verbose, also request the partition constraint definition */
|
||||||
if (verbose)
|
if (verbose)
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBufferStr(&buf,
|
||||||
",\n pg_catalog.pg_get_partition_constraintdef(inhrelid)");
|
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
"\nFROM pg_catalog.pg_class c"
|
"\nFROM pg_catalog.pg_class c"
|
||||||
" JOIN pg_catalog.pg_inherits i"
|
" JOIN pg_catalog.pg_inherits i"
|
||||||
" ON c.oid = inhrelid"
|
" ON c.oid = inhrelid"
|
||||||
"\nWHERE c.oid = '%s' AND c.relispartition;", oid);
|
"\nWHERE c.oid = '%s';", oid);
|
||||||
result = PSQLexec(buf.data);
|
result = PSQLexec(buf.data);
|
||||||
if (!result)
|
if (!result)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
if (PQntuples(result) > 0)
|
if (PQntuples(result) > 0)
|
||||||
{
|
{
|
||||||
parent_name = PQgetvalue(result, 0, 0);
|
char *parent_name = PQgetvalue(result, 0, 0);
|
||||||
partdef = PQgetvalue(result, 0, 1);
|
char *partdef = PQgetvalue(result, 0, 1);
|
||||||
|
|
||||||
if (PQnfields(result) == 3 && !PQgetisnull(result, 0, 2))
|
|
||||||
partconstraintdef = PQgetvalue(result, 0, 2);
|
|
||||||
|
|
||||||
printfPQExpBuffer(&tmpbuf, _("Partition of: %s %s"), parent_name,
|
printfPQExpBuffer(&tmpbuf, _("Partition of: %s %s"), parent_name,
|
||||||
partdef);
|
partdef);
|
||||||
@ -2140,6 +2135,10 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
|
char *partconstraintdef = NULL;
|
||||||
|
|
||||||
|
if (!PQgetisnull(result, 0, 2))
|
||||||
|
partconstraintdef = PQgetvalue(result, 0, 2);
|
||||||
/* If there isn't any constraint, show that explicitly */
|
/* If there isn't any constraint, show that explicitly */
|
||||||
if (partconstraintdef == NULL || partconstraintdef[0] == '\0')
|
if (partconstraintdef == NULL || partconstraintdef[0] == '\0')
|
||||||
printfPQExpBuffer(&tmpbuf, _("No partition constraint"));
|
printfPQExpBuffer(&tmpbuf, _("No partition constraint"));
|
||||||
@ -2148,27 +2147,29 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
partconstraintdef);
|
partconstraintdef);
|
||||||
printTableAddFooter(&cont, tmpbuf.data);
|
printTableAddFooter(&cont, tmpbuf.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
PQclear(result);
|
|
||||||
}
|
}
|
||||||
|
PQclear(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
|
if (tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
|
||||||
{
|
{
|
||||||
/* Get the partition key information */
|
/* Footer information for a partitioned table (partitioning parent) */
|
||||||
PGresult *result;
|
PGresult *result;
|
||||||
char *partkeydef;
|
|
||||||
|
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT pg_catalog.pg_get_partkeydef('%s'::pg_catalog.oid);",
|
"SELECT pg_catalog.pg_get_partkeydef('%s'::pg_catalog.oid);",
|
||||||
oid);
|
oid);
|
||||||
result = PSQLexec(buf.data);
|
result = PSQLexec(buf.data);
|
||||||
if (!result || PQntuples(result) != 1)
|
if (!result)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
partkeydef = PQgetvalue(result, 0, 0);
|
if (PQntuples(result) == 1)
|
||||||
|
{
|
||||||
|
char *partkeydef = PQgetvalue(result, 0, 0);
|
||||||
|
|
||||||
printfPQExpBuffer(&tmpbuf, _("Partition key: %s"), partkeydef);
|
printfPQExpBuffer(&tmpbuf, _("Partition key: %s"), partkeydef);
|
||||||
printTableAddFooter(&cont, tmpbuf.data);
|
printTableAddFooter(&cont, tmpbuf.data);
|
||||||
|
}
|
||||||
PQclear(result);
|
PQclear(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user