Fix various memory leaks in psql's describe commands \d*

Most of these have been introduced in d2d3547 with the new pattern
validation logic, and would leak memory worth an amount of one
PQExpBuffer each time (as of 256 bytes at minimum, possibly more).

Most of the patch has been written by Tang Haiying, with a few tweaks
coming from Álvaro Herrera.

Reported-by: Tang Haiying
Author: Tang Haiying, Álvaro Herrera
Reviewed-by: Mark Dilger, Andres Freund, Álvaro Herrera, Tom Lane, Japin
Li, Michael Paquier, Junwang Zhao
Backpatch-through: 15
This commit is contained in:
Michael Paquier 2022-07-21 10:42:07 +09:00
parent 2103266a36
commit eac3e00f81

View File

@ -112,7 +112,10 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
"n.nspname", "p.proname", NULL, "n.nspname", "p.proname", NULL,
"pg_catalog.pg_function_is_visible(p.oid)", "pg_catalog.pg_function_is_visible(p.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
@ -182,7 +185,10 @@ describeAccessMethods(const char *pattern, bool verbose)
NULL, "amname", NULL, NULL, "amname", NULL,
NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -244,7 +250,10 @@ describeTablespaces(const char *pattern, bool verbose)
NULL, "spcname", NULL, NULL, "spcname", NULL,
NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -534,7 +543,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
"n.nspname", "p.proname", NULL, "n.nspname", "p.proname", NULL,
"pg_catalog.pg_function_is_visible(p.oid)", "pg_catalog.pg_function_is_visible(p.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
for (int i = 0; i < num_arg_patterns; i++) for (int i = 0; i < num_arg_patterns; i++)
{ {
@ -561,7 +570,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
true, false, true, false,
nspname, typname, ft, tiv, nspname, typname, ft, tiv,
NULL, 3)) NULL, 3))
return false; goto error_return;
} }
else else
{ {
@ -599,6 +608,10 @@ describeFunctions(const char *functypes, const char *func_pattern,
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
@ -682,7 +695,10 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
"pg_catalog.format_type(t.oid, NULL)", "pg_catalog.format_type(t.oid, NULL)",
"pg_catalog.pg_type_is_visible(t.oid)", "pg_catalog.pg_type_is_visible(t.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -836,7 +852,7 @@ describeOperators(const char *oper_pattern,
"n.nspname", "o.oprname", NULL, "n.nspname", "o.oprname", NULL,
"pg_catalog.pg_operator_is_visible(o.oid)", "pg_catalog.pg_operator_is_visible(o.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
if (num_arg_patterns == 1) if (num_arg_patterns == 1)
appendPQExpBufferStr(&buf, " AND o.oprleft = 0\n"); appendPQExpBufferStr(&buf, " AND o.oprleft = 0\n");
@ -866,7 +882,7 @@ describeOperators(const char *oper_pattern,
true, false, true, false,
nspname, typname, ft, tiv, nspname, typname, ft, tiv,
NULL, 3)) NULL, 3))
return false; goto error_return;
} }
else else
{ {
@ -890,6 +906,10 @@ describeOperators(const char *oper_pattern,
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
@ -950,10 +970,15 @@ listAllDbs(const char *pattern, bool verbose)
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n"); " JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
if (pattern) if (pattern)
{
if (!validateSQLNamePattern(&buf, pattern, false, false, if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "d.datname", NULL, NULL, NULL, "d.datname", NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
res = PSQLexec(buf.data); res = PSQLexec(buf.data);
@ -1106,16 +1131,13 @@ permissionsList(const char *pattern)
"n.nspname", "c.relname", NULL, "n.nspname", "c.relname", NULL,
"n.nspname !~ '^pg_' AND pg_catalog.pg_table_is_visible(c.oid)", "n.nspname !~ '^pg_' AND pg_catalog.pg_table_is_visible(c.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
res = PSQLexec(buf.data); res = PSQLexec(buf.data);
if (!res) if (!res)
{ goto error_return;
termPQExpBuffer(&buf);
return false;
}
myopt.nullPrint = NULL; myopt.nullPrint = NULL;
printfPQExpBuffer(&buf, _("Access privileges")); printfPQExpBuffer(&buf, _("Access privileges"));
@ -1129,6 +1151,10 @@ permissionsList(const char *pattern)
termPQExpBuffer(&buf); termPQExpBuffer(&buf);
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
@ -1177,16 +1203,13 @@ listDefaultACLs(const char *pattern)
"pg_catalog.pg_get_userbyid(d.defaclrole)", "pg_catalog.pg_get_userbyid(d.defaclrole)",
NULL, NULL,
NULL, 3)) NULL, 3))
return false; goto error_return;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
res = PSQLexec(buf.data); res = PSQLexec(buf.data);
if (!res) if (!res)
{ goto error_return;
termPQExpBuffer(&buf);
return false;
}
myopt.nullPrint = NULL; myopt.nullPrint = NULL;
printfPQExpBuffer(&buf, _("Default access privileges")); printfPQExpBuffer(&buf, _("Default access privileges"));
@ -1200,6 +1223,10 @@ listDefaultACLs(const char *pattern)
termPQExpBuffer(&buf); termPQExpBuffer(&buf);
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
@ -1253,7 +1280,7 @@ objectDescription(const char *pattern, bool showSystem)
false, "n.nspname", "pgc.conname", NULL, false, "n.nspname", "pgc.conname", NULL,
"pg_catalog.pg_table_is_visible(c.oid)", "pg_catalog.pg_table_is_visible(c.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
/* Domain constraint descriptions */ /* Domain constraint descriptions */
appendPQExpBuffer(&buf, appendPQExpBuffer(&buf,
@ -1277,7 +1304,7 @@ objectDescription(const char *pattern, bool showSystem)
false, "n.nspname", "pgc.conname", NULL, false, "n.nspname", "pgc.conname", NULL,
"pg_catalog.pg_type_is_visible(t.oid)", "pg_catalog.pg_type_is_visible(t.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
/* Operator class descriptions */ /* Operator class descriptions */
appendPQExpBuffer(&buf, appendPQExpBuffer(&buf,
@ -1301,7 +1328,7 @@ objectDescription(const char *pattern, bool showSystem)
"n.nspname", "o.opcname", NULL, "n.nspname", "o.opcname", NULL,
"pg_catalog.pg_opclass_is_visible(o.oid)", "pg_catalog.pg_opclass_is_visible(o.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
/* Operator family descriptions */ /* Operator family descriptions */
appendPQExpBuffer(&buf, appendPQExpBuffer(&buf,
@ -1325,7 +1352,7 @@ objectDescription(const char *pattern, bool showSystem)
"n.nspname", "opf.opfname", NULL, "n.nspname", "opf.opfname", NULL,
"pg_catalog.pg_opfamily_is_visible(opf.oid)", "pg_catalog.pg_opfamily_is_visible(opf.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
/* Rule descriptions (ignore rules for views) */ /* Rule descriptions (ignore rules for views) */
appendPQExpBuffer(&buf, appendPQExpBuffer(&buf,
@ -1348,7 +1375,7 @@ objectDescription(const char *pattern, bool showSystem)
"n.nspname", "r.rulename", NULL, "n.nspname", "r.rulename", NULL,
"pg_catalog.pg_table_is_visible(c.oid)", "pg_catalog.pg_table_is_visible(c.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
/* Trigger descriptions */ /* Trigger descriptions */
appendPQExpBuffer(&buf, appendPQExpBuffer(&buf,
@ -1370,7 +1397,7 @@ objectDescription(const char *pattern, bool showSystem)
"n.nspname", "t.tgname", NULL, "n.nspname", "t.tgname", NULL,
"pg_catalog.pg_table_is_visible(c.oid)", "pg_catalog.pg_table_is_visible(c.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
appendPQExpBufferStr(&buf, appendPQExpBufferStr(&buf,
") AS tt\n" ") AS tt\n"
@ -1393,6 +1420,10 @@ objectDescription(const char *pattern, bool showSystem)
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
@ -1428,7 +1459,10 @@ describeTableDetails(const char *pattern, bool verbose, bool showSystem)
"n.nspname", "c.relname", NULL, "n.nspname", "c.relname", NULL,
"pg_catalog.pg_table_is_visible(c.oid)", "pg_catalog.pg_table_is_visible(c.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 2, 3;"); appendPQExpBufferStr(&buf, "ORDER BY 2, 3;");
@ -3617,7 +3651,10 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
if (!validateSQLNamePattern(&buf, pattern, false, false, if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "r.rolname", NULL, NULL, NULL, "r.rolname", NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -3742,11 +3779,11 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
gettext_noop("Settings")); gettext_noop("Settings"));
if (!validateSQLNamePattern(&buf, pattern, false, false, if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "r.rolname", NULL, NULL, &havewhere, 1)) NULL, "r.rolname", NULL, NULL, &havewhere, 1))
return false; goto error_return;
if (!validateSQLNamePattern(&buf, pattern2, havewhere, false, if (!validateSQLNamePattern(&buf, pattern2, havewhere, false,
NULL, "d.datname", NULL, NULL, NULL, "d.datname", NULL, NULL,
NULL, 1)) NULL, 1))
return false; goto error_return;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
res = PSQLexec(buf.data); res = PSQLexec(buf.data);
@ -3782,6 +3819,10 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
@ -3943,7 +3984,10 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
"n.nspname", "c.relname", NULL, "n.nspname", "c.relname", NULL,
"pg_catalog.pg_table_is_visible(c.oid)", "pg_catalog.pg_table_is_visible(c.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1,2;"); appendPQExpBufferStr(&buf, "ORDER BY 1,2;");
@ -4160,7 +4204,10 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
"n.nspname", "c.relname", NULL, "n.nspname", "c.relname", NULL,
"pg_catalog.pg_table_is_visible(c.oid)", "pg_catalog.pg_table_is_visible(c.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBuffer(&buf, "ORDER BY \"Schema\", %s%s\"Name\";", appendPQExpBuffer(&buf, "ORDER BY \"Schema\", %s%s\"Name\";",
mixed_output ? "\"Type\" DESC, " : "", mixed_output ? "\"Type\" DESC, " : "",
@ -4233,10 +4280,15 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Description")); gettext_noop("Description"));
if (pattern) if (pattern)
{
if (!validateSQLNamePattern(&buf, pattern, false, false, if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "l.lanname", NULL, NULL, NULL, "l.lanname", NULL, NULL,
NULL, 2)) NULL, 2))
{
termPQExpBuffer(&buf);
return false; return false;
}
}
if (!showSystem && !pattern) if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE l.lanplcallfoid != 0\n"); appendPQExpBufferStr(&buf, "WHERE l.lanplcallfoid != 0\n");
@ -4322,7 +4374,10 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"n.nspname", "t.typname", NULL, "n.nspname", "t.typname", NULL,
"pg_catalog.pg_type_is_visible(t.oid)", "pg_catalog.pg_type_is_visible(t.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -4398,7 +4453,10 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
"n.nspname", "c.conname", NULL, "n.nspname", "c.conname", NULL,
"pg_catalog.pg_conversion_is_visible(c.oid)", "pg_catalog.pg_conversion_is_visible(c.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -4545,7 +4603,10 @@ listEventTriggers(const char *pattern, bool verbose)
if (!validateSQLNamePattern(&buf, pattern, false, false, if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "evtname", NULL, NULL, NULL, "evtname", NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1"); appendPQExpBufferStr(&buf, "ORDER BY 1");
@ -4641,7 +4702,10 @@ listExtendedStats(const char *pattern)
"es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text", "es.stxname", "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text", "es.stxname",
NULL, "pg_catalog.pg_statistics_obj_is_visible(es.oid)", NULL, "pg_catalog.pg_statistics_obj_is_visible(es.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -4745,7 +4809,7 @@ listCasts(const char *pattern, bool verbose)
"pg_catalog.format_type(ts.oid, NULL)", "pg_catalog.format_type(ts.oid, NULL)",
"pg_catalog.pg_type_is_visible(ts.oid)", "pg_catalog.pg_type_is_visible(ts.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
appendPQExpBufferStr(&buf, ") OR (true"); appendPQExpBufferStr(&buf, ") OR (true");
@ -4754,7 +4818,7 @@ listCasts(const char *pattern, bool verbose)
"pg_catalog.format_type(tt.oid, NULL)", "pg_catalog.format_type(tt.oid, NULL)",
"pg_catalog.pg_type_is_visible(tt.oid)", "pg_catalog.pg_type_is_visible(tt.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;"); appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;");
@ -4773,6 +4837,10 @@ listCasts(const char *pattern, bool verbose)
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
/* /*
@ -4854,7 +4922,10 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
"n.nspname", "c.collname", NULL, "n.nspname", "c.collname", NULL,
"pg_catalog.pg_collation_is_visible(c.oid)", "pg_catalog.pg_collation_is_visible(c.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -4917,16 +4988,13 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
NULL, "n.nspname", NULL, NULL, "n.nspname", NULL,
NULL, NULL,
NULL, 2)) NULL, 2))
return false; goto error_return;
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
res = PSQLexec(buf.data); res = PSQLexec(buf.data);
if (!res) if (!res)
{ goto error_return;
termPQExpBuffer(&buf);
return false;
}
myopt.nullPrint = NULL; myopt.nullPrint = NULL;
myopt.title = _("List of schemas"); myopt.title = _("List of schemas");
@ -4947,10 +5015,7 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
pattern); pattern);
result = PSQLexec(buf.data); result = PSQLexec(buf.data);
if (!result) if (!result)
{ goto error_return;
termPQExpBuffer(&buf);
return false;
}
else else
pub_schema_tuples = PQntuples(result); pub_schema_tuples = PQntuples(result);
@ -4997,6 +5062,10 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
} }
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
@ -5032,7 +5101,10 @@ listTSParsers(const char *pattern, bool verbose)
"n.nspname", "p.prsname", NULL, "n.nspname", "p.prsname", NULL,
"pg_catalog.pg_ts_parser_is_visible(p.oid)", "pg_catalog.pg_ts_parser_is_visible(p.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -5075,7 +5147,10 @@ listTSParsersVerbose(const char *pattern)
"n.nspname", "p.prsname", NULL, "n.nspname", "p.prsname", NULL,
"pg_catalog.pg_ts_parser_is_visible(p.oid)", "pg_catalog.pg_ts_parser_is_visible(p.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -5218,7 +5293,10 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
res = PSQLexec(buf.data); res = PSQLexec(buf.data);
termPQExpBuffer(&buf); termPQExpBuffer(&buf);
if (!res) if (!res)
{
termPQExpBuffer(&title);
return false; return false;
}
myopt.nullPrint = NULL; myopt.nullPrint = NULL;
if (nspname) if (nspname)
@ -5284,7 +5362,10 @@ listTSDictionaries(const char *pattern, bool verbose)
"n.nspname", "d.dictname", NULL, "n.nspname", "d.dictname", NULL,
"pg_catalog.pg_ts_dict_is_visible(d.oid)", "pg_catalog.pg_ts_dict_is_visible(d.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -5347,7 +5428,10 @@ listTSTemplates(const char *pattern, bool verbose)
"n.nspname", "t.tmplname", NULL, "n.nspname", "t.tmplname", NULL,
"pg_catalog.pg_ts_template_is_visible(t.oid)", "pg_catalog.pg_ts_template_is_visible(t.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -5399,7 +5483,10 @@ listTSConfigs(const char *pattern, bool verbose)
"n.nspname", "c.cfgname", NULL, "n.nspname", "c.cfgname", NULL,
"pg_catalog.pg_ts_config_is_visible(c.oid)", "pg_catalog.pg_ts_config_is_visible(c.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -5443,7 +5530,10 @@ listTSConfigsVerbose(const char *pattern)
"n.nspname", "c.cfgname", NULL, "n.nspname", "c.cfgname", NULL,
"pg_catalog.pg_ts_config_is_visible(c.oid)", "pg_catalog.pg_ts_config_is_visible(c.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 3, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 3, 2;");
@ -5616,7 +5706,10 @@ listForeignDataWrappers(const char *pattern, bool verbose)
if (!validateSQLNamePattern(&buf, pattern, false, false, if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "fdwname", NULL, NULL, NULL, "fdwname", NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -5690,7 +5783,10 @@ listForeignServers(const char *pattern, bool verbose)
if (!validateSQLNamePattern(&buf, pattern, false, false, if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "s.srvname", NULL, NULL, NULL, "s.srvname", NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -5743,7 +5839,10 @@ listUserMappings(const char *pattern, bool verbose)
if (!validateSQLNamePattern(&buf, pattern, false, false, if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "um.srvname", "um.usename", NULL, NULL, "um.srvname", "um.usename", NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -5813,7 +5912,10 @@ listForeignTables(const char *pattern, bool verbose)
"n.nspname", "c.relname", NULL, "n.nspname", "c.relname", NULL,
"pg_catalog.pg_table_is_visible(c.oid)", "pg_catalog.pg_table_is_visible(c.oid)",
NULL, 3)) NULL, 3))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@ -5862,7 +5964,10 @@ listExtensions(const char *pattern)
NULL, "e.extname", NULL, NULL, "e.extname", NULL,
NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -5903,7 +6008,10 @@ listExtensionContents(const char *pattern)
NULL, "e.extname", NULL, NULL, "e.extname", NULL,
NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -6017,8 +6125,7 @@ validateSQLNamePattern(PQExpBuffer buf, const char *pattern, bool have_where,
{ {
pg_log_error("improper qualified name (too many dotted names): %s", pg_log_error("improper qualified name (too many dotted names): %s",
pattern); pattern);
termPQExpBuffer(&dbbuf); goto error_return;
return false;
} }
if (maxparts > 1 && dotcnt == maxparts - 1) if (maxparts > 1 && dotcnt == maxparts - 1)
@ -6026,16 +6133,21 @@ validateSQLNamePattern(PQExpBuffer buf, const char *pattern, bool have_where,
if (PQdb(pset.db) == NULL) if (PQdb(pset.db) == NULL)
{ {
pg_log_error("You are currently not connected to a database."); pg_log_error("You are currently not connected to a database.");
return false; goto error_return;
} }
if (strcmp(PQdb(pset.db), dbbuf.data) != 0) if (strcmp(PQdb(pset.db), dbbuf.data) != 0)
{ {
pg_log_error("cross-database references are not implemented: %s", pg_log_error("cross-database references are not implemented: %s",
pattern); pattern);
return false; goto error_return;
} }
} }
termPQExpBuffer(&dbbuf);
return true; return true;
error_return:
termPQExpBuffer(&dbbuf);
return false;
} }
/* /*
@ -6093,7 +6205,10 @@ listPublications(const char *pattern)
NULL, "pubname", NULL, NULL, "pubname", NULL,
NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -6208,7 +6323,10 @@ describePublications(const char *pattern)
NULL, "pubname", NULL, NULL, "pubname", NULL,
NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 2;"); appendPQExpBufferStr(&buf, "ORDER BY 2;");
@ -6420,7 +6538,10 @@ describeSubscriptions(const char *pattern, bool verbose)
NULL, "subname", NULL, NULL, "subname", NULL,
NULL, NULL,
NULL, 1)) NULL, 1))
{
termPQExpBuffer(&buf);
return false; return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1;"); appendPQExpBufferStr(&buf, "ORDER BY 1;");
@ -6524,7 +6645,7 @@ listOperatorClasses(const char *access_method_pattern,
if (!validateSQLNamePattern(&buf, access_method_pattern, if (!validateSQLNamePattern(&buf, access_method_pattern,
false, false, NULL, "am.amname", NULL, NULL, false, false, NULL, "am.amname", NULL, NULL,
&have_where, 1)) &have_where, 1))
return false; goto error_return;
if (type_pattern) if (type_pattern)
{ {
/* Match type name pattern against either internal or external name */ /* Match type name pattern against either internal or external name */
@ -6533,7 +6654,7 @@ listOperatorClasses(const char *access_method_pattern,
"pg_catalog.format_type(t.oid, NULL)", "pg_catalog.format_type(t.oid, NULL)",
"pg_catalog.pg_type_is_visible(t.oid)", "pg_catalog.pg_type_is_visible(t.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
} }
appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;"); appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
@ -6552,6 +6673,10 @@ listOperatorClasses(const char *access_method_pattern,
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
/* /*
@ -6600,7 +6725,7 @@ listOperatorFamilies(const char *access_method_pattern,
if (!validateSQLNamePattern(&buf, access_method_pattern, if (!validateSQLNamePattern(&buf, access_method_pattern,
false, false, NULL, "am.amname", NULL, NULL, false, false, NULL, "am.amname", NULL, NULL,
&have_where, 1)) &have_where, 1))
return false; goto error_return;
if (type_pattern) if (type_pattern)
{ {
appendPQExpBuffer(&buf, appendPQExpBuffer(&buf,
@ -6617,7 +6742,7 @@ listOperatorFamilies(const char *access_method_pattern,
"pg_catalog.format_type(t.oid, NULL)", "pg_catalog.format_type(t.oid, NULL)",
"pg_catalog.pg_type_is_visible(t.oid)", "pg_catalog.pg_type_is_visible(t.oid)",
NULL, 3)) NULL, 3))
return false; goto error_return;
appendPQExpBufferStr(&buf, " )\n"); appendPQExpBufferStr(&buf, " )\n");
} }
@ -6637,6 +6762,10 @@ listOperatorFamilies(const char *access_method_pattern,
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
/* /*
@ -6695,17 +6824,21 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n"); " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
if (access_method_pattern) if (access_method_pattern)
{
if (!validateSQLNamePattern(&buf, access_method_pattern, if (!validateSQLNamePattern(&buf, access_method_pattern,
false, false, NULL, "am.amname", false, false, NULL, "am.amname",
NULL, NULL, NULL, NULL,
&have_where, 1)) &have_where, 1))
return false; goto error_return;
}
if (family_pattern) if (family_pattern)
{
if (!validateSQLNamePattern(&buf, family_pattern, have_where, false, if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
"nsf.nspname", "of.opfname", NULL, NULL, "nsf.nspname", "of.opfname", NULL, NULL,
NULL, 3)) NULL, 3))
return false; goto error_return;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n" appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
" o.amoplefttype = o.amoprighttype DESC,\n" " o.amoplefttype = o.amoprighttype DESC,\n"
@ -6728,6 +6861,10 @@ listOpFamilyOperators(const char *access_method_pattern,
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
/* /*
@ -6783,16 +6920,20 @@ listOpFamilyFunctions(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n"); " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n");
if (access_method_pattern) if (access_method_pattern)
{
if (!validateSQLNamePattern(&buf, access_method_pattern, if (!validateSQLNamePattern(&buf, access_method_pattern,
false, false, NULL, "am.amname", false, false, NULL, "am.amname",
NULL, NULL, NULL, NULL,
&have_where, 1)) &have_where, 1))
return false; goto error_return;
}
if (family_pattern) if (family_pattern)
{
if (!validateSQLNamePattern(&buf, family_pattern, have_where, false, if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
"ns.nspname", "of.opfname", NULL, NULL, "ns.nspname", "of.opfname", NULL, NULL,
NULL, 3)) NULL, 3))
return false; goto error_return;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n" appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
" ap.amproclefttype = ap.amprocrighttype DESC,\n" " ap.amproclefttype = ap.amprocrighttype DESC,\n"
@ -6813,6 +6954,10 @@ listOpFamilyFunctions(const char *access_method_pattern,
PQclear(res); PQclear(res);
return true; return true;
error_return:
termPQExpBuffer(&buf);
return false;
} }
/* /*