aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/describe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/psql/describe.c')
-rw-r--r--src/bin/psql/describe.c504
1 files changed, 336 insertions, 168 deletions
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 583817b0cc6..4369f2235b4 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -46,6 +46,12 @@ static bool describeOneTSConfig(const char *oid, const char *nspname,
const char *pnspname, const char *prsname);
static void printACLColumn(PQExpBuffer buf, const char *colname);
static bool listOneExtensionContents(const char *extname, const char *oid);
+static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern,
+ bool have_where, bool force_escape,
+ const char *schemavar, const char *namevar,
+ const char *altnamevar,
+ const char *visibilityrule,
+ bool *added_clause, int maxparts);
/*----------------
@@ -102,9 +108,11 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "p.proname", NULL,
- "pg_catalog.pg_function_is_visible(p.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "p.proname", NULL,
+ "pg_catalog.pg_function_is_visible(p.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
@@ -170,9 +178,11 @@ describeAccessMethods(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_am\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "amname", NULL,
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "amname", NULL,
+ NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -230,9 +240,11 @@ describeTablespaces(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_tablespace\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "spcname", NULL,
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "spcname", NULL,
+ NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -518,9 +530,11 @@ describeFunctions(const char *functypes, const char *func_pattern,
appendPQExpBufferStr(&buf, " )\n");
}
- processSQLNamePattern(pset.db, &buf, func_pattern, have_where, false,
- "n.nspname", "p.proname", NULL,
- "pg_catalog.pg_function_is_visible(p.oid)");
+ if (!validateSQLNamePattern(&buf, func_pattern, have_where, false,
+ "n.nspname", "p.proname", NULL,
+ "pg_catalog.pg_function_is_visible(p.oid)",
+ NULL, 3))
+ return false;
for (int i = 0; i < num_arg_patterns; i++)
{
@@ -542,10 +556,12 @@ describeFunctions(const char *functypes, const char *func_pattern,
"pg_catalog.format_type(t%d.oid, NULL)", i);
snprintf(tiv, sizeof(tiv),
"pg_catalog.pg_type_is_visible(t%d.oid)", i);
- processSQLNamePattern(pset.db, &buf,
- map_typename_pattern(arg_patterns[i]),
- true, false,
- nspname, typname, ft, tiv);
+ if (!validateSQLNamePattern(&buf,
+ map_typename_pattern(arg_patterns[i]),
+ true, false,
+ nspname, typname, ft, tiv,
+ NULL, 3))
+ return false;
}
else
{
@@ -660,11 +676,13 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" AND n.nspname <> 'information_schema'\n");
/* Match name pattern against either internal or external name */
- processSQLNamePattern(pset.db, &buf, map_typename_pattern(pattern),
- true, false,
- "n.nspname", "t.typname",
- "pg_catalog.format_type(t.oid, NULL)",
- "pg_catalog.pg_type_is_visible(t.oid)");
+ if (!validateSQLNamePattern(&buf, map_typename_pattern(pattern),
+ true, false,
+ "n.nspname", "t.typname",
+ "pg_catalog.format_type(t.oid, NULL)",
+ "pg_catalog.pg_type_is_visible(t.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -813,10 +831,12 @@ describeOperators(const char *oper_pattern,
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, oper_pattern,
- !showSystem && !oper_pattern, true,
- "n.nspname", "o.oprname", NULL,
- "pg_catalog.pg_operator_is_visible(o.oid)");
+ if (!validateSQLNamePattern(&buf, oper_pattern,
+ !showSystem && !oper_pattern, true,
+ "n.nspname", "o.oprname", NULL,
+ "pg_catalog.pg_operator_is_visible(o.oid)",
+ NULL, 3))
+ return false;
if (num_arg_patterns == 1)
appendPQExpBufferStr(&buf, " AND o.oprleft = 0\n");
@@ -841,10 +861,12 @@ describeOperators(const char *oper_pattern,
"pg_catalog.format_type(t%d.oid, NULL)", i);
snprintf(tiv, sizeof(tiv),
"pg_catalog.pg_type_is_visible(t%d.oid)", i);
- processSQLNamePattern(pset.db, &buf,
- map_typename_pattern(arg_patterns[i]),
- true, false,
- nspname, typname, ft, tiv);
+ if (!validateSQLNamePattern(&buf,
+ map_typename_pattern(arg_patterns[i]),
+ true, false,
+ nspname, typname, ft, tiv,
+ NULL, 3))
+ return false;
}
else
{
@@ -928,8 +950,10 @@ listAllDbs(const char *pattern, bool verbose)
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
if (pattern)
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "d.datname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "d.datname", NULL, NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
res = PSQLexec(buf.data);
@@ -1078,9 +1102,11 @@ permissionsList(const char *pattern)
* point of view. You can see 'em by explicit request though, eg with \z
* pg_catalog.*
*/
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "c.relname", NULL,
- "n.nspname !~ '^pg_' AND pg_catalog.pg_table_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "c.relname", NULL,
+ "n.nspname !~ '^pg_' AND pg_catalog.pg_table_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -1145,11 +1171,13 @@ listDefaultACLs(const char *pattern)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_default_acl d\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL,
- "n.nspname",
- "pg_catalog.pg_get_userbyid(d.defaclrole)",
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL,
+ "n.nspname",
+ "pg_catalog.pg_get_userbyid(d.defaclrole)",
+ NULL,
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
@@ -1221,9 +1249,11 @@ objectDescription(const char *pattern, bool showSystem)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern,
- false, "n.nspname", "pgc.conname", NULL,
- "pg_catalog.pg_table_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern,
+ false, "n.nspname", "pgc.conname", NULL,
+ "pg_catalog.pg_table_is_visible(c.oid)",
+ NULL, 3))
+ return false;
/* Domain constraint descriptions */
appendPQExpBuffer(&buf,
@@ -1243,9 +1273,11 @@ objectDescription(const char *pattern, bool showSystem)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern,
- false, "n.nspname", "pgc.conname", NULL,
- "pg_catalog.pg_type_is_visible(t.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern,
+ false, "n.nspname", "pgc.conname", NULL,
+ "pg_catalog.pg_type_is_visible(t.oid)",
+ NULL, 3))
+ return false;
/* Operator class descriptions */
appendPQExpBuffer(&buf,
@@ -1265,9 +1297,11 @@ objectDescription(const char *pattern, bool showSystem)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "o.opcname", NULL,
- "pg_catalog.pg_opclass_is_visible(o.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "o.opcname", NULL,
+ "pg_catalog.pg_opclass_is_visible(o.oid)",
+ NULL, 3))
+ return false;
/* Operator family descriptions */
appendPQExpBuffer(&buf,
@@ -1287,9 +1321,11 @@ objectDescription(const char *pattern, bool showSystem)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "opf.opfname", NULL,
- "pg_catalog.pg_opfamily_is_visible(opf.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "opf.opfname", NULL,
+ "pg_catalog.pg_opfamily_is_visible(opf.oid)",
+ NULL, 3))
+ return false;
/* Rule descriptions (ignore rules for views) */
appendPQExpBuffer(&buf,
@@ -1308,9 +1344,11 @@ objectDescription(const char *pattern, bool showSystem)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "r.rulename", NULL,
- "pg_catalog.pg_table_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "r.rulename", NULL,
+ "pg_catalog.pg_table_is_visible(c.oid)",
+ NULL, 3))
+ return false;
/* Trigger descriptions */
appendPQExpBuffer(&buf,
@@ -1328,9 +1366,11 @@ objectDescription(const char *pattern, bool showSystem)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern, false,
- "n.nspname", "t.tgname", NULL,
- "pg_catalog.pg_table_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern, false,
+ "n.nspname", "t.tgname", NULL,
+ "pg_catalog.pg_table_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf,
") AS tt\n"
@@ -1384,9 +1424,11 @@ describeTableDetails(const char *pattern, bool verbose, bool showSystem)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern, false,
- "n.nspname", "c.relname", NULL,
- "pg_catalog.pg_table_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern, false,
+ "n.nspname", "c.relname", NULL,
+ "pg_catalog.pg_table_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 2, 3;");
@@ -3572,8 +3614,10 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE r.rolname !~ '^pg_'\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "r.rolname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "r.rolname", NULL, NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -3696,10 +3740,13 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
gettext_noop("Role"),
gettext_noop("Database"),
gettext_noop("Settings"));
- havewhere = processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "r.rolname", NULL, NULL);
- processSQLNamePattern(pset.db, &buf, pattern2, havewhere, false,
- NULL, "d.datname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "r.rolname", NULL, NULL, &havewhere, 1))
+ return false;
+ if (!validateSQLNamePattern(&buf, pattern2, havewhere, false,
+ NULL, "d.datname", NULL, NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
res = PSQLexec(buf.data);
@@ -3892,9 +3939,11 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
" AND n.nspname !~ '^pg_toast'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "c.relname", NULL,
- "pg_catalog.pg_table_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "c.relname", NULL,
+ "pg_catalog.pg_table_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1,2;");
@@ -4107,9 +4156,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
" AND n.nspname !~ '^pg_toast'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "c.relname", NULL,
- "pg_catalog.pg_table_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "c.relname", NULL,
+ "pg_catalog.pg_table_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBuffer(&buf, "ORDER BY \"Schema\", %s%s\"Name\";",
mixed_output ? "\"Type\" DESC, " : "",
@@ -4182,8 +4233,10 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Description"));
if (pattern)
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "l.lanname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "l.lanname", NULL, NULL,
+ NULL, 2))
+ return false;
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE l.lanplcallfoid != 0\n");
@@ -4265,9 +4318,11 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "t.typname", NULL,
- "pg_catalog.pg_type_is_visible(t.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "t.typname", NULL,
+ "pg_catalog.pg_type_is_visible(t.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -4339,9 +4394,11 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
" AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "c.conname", NULL,
- "pg_catalog.pg_conversion_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "c.conname", NULL,
+ "pg_catalog.pg_conversion_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -4406,7 +4463,7 @@ describeConfigurationParameters(const char *pattern, bool verbose,
processSQLNamePattern(pset.db, &buf, pattern,
false, false,
NULL, "pg_catalog.lower(s.name)", NULL,
- NULL);
+ NULL, NULL, NULL);
else
appendPQExpBufferStr(&buf, "WHERE s.source <> 'default' AND\n"
" s.setting IS DISTINCT FROM s.boot_val\n");
@@ -4485,8 +4542,10 @@ listEventTriggers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_event_trigger e ");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "evtname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "evtname", NULL, NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1");
@@ -4577,10 +4636,12 @@ listExtendedStats(const char *pattern)
appendPQExpBufferStr(&buf,
" \nFROM pg_catalog.pg_statistic_ext es \n");
- processSQLNamePattern(pset.db, &buf, pattern,
- false, false,
- "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text", "es.stxname",
- NULL, "pg_catalog.pg_statistics_obj_is_visible(es.oid)");
+ if (!validateSQLNamePattern(&buf, pattern,
+ false, false,
+ "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text", "es.stxname",
+ NULL, "pg_catalog.pg_statistics_obj_is_visible(es.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -4679,17 +4740,21 @@ listCasts(const char *pattern, bool verbose)
* Match name pattern against either internal or external name of either
* castsource or casttarget
*/
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "ns.nspname", "ts.typname",
- "pg_catalog.format_type(ts.oid, NULL)",
- "pg_catalog.pg_type_is_visible(ts.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "ns.nspname", "ts.typname",
+ "pg_catalog.format_type(ts.oid, NULL)",
+ "pg_catalog.pg_type_is_visible(ts.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, ") OR (true");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "nt.nspname", "tt.typname",
- "pg_catalog.format_type(tt.oid, NULL)",
- "pg_catalog.pg_type_is_visible(tt.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "nt.nspname", "tt.typname",
+ "pg_catalog.format_type(tt.oid, NULL)",
+ "pg_catalog.pg_type_is_visible(tt.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;");
@@ -4785,9 +4850,11 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
*/
appendPQExpBufferStr(&buf, " AND c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding()))\n");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "c.collname", NULL,
- "pg_catalog.pg_collation_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "c.collname", NULL,
+ "pg_catalog.pg_collation_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -4845,10 +4912,12 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBufferStr(&buf,
"WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'\n");
- processSQLNamePattern(pset.db, &buf, pattern,
- !showSystem && !pattern, false,
- NULL, "n.nspname", NULL,
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern,
+ !showSystem && !pattern, false,
+ NULL, "n.nspname", NULL,
+ NULL,
+ NULL, 2))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -4959,9 +5028,11 @@ listTSParsers(const char *pattern, bool verbose)
gettext_noop("Description")
);
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- "n.nspname", "p.prsname", NULL,
- "pg_catalog.pg_ts_parser_is_visible(p.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ "n.nspname", "p.prsname", NULL,
+ "pg_catalog.pg_ts_parser_is_visible(p.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -5000,9 +5071,11 @@ listTSParsersVerbose(const char *pattern)
"LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.prsnamespace\n"
);
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- "n.nspname", "p.prsname", NULL,
- "pg_catalog.pg_ts_parser_is_visible(p.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ "n.nspname", "p.prsname", NULL,
+ "pg_catalog.pg_ts_parser_is_visible(p.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -5207,9 +5280,11 @@ listTSDictionaries(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_ts_dict d\n"
"LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.dictnamespace\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- "n.nspname", "d.dictname", NULL,
- "pg_catalog.pg_ts_dict_is_visible(d.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ "n.nspname", "d.dictname", NULL,
+ "pg_catalog.pg_ts_dict_is_visible(d.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -5268,9 +5343,11 @@ listTSTemplates(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_ts_template t\n"
"LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.tmplnamespace\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- "n.nspname", "t.tmplname", NULL,
- "pg_catalog.pg_ts_template_is_visible(t.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ "n.nspname", "t.tmplname", NULL,
+ "pg_catalog.pg_ts_template_is_visible(t.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -5318,9 +5395,11 @@ listTSConfigs(const char *pattern, bool verbose)
gettext_noop("Description")
);
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- "n.nspname", "c.cfgname", NULL,
- "pg_catalog.pg_ts_config_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ "n.nspname", "c.cfgname", NULL,
+ "pg_catalog.pg_ts_config_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -5360,9 +5439,11 @@ listTSConfigsVerbose(const char *pattern)
"WHERE p.oid = c.cfgparser\n"
);
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- "n.nspname", "c.cfgname", NULL,
- "pg_catalog.pg_ts_config_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ "n.nspname", "c.cfgname", NULL,
+ "pg_catalog.pg_ts_config_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 3, 2;");
@@ -5532,8 +5613,10 @@ listForeignDataWrappers(const char *pattern, bool verbose)
" ON d.classoid = fdw.tableoid "
"AND d.objoid = fdw.oid AND d.objsubid = 0\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "fdwname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "fdwname", NULL, NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -5604,8 +5687,10 @@ listForeignServers(const char *pattern, bool verbose)
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
"AND d.objsubid = 0\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "s.srvname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "s.srvname", NULL, NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -5655,8 +5740,10 @@ listUserMappings(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_user_mappings um\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "um.srvname", "um.usename", NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "um.srvname", "um.usename", NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -5722,9 +5809,11 @@ listForeignTables(const char *pattern, bool verbose)
" ON d.classoid = c.tableoid AND "
"d.objoid = c.oid AND d.objsubid = 0\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- "n.nspname", "c.relname", NULL,
- "pg_catalog.pg_table_is_visible(c.oid)");
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ "n.nspname", "c.relname", NULL,
+ "pg_catalog.pg_table_is_visible(c.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
@@ -5768,10 +5857,12 @@ listExtensions(const char *pattern)
gettext_noop("Schema"),
gettext_noop("Description"));
- processSQLNamePattern(pset.db, &buf, pattern,
- false, false,
- NULL, "e.extname", NULL,
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern,
+ false, false,
+ NULL, "e.extname", NULL,
+ NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -5807,10 +5898,12 @@ listExtensionContents(const char *pattern)
"SELECT e.extname, e.oid\n"
"FROM pg_catalog.pg_extension e\n");
- processSQLNamePattern(pset.db, &buf, pattern,
- false, false,
- NULL, "e.extname", NULL,
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern,
+ false, false,
+ NULL, "e.extname", NULL,
+ NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -5893,6 +5986,59 @@ listOneExtensionContents(const char *extname, const char *oid)
}
/*
+ * validateSQLNamePattern
+ *
+ * Wrapper around string_utils's processSQLNamePattern which also checks the
+ * pattern's validity. In addition to that function's parameters, takes a
+ * 'maxparts' parameter specifying the maximum number of dotted names the
+ * pattern is allowed to have, and a 'added_clause' parameter that returns by
+ * reference whether a clause was added to 'buf'. Returns whether the pattern
+ * passed validation, after logging any errors.
+ */
+static bool
+validateSQLNamePattern(PQExpBuffer buf, const char *pattern, bool have_where,
+ bool force_escape, const char *schemavar,
+ const char *namevar, const char *altnamevar,
+ const char *visibilityrule, bool *added_clause,
+ int maxparts)
+{
+ PQExpBufferData dbbuf;
+ int dotcnt;
+ bool added;
+
+ initPQExpBuffer(&dbbuf);
+ added = processSQLNamePattern(pset.db, buf, pattern, have_where, force_escape,
+ schemavar, namevar, altnamevar,
+ visibilityrule, &dbbuf, &dotcnt);
+ if (added_clause != NULL)
+ *added_clause = added;
+
+ if (dotcnt >= maxparts)
+ {
+ pg_log_error("improper qualified name (too many dotted names): %s",
+ pattern);
+ termPQExpBuffer(&dbbuf);
+ return false;
+ }
+
+ if (maxparts > 1 && dotcnt == maxparts-1)
+ {
+ if (PQdb(pset.db) == NULL)
+ {
+ pg_log_error("You are currently not connected to a database.");
+ return false;
+ }
+ if (strcmp(PQdb(pset.db), dbbuf.data) != 0)
+ {
+ pg_log_error("cross-database references are not implemented: %s",
+ pattern);
+ return false;
+ }
+ }
+ return true;
+}
+
+/*
* \dRp
* Lists publications.
*
@@ -5943,9 +6089,11 @@ listPublications(const char *pattern)
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_publication\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "pubname", NULL,
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "pubname", NULL,
+ NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -6056,9 +6204,11 @@ describePublications(const char *pattern)
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_publication\n");
- processSQLNamePattern(pset.db, &buf, pattern, false, false,
- NULL, "pubname", NULL,
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern, false, false,
+ NULL, "pubname", NULL,
+ NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 2;");
@@ -6266,9 +6416,11 @@ describeSubscriptions(const char *pattern, bool verbose)
" FROM pg_catalog.pg_database\n"
" WHERE datname = pg_catalog.current_database())");
- processSQLNamePattern(pset.db, &buf, pattern, true, false,
- NULL, "subname", NULL,
- NULL);
+ if (!validateSQLNamePattern(&buf, pattern, true, false,
+ NULL, "subname", NULL,
+ NULL,
+ NULL, 1))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1;");
@@ -6369,15 +6521,19 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
if (access_method_pattern)
- have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern,
- false, false, NULL, "am.amname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, access_method_pattern,
+ false, false, NULL, "am.amname", NULL, NULL,
+ &have_where, 1))
+ return false;
if (type_pattern)
{
/* Match type name pattern against either internal or external name */
- processSQLNamePattern(pset.db, &buf, type_pattern, have_where, false,
- "tn.nspname", "t.typname",
- "pg_catalog.format_type(t.oid, NULL)",
- "pg_catalog.pg_type_is_visible(t.oid)");
+ if (!validateSQLNamePattern(&buf, type_pattern, have_where, false,
+ "tn.nspname", "t.typname",
+ "pg_catalog.format_type(t.oid, NULL)",
+ "pg_catalog.pg_type_is_visible(t.oid)",
+ NULL, 3))
+ return false;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
@@ -6441,8 +6597,10 @@ listOperatorFamilies(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = f.opfnamespace\n");
if (access_method_pattern)
- have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern,
- false, false, NULL, "am.amname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, access_method_pattern,
+ false, false, NULL, "am.amname", NULL, NULL,
+ &have_where, 1))
+ return false;
if (type_pattern)
{
appendPQExpBuffer(&buf,
@@ -6454,10 +6612,12 @@ listOperatorFamilies(const char *access_method_pattern,
" WHERE oc.opcfamily = f.oid\n",
have_where ? "AND" : "WHERE");
/* Match type name pattern against either internal or external name */
- processSQLNamePattern(pset.db, &buf, type_pattern, true, false,
- "tn.nspname", "t.typname",
- "pg_catalog.format_type(t.oid, NULL)",
- "pg_catalog.pg_type_is_visible(t.oid)");
+ if (!validateSQLNamePattern(&buf, type_pattern, true, false,
+ "tn.nspname", "t.typname",
+ "pg_catalog.format_type(t.oid, NULL)",
+ "pg_catalog.pg_type_is_visible(t.oid)",
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, " )\n");
}
@@ -6535,13 +6695,17 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
if (access_method_pattern)
- have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern,
- false, false, NULL, "am.amname",
- NULL, NULL);
+ if (!validateSQLNamePattern(&buf, access_method_pattern,
+ false, false, NULL, "am.amname",
+ NULL, NULL,
+ &have_where, 1))
+ return false;
if (family_pattern)
- processSQLNamePattern(pset.db, &buf, family_pattern, have_where, false,
- "nsf.nspname", "of.opfname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
+ "nsf.nspname", "of.opfname", NULL, NULL,
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
" o.amoplefttype = o.amoprighttype DESC,\n"
@@ -6619,12 +6783,16 @@ listOpFamilyFunctions(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n");
if (access_method_pattern)
- have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern,
- false, false, NULL, "am.amname",
- NULL, NULL);
+ if (!validateSQLNamePattern(&buf, access_method_pattern,
+ false, false, NULL, "am.amname",
+ NULL, NULL,
+ &have_where, 1))
+ return false;
if (family_pattern)
- processSQLNamePattern(pset.db, &buf, family_pattern, have_where, false,
- "ns.nspname", "of.opfname", NULL, NULL);
+ if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
+ "ns.nspname", "of.opfname", NULL, NULL,
+ NULL, 3))
+ return false;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
" ap.amproclefttype = ap.amprocrighttype DESC,\n"