</para>
<para>
- A pattern that contains a dot (<literal>.</literal>) is interpreted as a schema
+ A relation pattern that contains a dot (<literal>.</literal>) is interpreted as a schema
name pattern followed by an object name pattern. For example,
<literal>\dt foo*.*bar*</literal> displays all tables whose table name
includes <literal>bar</literal> that are in schemas whose schema name
starts with <literal>foo</literal>. When no dot appears, then the pattern
matches only objects that are visible in the current schema search path.
Again, a dot within double quotes loses its special meaning and is matched
- literally.
+ literally. A relation pattern that contains two dots (<literal>.</literal>)
+ is interpreted as a database name followed by a schema name pattern followed
+ by an object name pattern. The database name portion will not be treated as
+ a pattern and must match the name of the currently connected database, else
+ an error will be raised.
+ </para>
+
+ <para>
+ A schema pattern that contains a dot (<literal>.</literal>) is interpreted
+ as a database name followed by a schema name pattern. For example,
+ <literal>\dn mydb.*foo*</literal> displays all schemas whose schema name
+ includes <literal>foo</literal>. The database name portion will not be
+ treated as a pattern and must match the name of the currently connected
+ database, else an error will be raised.
</para>
<para>
append_database_pattern(PatternInfoArray *pia, const char *pattern, int encoding)
{
PQExpBufferData buf;
+ int dotcnt;
PatternInfo *info = extend_pattern_info_array(pia);
initPQExpBuffer(&buf);
- patternToSQLRegex(encoding, NULL, NULL, &buf, pattern, false);
+ patternToSQLRegex(encoding, NULL, NULL, &buf, pattern, false, false,
+ &dotcnt);
+ if (dotcnt > 0)
+ {
+ pg_log_error("improper qualified name (too many dotted names): %s", pattern);
+ exit(2);
+ }
info->pattern = pattern;
info->db_regex = pstrdup(buf.data);
{
PQExpBufferData dbbuf;
PQExpBufferData nspbuf;
+ int dotcnt;
PatternInfo *info = extend_pattern_info_array(pia);
initPQExpBuffer(&dbbuf);
initPQExpBuffer(&nspbuf);
- patternToSQLRegex(encoding, NULL, &dbbuf, &nspbuf, pattern, false);
+ patternToSQLRegex(encoding, NULL, &dbbuf, &nspbuf, pattern, false, false,
+ &dotcnt);
+ if (dotcnt > 1)
+ {
+ pg_log_error("improper qualified name (too many dotted names): %s", pattern);
+ exit(2);
+ }
info->pattern = pattern;
if (dbbuf.data[0])
{
PQExpBufferData dbbuf;
PQExpBufferData nspbuf;
PQExpBufferData relbuf;
+ int dotcnt;
PatternInfo *info = extend_pattern_info_array(pia);
initPQExpBuffer(&dbbuf);
initPQExpBuffer(&nspbuf);
initPQExpBuffer(&relbuf);
- patternToSQLRegex(encoding, &dbbuf, &nspbuf, &relbuf, pattern, false);
+ patternToSQLRegex(encoding, &dbbuf, &nspbuf, &relbuf, pattern, false,
+ false, &dotcnt);
+ if (dotcnt > 2)
+ {
+ pg_log_error("improper relation name (too many dotted names): %s", pattern);
+ exit(2);
+ }
info->pattern = pattern;
if (dbbuf.data[0])
{
[qr/pg_amcheck: error: no heap tables to check matching "\."/],
'checking table pattern "."');
+# Check that a multipart database name is rejected
+$node->command_checks_all(
+ [ 'pg_amcheck', '-d', 'localhost.postgres' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper qualified name \(too many dotted names\): localhost\.postgres/
+ ],
+ 'multipart database patterns are rejected'
+);
+
+# Check that a three-part schema name is rejected
+$node->command_checks_all(
+ [ 'pg_amcheck', '-s', 'localhost.postgres.pg_catalog' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper qualified name \(too many dotted names\): localhost\.postgres\.pg_catalog/
+ ],
+ 'three part schema patterns are rejected'
+);
+
+# Check that a four-part table name is rejected
+$node->command_checks_all(
+ [ 'pg_amcheck', '-t', 'localhost.postgres.pg_catalog.pg_class' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper relation name \(too many dotted names\): localhost\.postgres\.pg_catalog\.pg_class/
+ ],
+ 'four part table patterns are rejected'
+);
+
+# Check that too many dotted names still draws an error under --no-strict-names
+# That flag means that it is ok for the object to be missing, not that it is ok
+# for the object name to be ungrammatical
+$node->command_checks_all(
+ [ 'pg_amcheck', '--no-strict-names', '-t', 'this.is.a.really.long.dotted.string' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper relation name \(too many dotted names\): this\.is\.a\.really\.long\.dotted\.string/
+ ],
+ 'ungrammatical table names still draw errors under --no-strict-names'
+);
+$node->command_checks_all(
+ [ 'pg_amcheck', '--no-strict-names', '-s', 'postgres.long.dotted.string' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper qualified name \(too many dotted names\): postgres\.long\.dotted\.string/
+ ],
+ 'ungrammatical schema names still draw errors under --no-strict-names'
+);
+$node->command_checks_all(
+ [ 'pg_amcheck', '--no-strict-names', '-d', 'postgres.long.dotted.string' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper qualified name \(too many dotted names\): postgres\.long\.dotted\.string/
+ ],
+ 'ungrammatical database names still draw errors under --no-strict-names'
+);
+
+# Likewise for exclusion patterns
+$node->command_checks_all(
+ [ 'pg_amcheck', '--no-strict-names', '-T', 'a.b.c.d' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper relation name \(too many dotted names\): a\.b\.c\.d/
+ ],
+ 'ungrammatical table exclusions still draw errors under --no-strict-names'
+);
+$node->command_checks_all(
+ [ 'pg_amcheck', '--no-strict-names', '-S', 'a.b.c' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper qualified name \(too many dotted names\): a\.b\.c/
+ ],
+ 'ungrammatical schema exclusions still draw errors under --no-strict-names'
+);
+$node->command_checks_all(
+ [ 'pg_amcheck', '--no-strict-names', '-D', 'a.b' ],
+ 2,
+ [qr/^$/],
+ [
+ qr/pg_amcheck: error: improper qualified name \(too many dotted names\): a\.b/
+ ],
+ 'ungrammatical database exclusions still draw errors under --no-strict-names'
+);
+
+
#########################################
# Test checking non-existent databases, schemas, tables, and indexes
'-d', 'no*such*database',
'-r', 'none.none',
'-r', 'none.none.none',
- '-r', 'this.is.a.really.long.dotted.string',
'-r', 'postgres.none.none',
- '-r', 'postgres.long.dotted.string',
'-r', 'postgres.pg_catalog.none',
'-r', 'postgres.none.pg_class',
'-t', 'postgres.pg_catalog.pg_class', # This exists
qr/pg_amcheck: warning: no connectable databases to check matching "no\*such\*database"/,
qr/pg_amcheck: warning: no relations to check matching "none\.none"/,
qr/pg_amcheck: warning: no connectable databases to check matching "none\.none\.none"/,
- qr/pg_amcheck: warning: no connectable databases to check matching "this\.is\.a\.really\.long\.dotted\.string"/,
qr/pg_amcheck: warning: no relations to check matching "postgres\.none\.none"/,
- qr/pg_amcheck: warning: no relations to check matching "postgres\.long\.dotted\.string"/,
qr/pg_amcheck: warning: no relations to check matching "postgres\.pg_catalog\.none"/,
qr/pg_amcheck: warning: no relations to check matching "postgres\.none\.pg_class"/,
qr/pg_amcheck: warning: no connectable databases to check matching "no_such_database"/,
qr/pg_amcheck: warning: no connectable databases to check matching "no\*such\*database"/,
qr/pg_amcheck: warning: no connectable databases to check matching "none\.none\.none"/,
- qr/pg_amcheck: warning: no connectable databases to check matching "this\.is\.a\.really\.long\.dotted\.string"/,
],
'many unmatched patterns and one matched pattern under --no-strict-names'
);
SimpleStringList *patterns,
SimpleOidList *oids,
bool strict_names);
+static void prohibit_crossdb_refs(PGconn *conn, const char *dbname,
+ const char *pattern);
+
static NamespaceInfo *findNamespace(Oid nsoid);
static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo);
static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo);
for (cell = patterns->head; cell; cell = cell->next)
{
+ PQExpBufferData dbbuf;
+ int dotcnt;
+
appendPQExpBufferStr(query,
"SELECT oid FROM pg_catalog.pg_namespace n\n");
+ initPQExpBuffer(&dbbuf);
processSQLNamePattern(GetConnection(fout), query, cell->val, false,
- false, NULL, "n.nspname", NULL, NULL);
+ false, NULL, "n.nspname", NULL, NULL, &dbbuf,
+ &dotcnt);
+ if (dotcnt > 1)
+ pg_fatal("improper qualified name (too many dotted names): %s",
+ cell->val);
+ else if (dotcnt == 1)
+ prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
+ termPQExpBuffer(&dbbuf);
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
if (strict_names && PQntuples(res) == 0)
*/
for (cell = patterns->head; cell; cell = cell->next)
{
+ int dotcnt;
+
appendPQExpBufferStr(query,
"SELECT oid FROM pg_catalog.pg_extension e\n");
processSQLNamePattern(GetConnection(fout), query, cell->val, false,
- false, NULL, "e.extname", NULL, NULL);
+ false, NULL, "e.extname", NULL, NULL, NULL,
+ &dotcnt);
+ if (dotcnt > 0)
+ pg_fatal("improper qualified name (too many dotted names): %s",
+ cell->val);
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
if (strict_names && PQntuples(res) == 0)
for (cell = patterns->head; cell; cell = cell->next)
{
+ int dotcnt;
+
appendPQExpBufferStr(query,
"SELECT oid FROM pg_catalog.pg_foreign_server s\n");
processSQLNamePattern(GetConnection(fout), query, cell->val, false,
- false, NULL, "s.srvname", NULL, NULL);
+ false, NULL, "s.srvname", NULL, NULL, NULL,
+ &dotcnt);
+ if (dotcnt > 0)
+ pg_fatal("improper qualified name (too many dotted names): %s",
+ cell->val);
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
if (PQntuples(res) == 0)
for (cell = patterns->head; cell; cell = cell->next)
{
+ PQExpBufferData dbbuf;
+ int dotcnt;
+
/*
* Query must remain ABSOLUTELY devoid of unqualified names. This
* would be unnecessary given a pg_table_is_visible() variant taking a
RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
RELKIND_PARTITIONED_TABLE);
+ initPQExpBuffer(&dbbuf);
processSQLNamePattern(GetConnection(fout), query, cell->val, true,
false, "n.nspname", "c.relname", NULL,
- "pg_catalog.pg_table_is_visible(c.oid)");
+ "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
+ &dotcnt);
+ if (dotcnt > 2)
+ pg_fatal("improper relation name (too many dotted names): %s",
+ cell->val);
+ else if (dotcnt == 2)
+ prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
+ termPQExpBuffer(&dbbuf);
ExecuteSqlStatement(fout, "RESET search_path");
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
destroyPQExpBuffer(query);
}
+/*
+ * Verifies that the connected database name matches the given database name,
+ * and if not, dies with an error about the given pattern.
+ *
+ * The 'dbname' argument should be a literal name parsed from 'pattern'.
+ */
+static void
+prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
+{
+ const char *db;
+
+ db = PQdb(conn);
+ if (db == NULL)
+ pg_fatal("You are currently not connected to a database.");
+
+ if (strcmp(db, dbname) != 0)
+ pg_fatal("cross-database references are not implemented: %s",
+ pattern);
+}
+
/*
* checkExtensionMembership
* Determine whether object is an extension member, and if so,
for (SimpleStringListCell *cell = patterns->head; cell; cell = cell->next)
{
+ int dotcnt;
+
appendPQExpBufferStr(query,
"SELECT datname FROM pg_catalog.pg_database n\n");
processSQLNamePattern(conn, query, cell->val, false,
- false, NULL, "datname", NULL, NULL);
+ false, NULL, "datname", NULL, NULL, NULL,
+ &dotcnt);
+
+ if (dotcnt > 0)
+ {
+ pg_log_error("improper qualified name (too many dotted names): %s",
+ cell->val);
+ PQfinish(conn);
+ exit_nicely(1);
+ }
res = executeQuery(conn, query->data);
for (int i = 0; i < PQntuples(res); i++)
qr/\Qpg_dump: error: no matching tables were found for pattern\E/,
'no matching tables');
+#########################################
+# Test invalid multipart database names
+
+$node->command_fails_like(
+ [ 'pg_dumpall', '--exclude-database', '.' ],
+ qr/pg_dumpall: error: improper qualified name \(too many dotted names\): \./,
+ 'pg_dumpall: option --exclude-database rejects multipart pattern "."'
+);
+
+$node->command_fails_like(
+ [ 'pg_dumpall', '--exclude-database', '.*' ],
+ qr/pg_dumpall: error: improper qualified name \(too many dotted names\): \.\*/,
+ 'pg_dumpall: option --exclude-database rejects multipart pattern ".*"'
+);
+
+$node->command_fails_like(
+ [ 'pg_dumpall', '--exclude-database', '*.*' ],
+ qr/pg_dumpall: error: improper qualified name \(too many dotted names\): \*\.\*/,
+ 'pg_dumpall: option --exclude-database rejects multipart pattern "*.*"'
+);
+
+$node->command_fails_like(
+ [ 'pg_dumpall', '--exclude-database', 'myhost.mydb' ],
+ qr/pg_dumpall: error: improper qualified name \(too many dotted names\): myhost\.mydb/,
+ 'pg_dumpall: option --exclude-database rejects multipart database names'
+);
+
+#########################################
+# Test valid database exclusion patterns
+
+$node->command_ok(
+ [ 'pg_dumpall', '-p', "$port", '--exclude-database', '"myhost.mydb"' ],
+ 'pg_dumpall: option --exclude-database handles database names with embedded dots'
+);
+
+$node->command_ok(
+ [ 'pg_dumpall', '--exclude-database', '??*' ],
+ 'pg_dumpall: option --exclude-database handles database name patterns'
+);
+
+
+#########################################
+# Test invalid multipart schema names
+
+$node->command_fails_like(
+ [ 'pg_dump', '--schema', 'myhost.mydb.myschema' ],
+ qr/pg_dump: error: improper qualified name \(too many dotted names\): myhost\.mydb\.myschema/,
+ 'pg_dump: option --schema rejects three-part schema names'
+);
+
+$node->command_fails_like(
+ [ 'pg_dump', '--schema', 'otherdb.myschema' ],
+ qr/pg_dump: error: cross-database references are not implemented: otherdb\.myschema/,
+ 'pg_dump: option --schema rejects cross-database multipart schema names'
+);
+
+$node->command_fails_like(
+ [ 'pg_dump', '--schema', '.' ],
+ qr/pg_dump: error: cross-database references are not implemented: \./,
+ 'pg_dump: option --schema rejects degenerate two-part schema name: "."'
+);
+
+$node->command_fails_like(
+ [ 'pg_dump', '--schema', '"some.other.db".myschema' ],
+ qr/pg_dump: error: cross-database references are not implemented: "some\.other\.db"\.myschema/,
+ 'pg_dump: option --schema rejects cross-database multipart schema names with embedded dots'
+);
+
+$node->command_fails_like(
+ [ 'pg_dump', '--schema', '.*' ],
+ qr/pg_dump: error: cross-database references are not implemented: \.\*/,
+ 'pg_dump: option --schema rejects degenerate two-part schema name: ".*"'
+);
+
+$node->command_fails_like(
+ [ 'pg_dump', '--schema', '..' ],
+ qr/pg_dump: error: improper qualified name \(too many dotted names\): \.\./,
+ 'pg_dump: option --schema rejects degenerate three-part schema name: ".."'
+);
+
+$node->command_fails_like(
+ [ 'pg_dump', '--schema', '.*.*' ],
+ qr/pg_dump: error: improper qualified name \(too many dotted names\): \.\*\.\*/,
+ 'pg_dump: option --schema rejects degenerate three-part schema pattern: ".*.*"'
+);
+
+#########################################
+# Test invalid multipart relation names
+
+$node->command_fails_like(
+ [ 'pg_dump', '--table', 'myhost.mydb.myschema.mytable' ],
+ qr/pg_dump: error: improper relation name \(too many dotted names\): myhost\.mydb\.myschema\.mytable/,
+ 'pg_dump: option --table rejects four-part table names'
+);
+
+$node->command_fails_like(
+ [ 'pg_dump', '--table', 'otherdb.pg_catalog.pg_class' ],
+ qr/pg_dump: error: cross-database references are not implemented: otherdb\.pg_catalog\.pg_class/,
+ 'pg_dump: option --table rejects cross-database three part table names'
+);
+
+command_fails_like(
+ [ 'pg_dump', '-p', "$port", '--table', '"some.other.db".pg_catalog.pg_class' ],
+ qr/pg_dump: error: cross-database references are not implemented: "some\.other\.db"\.pg_catalog\.pg_class/,
+ 'pg_dump: option --table rejects cross-database three part table names with embedded dots'
+);
+
#########################################
# Run all runs
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);
/*----------------
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;");
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;");
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;");
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++)
{
"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
{
" 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;");
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");
"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
{
" 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);
* 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;");
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;");
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,
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,
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,
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,
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,
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"
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;");
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;");
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);
" 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;");
" 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, " : "",
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");
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;");
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;");
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");
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");
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;");
* 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;");
*/
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;");
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;");
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;");
"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;");
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;");
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;");
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;");
"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;");
" 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;");
"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;");
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;");
" 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;");
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;");
"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;");
return true;
}
+/*
+ * 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.
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;");
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;");
" 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;");
" 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;");
" 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,
" 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");
}
" 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"
" 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"
* altnamevar: NULL, or name of an alternative variable to match against name.
* visibilityrule: clause to use if we want to restrict to visible objects
* (for example, "pg_catalog.pg_table_is_visible(p.oid)"). Can be NULL.
+ * dbnamebuf: output parameter receiving the database name portion of the
+ * pattern, if any. Can be NULL.
+ * dotcnt: how many separators were parsed from the pattern, by reference.
*
* Formatting note: the text already present in buf should end with a newline.
* The appended text, if any, will end with one too.
processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern,
bool have_where, bool force_escape,
const char *schemavar, const char *namevar,
- const char *altnamevar, const char *visibilityrule)
+ const char *altnamevar, const char *visibilityrule,
+ PQExpBuffer dbnamebuf, int *dotcnt)
{
PQExpBufferData schemabuf;
PQExpBufferData namebuf;
bool added_clause = false;
+ int dcnt;
#define WHEREAND() \
(appendPQExpBufferStr(buf, have_where ? " AND " : "WHERE "), \
have_where = true, added_clause = true)
+ if (dotcnt == NULL)
+ dotcnt = &dcnt;
+ *dotcnt = 0;
if (pattern == NULL)
{
/* Default: select all visible objects */
* If the caller provided a schemavar, we want to split the pattern on
* ".", otherwise not.
*/
- patternToSQLRegex(PQclientEncoding(conn), NULL,
- (schemavar ? &schemabuf : NULL), &namebuf,
- pattern, force_escape);
+ patternToSQLRegex(PQclientEncoding(conn),
+ (schemavar ? dbnamebuf : NULL),
+ (schemavar ? &schemabuf : NULL),
+ &namebuf,
+ pattern, force_escape, true, dotcnt);
/*
* Now decide what we need to emit. We may run under a hostile
* is >= v12 then we need to force it through explicit COLLATE clauses,
* otherwise the "C" collation attached to "name" catalog columns wins.
*/
- if (namebuf.len > 2)
+ if (namevar && namebuf.len > 2)
{
/* We have a name pattern, so constrain the namevar(s) */
}
}
- if (schemabuf.len > 2)
+ if (schemavar && schemabuf.len > 2)
{
/* We have a schema pattern, so constrain the schemavar */
* If the dbnamebuf and schemabuf arguments are non-NULL, and the pattern
* contains two or more dbname/schema/name separators, we parse the portions of
* the pattern prior to the first and second separators into dbnamebuf and
- * schemabuf, and the rest into namebuf. (Additional dots in the name portion
- * are not treated as special.)
+ * schemabuf, and the rest into namebuf.
*
* If dbnamebuf is NULL and schemabuf is non-NULL, and the pattern contains at
* least one separator, we parse the first portion into schemabuf and the rest
*
* Otherwise, we parse all the pattern into namebuf.
*
+ * If the pattern contains more dotted parts than buffers to parse into, the
+ * extra dots will be treated as literal characters and written into the
+ * namebuf, though they will be counted. Callers should always check the value
+ * returned by reference in dotcnt and handle this error case appropriately.
+ *
* We surround the regexps with "^(...)$" to force them to match whole strings,
* as per SQL practice. We have to have parens in case strings contain "|",
* else the "^" and "$" will be bound into the first and last alternatives
- * which is not what we want.
+ * which is not what we want. Whether this is done for dbnamebuf is controlled
+ * by the want_literal_dbname parameter.
*
* The regexps we parse into the buffers are appended to the data (if any)
* already present. If we parse fewer fields than the number of buffers we
* were given, the extra buffers are unaltered.
+ *
+ * encoding: the character encoding for the given pattern
+ * dbnamebuf: output parameter receiving the database name portion of the
+ * pattern, if any. Can be NULL.
+ * schemabuf: output parameter receiving the schema name portion of the
+ * pattern, if any. Can be NULL.
+ * namebuf: output parameter receiving the database name portion of the
+ * pattern, if any. Can be NULL.
+ * pattern: user-specified pattern option, or NULL if none ("*" is implied).
+ * force_escape: always quote regexp special characters, even outside
+ * double quotes (else they are quoted only between double quotes).
+ * want_literal_dbname: if true, regexp special characters within the database
+ * name portion of the pattern will not be escaped, nor will the dbname be
+ * converted into a regular expression.
+ * dotcnt: output parameter receiving the number of separators parsed from the
+ * pattern.
*/
void
patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, PQExpBuffer schemabuf,
- PQExpBuffer namebuf, const char *pattern, bool force_escape)
+ PQExpBuffer namebuf, const char *pattern, bool force_escape,
+ bool want_literal_dbname, int *dotcnt)
{
PQExpBufferData buf[3];
+ PQExpBufferData left_literal;
PQExpBuffer curbuf;
PQExpBuffer maxbuf;
int i;
bool inquotes;
+ bool left;
const char *cp;
Assert(pattern != NULL);
/* callers should never expect "dbname.relname" format */
Assert(dbnamebuf == NULL || schemabuf != NULL);
+ Assert(dotcnt != NULL);
+ *dotcnt = 0;
inquotes = false;
cp = pattern;
maxbuf = &buf[0];
curbuf = &buf[0];
+ if (want_literal_dbname)
+ {
+ left = true;
+ initPQExpBuffer(&left_literal);
+ }
+ else
+ left = false;
initPQExpBuffer(curbuf);
appendPQExpBufferStr(curbuf, "^(");
while (*cp)
{
/* emit one quote, stay in inquotes mode */
appendPQExpBufferChar(curbuf, '"');
+ if (left)
+ appendPQExpBufferChar(&left_literal, '"');
cp++;
}
else
{
appendPQExpBufferChar(curbuf,
pg_tolower((unsigned char) ch));
+ if (left)
+ appendPQExpBufferChar(&left_literal,
+ pg_tolower((unsigned char) ch));
cp++;
}
else if (!inquotes && ch == '*')
{
appendPQExpBufferStr(curbuf, ".*");
+ if (left)
+ appendPQExpBufferChar(&left_literal, '*');
cp++;
}
else if (!inquotes && ch == '?')
{
appendPQExpBufferChar(curbuf, '.');
+ if (left)
+ appendPQExpBufferChar(&left_literal, '?');
cp++;
}
-
- /*
- * When we find a dbname/schema/name separator, we treat it specially
- * only if the caller requested more patterns to be parsed than we
- * have already parsed from the pattern. Otherwise, dot characters
- * are not special.
- */
- else if (!inquotes && ch == '.' && curbuf < maxbuf)
+ else if (!inquotes && ch == '.')
{
- appendPQExpBufferStr(curbuf, ")$");
- curbuf++;
- initPQExpBuffer(curbuf);
- appendPQExpBufferStr(curbuf, "^(");
- cp++;
+ left = false;
+ if (dotcnt)
+ (*dotcnt)++;
+ if (curbuf < maxbuf)
+ {
+ appendPQExpBufferStr(curbuf, ")$");
+ curbuf++;
+ initPQExpBuffer(curbuf);
+ appendPQExpBufferStr(curbuf, "^(");
+ cp++;
+ }
+ else
+ appendPQExpBufferChar(curbuf, *cp++);
}
else if (ch == '$')
{
* having it possess its regexp meaning.
*/
appendPQExpBufferStr(curbuf, "\\$");
+ if (left)
+ appendPQExpBufferChar(&left_literal, '$');
cp++;
}
else
appendPQExpBufferChar(curbuf, '\\');
i = PQmblenBounded(cp, encoding);
while (i--)
+ {
+ if (left)
+ appendPQExpBufferChar(&left_literal, *cp);
appendPQExpBufferChar(curbuf, *cp++);
+ }
}
}
appendPQExpBufferStr(curbuf, ")$");
- appendPQExpBufferStr(namebuf, curbuf->data);
- termPQExpBuffer(curbuf);
-
- if (curbuf > buf)
+ if (namebuf)
{
+ appendPQExpBufferStr(namebuf, curbuf->data);
+ termPQExpBuffer(curbuf);
curbuf--;
+ }
+
+ if (schemabuf && curbuf >= buf)
+ {
appendPQExpBufferStr(schemabuf, curbuf->data);
termPQExpBuffer(curbuf);
+ curbuf--;
+ }
- if (curbuf > buf)
- {
- curbuf--;
+ if (dbnamebuf && curbuf >= buf)
+ {
+ if (want_literal_dbname)
+ appendPQExpBufferStr(dbnamebuf, left_literal.data);
+ else
appendPQExpBufferStr(dbnamebuf, curbuf->data);
- termPQExpBuffer(curbuf);
- }
+ termPQExpBuffer(curbuf);
}
}
const char *pattern,
bool have_where, bool force_escape,
const char *schemavar, const char *namevar,
- const char *altnamevar, const char *visibilityrule);
+ const char *altnamevar, const char *visibilityrule,
+ PQExpBuffer dbnamebuf, int *dotcnt);
extern void patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf,
PQExpBuffer schemabuf, PQExpBuffer namebuf,
- const char *pattern, bool force_escape);
+ const char *pattern, bool force_escape,
+ bool want_literal_dbname, int *dotcnt);
#endif /* STRING_UTILS_H */
# final ON_ERROR_ROLLBACK: off
DROP TABLE bla;
DROP FUNCTION psql_error;
+-- check describing invalid multipart names
+\dA regression.heap
+improper qualified name (too many dotted names): regression.heap
+\dA nonesuch.heap
+improper qualified name (too many dotted names): nonesuch.heap
+\dt host.regression.pg_catalog.pg_class
+improper qualified name (too many dotted names): host.regression.pg_catalog.pg_class
+\dt |.pg_catalog.pg_class
+cross-database references are not implemented: |.pg_catalog.pg_class
+\dt nonesuch.pg_catalog.pg_class
+cross-database references are not implemented: nonesuch.pg_catalog.pg_class
+\da host.regression.pg_catalog.sum
+improper qualified name (too many dotted names): host.regression.pg_catalog.sum
+\da +.pg_catalog.sum
+cross-database references are not implemented: +.pg_catalog.sum
+\da nonesuch.pg_catalog.sum
+cross-database references are not implemented: nonesuch.pg_catalog.sum
+\dAc nonesuch.brin
+improper qualified name (too many dotted names): nonesuch.brin
+\dAc regression.brin
+improper qualified name (too many dotted names): regression.brin
+\dAf nonesuch.brin
+improper qualified name (too many dotted names): nonesuch.brin
+\dAf regression.brin
+improper qualified name (too many dotted names): regression.brin
+\dAo nonesuch.brin
+improper qualified name (too many dotted names): nonesuch.brin
+\dAo regression.brin
+improper qualified name (too many dotted names): regression.brin
+\dAp nonesuch.brin
+improper qualified name (too many dotted names): nonesuch.brin
+\dAp regression.brin
+improper qualified name (too many dotted names): regression.brin
+\db nonesuch.pg_default
+improper qualified name (too many dotted names): nonesuch.pg_default
+\db regression.pg_default
+improper qualified name (too many dotted names): regression.pg_default
+\dc host.regression.public.conversion
+improper qualified name (too many dotted names): host.regression.public.conversion
+\dc (.public.conversion
+cross-database references are not implemented: (.public.conversion
+\dc nonesuch.public.conversion
+cross-database references are not implemented: nonesuch.public.conversion
+\dC host.regression.pg_catalog.int8
+improper qualified name (too many dotted names): host.regression.pg_catalog.int8
+\dC ).pg_catalog.int8
+cross-database references are not implemented: ).pg_catalog.int8
+\dC nonesuch.pg_catalog.int8
+cross-database references are not implemented: nonesuch.pg_catalog.int8
+\dd host.regression.pg_catalog.pg_class
+improper qualified name (too many dotted names): host.regression.pg_catalog.pg_class
+\dd [.pg_catalog.pg_class
+cross-database references are not implemented: [.pg_catalog.pg_class
+\dd nonesuch.pg_catalog.pg_class
+cross-database references are not implemented: nonesuch.pg_catalog.pg_class
+\dD host.regression.public.gtestdomain1
+improper qualified name (too many dotted names): host.regression.public.gtestdomain1
+\dD ].public.gtestdomain1
+cross-database references are not implemented: ].public.gtestdomain1
+\dD nonesuch.public.gtestdomain1
+cross-database references are not implemented: nonesuch.public.gtestdomain1
+\ddp host.regression.pg_catalog.pg_class
+improper qualified name (too many dotted names): host.regression.pg_catalog.pg_class
+\ddp {.pg_catalog.pg_class
+cross-database references are not implemented: {.pg_catalog.pg_class
+\ddp nonesuch.pg_catalog.pg_class
+cross-database references are not implemented: nonesuch.pg_catalog.pg_class
+\dE host.regression.public.ft
+improper qualified name (too many dotted names): host.regression.public.ft
+\dE }.public.ft
+cross-database references are not implemented: }.public.ft
+\dE nonesuch.public.ft
+cross-database references are not implemented: nonesuch.public.ft
+\di host.regression.public.tenk1_hundred
+improper qualified name (too many dotted names): host.regression.public.tenk1_hundred
+\di ..public.tenk1_hundred
+improper qualified name (too many dotted names): ..public.tenk1_hundred
+\di nonesuch.public.tenk1_hundred
+cross-database references are not implemented: nonesuch.public.tenk1_hundred
+\dm host.regression.public.mvtest_bb
+improper qualified name (too many dotted names): host.regression.public.mvtest_bb
+\dm ^.public.mvtest_bb
+cross-database references are not implemented: ^.public.mvtest_bb
+\dm nonesuch.public.mvtest_bb
+cross-database references are not implemented: nonesuch.public.mvtest_bb
+\ds host.regression.public.check_seq
+improper qualified name (too many dotted names): host.regression.public.check_seq
+\ds regression|mydb.public.check_seq
+cross-database references are not implemented: regression|mydb.public.check_seq
+\ds nonesuch.public.check_seq
+cross-database references are not implemented: nonesuch.public.check_seq
+\dt host.regression.public.b_star
+improper qualified name (too many dotted names): host.regression.public.b_star
+\dt regres+ion.public.b_star
+cross-database references are not implemented: regres+ion.public.b_star
+\dt nonesuch.public.b_star
+cross-database references are not implemented: nonesuch.public.b_star
+\dv host.regression.public.shoe
+improper qualified name (too many dotted names): host.regression.public.shoe
+\dv regress(ion).public.shoe
+cross-database references are not implemented: regress(ion).public.shoe
+\dv nonesuch.public.shoe
+cross-database references are not implemented: nonesuch.public.shoe
+\des nonesuch.server
+improper qualified name (too many dotted names): nonesuch.server
+\des regression.server
+improper qualified name (too many dotted names): regression.server
+\des nonesuch.server
+improper qualified name (too many dotted names): nonesuch.server
+\des regression.server
+improper qualified name (too many dotted names): regression.server
+\des nonesuch.username
+improper qualified name (too many dotted names): nonesuch.username
+\des regression.username
+improper qualified name (too many dotted names): regression.username
+\dew nonesuch.fdw
+improper qualified name (too many dotted names): nonesuch.fdw
+\dew regression.fdw
+improper qualified name (too many dotted names): regression.fdw
+\df host.regression.public.namelen
+improper qualified name (too many dotted names): host.regression.public.namelen
+\df regres[qrstuv]ion.public.namelen
+cross-database references are not implemented: regres[qrstuv]ion.public.namelen
+\df nonesuch.public.namelen
+cross-database references are not implemented: nonesuch.public.namelen
+\dF host.regression.pg_catalog.arabic
+improper qualified name (too many dotted names): host.regression.pg_catalog.arabic
+\dF regres{1,2}ion.pg_catalog.arabic
+cross-database references are not implemented: regres{1,2}ion.pg_catalog.arabic
+\dF nonesuch.pg_catalog.arabic
+cross-database references are not implemented: nonesuch.pg_catalog.arabic
+\dFd host.regression.pg_catalog.arabic_stem
+improper qualified name (too many dotted names): host.regression.pg_catalog.arabic_stem
+\dFd regres?ion.pg_catalog.arabic_stem
+cross-database references are not implemented: regres?ion.pg_catalog.arabic_stem
+\dFd nonesuch.pg_catalog.arabic_stem
+cross-database references are not implemented: nonesuch.pg_catalog.arabic_stem
+\dFp host.regression.pg_catalog.default
+improper qualified name (too many dotted names): host.regression.pg_catalog.default
+\dFp ^regression.pg_catalog.default
+cross-database references are not implemented: ^regression.pg_catalog.default
+\dFp nonesuch.pg_catalog.default
+cross-database references are not implemented: nonesuch.pg_catalog.default
+\dFt host.regression.pg_catalog.ispell
+improper qualified name (too many dotted names): host.regression.pg_catalog.ispell
+\dFt regression$.pg_catalog.ispell
+cross-database references are not implemented: regression$.pg_catalog.ispell
+\dFt nonesuch.pg_catalog.ispell
+cross-database references are not implemented: nonesuch.pg_catalog.ispell
+\dg nonesuch.pg_database_owner
+improper qualified name (too many dotted names): nonesuch.pg_database_owner
+\dg regression.pg_database_owner
+improper qualified name (too many dotted names): regression.pg_database_owner
+\dL host.regression.plpgsql
+improper qualified name (too many dotted names): host.regression.plpgsql
+\dL *.plpgsql
+cross-database references are not implemented: *.plpgsql
+\dL nonesuch.plpgsql
+cross-database references are not implemented: nonesuch.plpgsql
+\dn host.regression.public
+improper qualified name (too many dotted names): host.regression.public
+\dn """".public
+cross-database references are not implemented: """".public
+\dn nonesuch.public
+cross-database references are not implemented: nonesuch.public
+\do host.regression.public.!=-
+improper qualified name (too many dotted names): host.regression.public.!=-
+\do "regression|mydb".public.!=-
+cross-database references are not implemented: "regression|mydb".public.!=-
+\do nonesuch.public.!=-
+cross-database references are not implemented: nonesuch.public.!=-
+\dO host.regression.pg_catalog.POSIX
+improper qualified name (too many dotted names): host.regression.pg_catalog.POSIX
+\dO .pg_catalog.POSIX
+cross-database references are not implemented: .pg_catalog.POSIX
+\dO nonesuch.pg_catalog.POSIX
+cross-database references are not implemented: nonesuch.pg_catalog.POSIX
+\dp host.regression.public.a_star
+improper qualified name (too many dotted names): host.regression.public.a_star
+\dp "regres+ion".public.a_star
+cross-database references are not implemented: "regres+ion".public.a_star
+\dp nonesuch.public.a_star
+cross-database references are not implemented: nonesuch.public.a_star
+\dP host.regression.public.mlparted
+improper qualified name (too many dotted names): host.regression.public.mlparted
+\dP "regres(sion)".public.mlparted
+cross-database references are not implemented: "regres(sion)".public.mlparted
+\dP nonesuch.public.mlparted
+cross-database references are not implemented: nonesuch.public.mlparted
+\drds nonesuch.lc_messages
+improper qualified name (too many dotted names): nonesuch.lc_messages
+\drds regression.lc_messages
+improper qualified name (too many dotted names): regression.lc_messages
+\dRp public.mypub
+improper qualified name (too many dotted names): public.mypub
+\dRp regression.mypub
+improper qualified name (too many dotted names): regression.mypub
+\dRs public.mysub
+improper qualified name (too many dotted names): public.mysub
+\dRs regression.mysub
+improper qualified name (too many dotted names): regression.mysub
+\dT host.regression.public.widget
+improper qualified name (too many dotted names): host.regression.public.widget
+\dT "regression{1,2}".public.widget
+cross-database references are not implemented: "regression{1,2}".public.widget
+\dT nonesuch.public.widget
+cross-database references are not implemented: nonesuch.public.widget
+\dx regression.plpgsql
+improper qualified name (too many dotted names): regression.plpgsql
+\dx nonesuch.plpgsql
+improper qualified name (too many dotted names): nonesuch.plpgsql
+\dX host.regression.public.func_deps_stat
+improper qualified name (too many dotted names): host.regression.public.func_deps_stat
+\dX "^regression$".public.func_deps_stat
+cross-database references are not implemented: "^regression$".public.func_deps_stat
+\dX nonesuch.public.func_deps_stat
+cross-database references are not implemented: nonesuch.public.func_deps_stat
+\dy regression.myevt
+improper qualified name (too many dotted names): regression.myevt
+\dy nonesuch.myevt
+improper qualified name (too many dotted names): nonesuch.myevt
+-- check that dots within quoted name segments are not counted
+\dA "no.such.access.method"
+List of access methods
+ Name | Type
+------+------
+(0 rows)
+
+\dt "no.such.table.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\da "no.such.aggregate.function"
+ List of aggregate functions
+ Schema | Name | Result data type | Argument data types | Description
+--------+------+------------------+---------------------+-------------
+(0 rows)
+
+\dAc "no.such.operator.class"
+ List of operator classes
+ AM | Input type | Storage type | Operator class | Default?
+----+------------+--------------+----------------+----------
+(0 rows)
+
+\dAf "no.such.operator.family"
+ List of operator families
+ AM | Operator family | Applicable types
+----+-----------------+------------------
+(0 rows)
+
+\dAo "no.such.operator.of.operator.family"
+ List of operators of operator families
+ AM | Operator family | Operator | Strategy | Purpose
+----+-----------------+----------+----------+---------
+(0 rows)
+
+\dAp "no.such.operator.support.function.of.operator.family"
+ List of support functions of operator families
+ AM | Operator family | Registered left type | Registered right type | Number | Function
+----+-----------------+----------------------+-----------------------+--------+----------
+(0 rows)
+
+\db "no.such.tablespace"
+ List of tablespaces
+ Name | Owner | Location
+------+-------+----------
+(0 rows)
+
+\dc "no.such.conversion"
+ List of conversions
+ Schema | Name | Source | Destination | Default?
+--------+------+--------+-------------+----------
+(0 rows)
+
+\dC "no.such.cast"
+ List of casts
+ Source type | Target type | Function | Implicit?
+-------------+-------------+----------+-----------
+(0 rows)
+
+\dd "no.such.object.description"
+ Object descriptions
+ Schema | Name | Object | Description
+--------+------+--------+-------------
+(0 rows)
+
+\dD "no.such.domain"
+ List of domains
+ Schema | Name | Type | Collation | Nullable | Default | Check
+--------+------+------+-----------+----------+---------+-------
+(0 rows)
+
+\ddp "no.such.default.access.privilege"
+ Default access privileges
+ Owner | Schema | Type | Access privileges
+-------+--------+------+-------------------
+(0 rows)
+
+\di "no.such.index.relation"
+ List of relations
+ Schema | Name | Type | Owner | Table
+--------+------+------+-------+-------
+(0 rows)
+
+\dm "no.such.materialized.view"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\ds "no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\dt "no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\dv "no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\des "no.such.foreign.server"
+ List of foreign servers
+ Name | Owner | Foreign-data wrapper
+------+-------+----------------------
+(0 rows)
+
+\dew "no.such.foreign.data.wrapper"
+ List of foreign-data wrappers
+ Name | Owner | Handler | Validator
+------+-------+---------+-----------
+(0 rows)
+
+\df "no.such.function"
+ List of functions
+ Schema | Name | Result data type | Argument data types | Type
+--------+------+------------------+---------------------+------
+(0 rows)
+
+\dF "no.such.text.search.configuration"
+List of text search configurations
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFd "no.such.text.search.dictionary"
+List of text search dictionaries
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFp "no.such.text.search.parser"
+ List of text search parsers
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFt "no.such.text.search.template"
+List of text search templates
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dg "no.such.role"
+ List of roles
+ Role name | Attributes | Member of
+-----------+------------+-----------
+
+\dL "no.such.language"
+ List of languages
+ Name | Owner | Trusted | Description
+------+-------+---------+-------------
+(0 rows)
+
+\dn "no.such.schema"
+List of schemas
+ Name | Owner
+------+-------
+(0 rows)
+
+\do "no.such.operator"
+ List of operators
+ Schema | Name | Left arg type | Right arg type | Result type | Description
+--------+------+---------------+----------------+-------------+-------------
+(0 rows)
+
+\dO "no.such.collation"
+ List of collations
+ Schema | Name | Collate | Ctype | ICU Locale | Provider | Deterministic?
+--------+------+---------+-------+------------+----------+----------------
+(0 rows)
+
+\dp "no.such.access.privilege"
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+------+------+-------------------+-------------------+----------
+(0 rows)
+
+\dP "no.such.partitioned.relation"
+ List of partitioned relations
+ Schema | Name | Owner | Type | Parent name | Table
+--------+------+-------+------+-------------+-------
+(0 rows)
+
+\drds "no.such.setting"
+ List of settings
+ Role | Database | Settings
+------+----------+----------
+(0 rows)
+
+\dRp "no.such.publication"
+ List of publications
+ Name | Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+------+-------+------------+---------+---------+---------+-----------+----------
+(0 rows)
+
+\dRs "no.such.subscription"
+ List of subscriptions
+ Name | Owner | Enabled | Publication
+------+-------+---------+-------------
+(0 rows)
+
+\dT "no.such.data.type"
+ List of data types
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dx "no.such.installed.extension"
+ List of installed extensions
+ Name | Version | Schema | Description
+------+---------+--------+-------------
+(0 rows)
+
+\dX "no.such.extended.statistics"
+ List of extended statistics
+ Schema | Name | Definition | Ndistinct | Dependencies | MCV
+--------+------+------------+-----------+--------------+-----
+(0 rows)
+
+\dy "no.such.event.trigger"
+ List of event triggers
+ Name | Event | Owner | Enabled | Function | Tags
+------+-------+-------+---------+----------+------
+(0 rows)
+
+-- again, but with dotted schema qualifications.
+\dA "no.such.schema"."no.such.access.method"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.access.method"
+\dt "no.such.schema"."no.such.table.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\da "no.such.schema"."no.such.aggregate.function"
+ List of aggregate functions
+ Schema | Name | Result data type | Argument data types | Description
+--------+------+------------------+---------------------+-------------
+(0 rows)
+
+\dAc "no.such.schema"."no.such.operator.class"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.operator.class"
+\dAf "no.such.schema"."no.such.operator.family"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.operator.family"
+\dAo "no.such.schema"."no.such.operator.of.operator.family"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.operator.of.operator.family"
+\dAp "no.such.schema"."no.such.operator.support.function.of.operator.family"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.operator.support.function.of.operator.family"
+\db "no.such.schema"."no.such.tablespace"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.tablespace"
+\dc "no.such.schema"."no.such.conversion"
+ List of conversions
+ Schema | Name | Source | Destination | Default?
+--------+------+--------+-------------+----------
+(0 rows)
+
+\dC "no.such.schema"."no.such.cast"
+ List of casts
+ Source type | Target type | Function | Implicit?
+-------------+-------------+----------+-----------
+(0 rows)
+
+\dd "no.such.schema"."no.such.object.description"
+ Object descriptions
+ Schema | Name | Object | Description
+--------+------+--------+-------------
+(0 rows)
+
+\dD "no.such.schema"."no.such.domain"
+ List of domains
+ Schema | Name | Type | Collation | Nullable | Default | Check
+--------+------+------+-----------+----------+---------+-------
+(0 rows)
+
+\ddp "no.such.schema"."no.such.default.access.privilege"
+ Default access privileges
+ Owner | Schema | Type | Access privileges
+-------+--------+------+-------------------
+(0 rows)
+
+\di "no.such.schema"."no.such.index.relation"
+ List of relations
+ Schema | Name | Type | Owner | Table
+--------+------+------+-------+-------
+(0 rows)
+
+\dm "no.such.schema"."no.such.materialized.view"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\ds "no.such.schema"."no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\dt "no.such.schema"."no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\dv "no.such.schema"."no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\des "no.such.schema"."no.such.foreign.server"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.foreign.server"
+\dew "no.such.schema"."no.such.foreign.data.wrapper"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.foreign.data.wrapper"
+\df "no.such.schema"."no.such.function"
+ List of functions
+ Schema | Name | Result data type | Argument data types | Type
+--------+------+------------------+---------------------+------
+(0 rows)
+
+\dF "no.such.schema"."no.such.text.search.configuration"
+List of text search configurations
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFd "no.such.schema"."no.such.text.search.dictionary"
+List of text search dictionaries
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFp "no.such.schema"."no.such.text.search.parser"
+ List of text search parsers
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFt "no.such.schema"."no.such.text.search.template"
+List of text search templates
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dg "no.such.schema"."no.such.role"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.role"
+\dL "no.such.schema"."no.such.language"
+cross-database references are not implemented: "no.such.schema"."no.such.language"
+\do "no.such.schema"."no.such.operator"
+ List of operators
+ Schema | Name | Left arg type | Right arg type | Result type | Description
+--------+------+---------------+----------------+-------------+-------------
+(0 rows)
+
+\dO "no.such.schema"."no.such.collation"
+ List of collations
+ Schema | Name | Collate | Ctype | ICU Locale | Provider | Deterministic?
+--------+------+---------+-------+------------+----------+----------------
+(0 rows)
+
+\dp "no.such.schema"."no.such.access.privilege"
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+------+------+-------------------+-------------------+----------
+(0 rows)
+
+\dP "no.such.schema"."no.such.partitioned.relation"
+ List of partitioned relations
+ Schema | Name | Owner | Type | Parent name | Table
+--------+------+-------+------+-------------+-------
+(0 rows)
+
+\drds "no.such.schema"."no.such.setting"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.setting"
+\dRp "no.such.schema"."no.such.publication"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.publication"
+\dRs "no.such.schema"."no.such.subscription"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.subscription"
+\dT "no.such.schema"."no.such.data.type"
+ List of data types
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dx "no.such.schema"."no.such.installed.extension"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.installed.extension"
+\dX "no.such.schema"."no.such.extended.statistics"
+ List of extended statistics
+ Schema | Name | Definition | Ndistinct | Dependencies | MCV
+--------+------+------------+-----------+--------------+-----
+(0 rows)
+
+\dy "no.such.schema"."no.such.event.trigger"
+improper qualified name (too many dotted names): "no.such.schema"."no.such.event.trigger"
+-- again, but with current database and dotted schema qualifications.
+\dt regression."no.such.schema"."no.such.table.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\da regression."no.such.schema"."no.such.aggregate.function"
+ List of aggregate functions
+ Schema | Name | Result data type | Argument data types | Description
+--------+------+------------------+---------------------+-------------
+(0 rows)
+
+\dc regression."no.such.schema"."no.such.conversion"
+ List of conversions
+ Schema | Name | Source | Destination | Default?
+--------+------+--------+-------------+----------
+(0 rows)
+
+\dC regression."no.such.schema"."no.such.cast"
+ List of casts
+ Source type | Target type | Function | Implicit?
+-------------+-------------+----------+-----------
+(0 rows)
+
+\dd regression."no.such.schema"."no.such.object.description"
+ Object descriptions
+ Schema | Name | Object | Description
+--------+------+--------+-------------
+(0 rows)
+
+\dD regression."no.such.schema"."no.such.domain"
+ List of domains
+ Schema | Name | Type | Collation | Nullable | Default | Check
+--------+------+------+-----------+----------+---------+-------
+(0 rows)
+
+\di regression."no.such.schema"."no.such.index.relation"
+ List of relations
+ Schema | Name | Type | Owner | Table
+--------+------+------+-------+-------
+(0 rows)
+
+\dm regression."no.such.schema"."no.such.materialized.view"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\ds regression."no.such.schema"."no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\dt regression."no.such.schema"."no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\dv regression."no.such.schema"."no.such.relation"
+ List of relations
+ Schema | Name | Type | Owner
+--------+------+------+-------
+(0 rows)
+
+\df regression."no.such.schema"."no.such.function"
+ List of functions
+ Schema | Name | Result data type | Argument data types | Type
+--------+------+------------------+---------------------+------
+(0 rows)
+
+\dF regression."no.such.schema"."no.such.text.search.configuration"
+List of text search configurations
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFd regression."no.such.schema"."no.such.text.search.dictionary"
+List of text search dictionaries
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFp regression."no.such.schema"."no.such.text.search.parser"
+ List of text search parsers
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dFt regression."no.such.schema"."no.such.text.search.template"
+List of text search templates
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\do regression."no.such.schema"."no.such.operator"
+ List of operators
+ Schema | Name | Left arg type | Right arg type | Result type | Description
+--------+------+---------------+----------------+-------------+-------------
+(0 rows)
+
+\dO regression."no.such.schema"."no.such.collation"
+ List of collations
+ Schema | Name | Collate | Ctype | ICU Locale | Provider | Deterministic?
+--------+------+---------+-------+------------+----------+----------------
+(0 rows)
+
+\dp regression."no.such.schema"."no.such.access.privilege"
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+------+------+-------------------+-------------------+----------
+(0 rows)
+
+\dP regression."no.such.schema"."no.such.partitioned.relation"
+ List of partitioned relations
+ Schema | Name | Owner | Type | Parent name | Table
+--------+------+-------+------+-------------+-------
+(0 rows)
+
+\dT regression."no.such.schema"."no.such.data.type"
+ List of data types
+ Schema | Name | Description
+--------+------+-------------
+(0 rows)
+
+\dX regression."no.such.schema"."no.such.extended.statistics"
+ List of extended statistics
+ Schema | Name | Definition | Ndistinct | Dependencies | MCV
+--------+------+------------+-----------+--------------+-----
+(0 rows)
+
+-- again, but with dotted database and dotted schema qualifications.
+\dt "no.such.database"."no.such.schema"."no.such.table.relation"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.table.relation"
+\da "no.such.database"."no.such.schema"."no.such.aggregate.function"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.aggregate.function"
+\dc "no.such.database"."no.such.schema"."no.such.conversion"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.conversion"
+\dC "no.such.database"."no.such.schema"."no.such.cast"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.cast"
+\dd "no.such.database"."no.such.schema"."no.such.object.description"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.object.description"
+\dD "no.such.database"."no.such.schema"."no.such.domain"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.domain"
+\ddp "no.such.database"."no.such.schema"."no.such.default.access.privilege"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.default.access.privilege"
+\di "no.such.database"."no.such.schema"."no.such.index.relation"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.index.relation"
+\dm "no.such.database"."no.such.schema"."no.such.materialized.view"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.materialized.view"
+\ds "no.such.database"."no.such.schema"."no.such.relation"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.relation"
+\dt "no.such.database"."no.such.schema"."no.such.relation"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.relation"
+\dv "no.such.database"."no.such.schema"."no.such.relation"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.relation"
+\df "no.such.database"."no.such.schema"."no.such.function"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.function"
+\dF "no.such.database"."no.such.schema"."no.such.text.search.configuration"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.text.search.configuration"
+\dFd "no.such.database"."no.such.schema"."no.such.text.search.dictionary"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.text.search.dictionary"
+\dFp "no.such.database"."no.such.schema"."no.such.text.search.parser"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.text.search.parser"
+\dFt "no.such.database"."no.such.schema"."no.such.text.search.template"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.text.search.template"
+\do "no.such.database"."no.such.schema"."no.such.operator"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.operator"
+\dO "no.such.database"."no.such.schema"."no.such.collation"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.collation"
+\dp "no.such.database"."no.such.schema"."no.such.access.privilege"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.access.privilege"
+\dP "no.such.database"."no.such.schema"."no.such.partitioned.relation"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.partitioned.relation"
+\dT "no.such.database"."no.such.schema"."no.such.data.type"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.data.type"
+\dX "no.such.database"."no.such.schema"."no.such.extended.statistics"
+cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.extended.statistics"
\echo '# final ON_ERROR_ROLLBACK:' :ON_ERROR_ROLLBACK
DROP TABLE bla;
DROP FUNCTION psql_error;
+
+-- check describing invalid multipart names
+\dA regression.heap
+\dA nonesuch.heap
+\dt host.regression.pg_catalog.pg_class
+\dt |.pg_catalog.pg_class
+\dt nonesuch.pg_catalog.pg_class
+\da host.regression.pg_catalog.sum
+\da +.pg_catalog.sum
+\da nonesuch.pg_catalog.sum
+\dAc nonesuch.brin
+\dAc regression.brin
+\dAf nonesuch.brin
+\dAf regression.brin
+\dAo nonesuch.brin
+\dAo regression.brin
+\dAp nonesuch.brin
+\dAp regression.brin
+\db nonesuch.pg_default
+\db regression.pg_default
+\dc host.regression.public.conversion
+\dc (.public.conversion
+\dc nonesuch.public.conversion
+\dC host.regression.pg_catalog.int8
+\dC ).pg_catalog.int8
+\dC nonesuch.pg_catalog.int8
+\dd host.regression.pg_catalog.pg_class
+\dd [.pg_catalog.pg_class
+\dd nonesuch.pg_catalog.pg_class
+\dD host.regression.public.gtestdomain1
+\dD ].public.gtestdomain1
+\dD nonesuch.public.gtestdomain1
+\ddp host.regression.pg_catalog.pg_class
+\ddp {.pg_catalog.pg_class
+\ddp nonesuch.pg_catalog.pg_class
+\dE host.regression.public.ft
+\dE }.public.ft
+\dE nonesuch.public.ft
+\di host.regression.public.tenk1_hundred
+\di ..public.tenk1_hundred
+\di nonesuch.public.tenk1_hundred
+\dm host.regression.public.mvtest_bb
+\dm ^.public.mvtest_bb
+\dm nonesuch.public.mvtest_bb
+\ds host.regression.public.check_seq
+\ds regression|mydb.public.check_seq
+\ds nonesuch.public.check_seq
+\dt host.regression.public.b_star
+\dt regres+ion.public.b_star
+\dt nonesuch.public.b_star
+\dv host.regression.public.shoe
+\dv regress(ion).public.shoe
+\dv nonesuch.public.shoe
+\des nonesuch.server
+\des regression.server
+\des nonesuch.server
+\des regression.server
+\des nonesuch.username
+\des regression.username
+\dew nonesuch.fdw
+\dew regression.fdw
+\df host.regression.public.namelen
+\df regres[qrstuv]ion.public.namelen
+\df nonesuch.public.namelen
+\dF host.regression.pg_catalog.arabic
+\dF regres{1,2}ion.pg_catalog.arabic
+\dF nonesuch.pg_catalog.arabic
+\dFd host.regression.pg_catalog.arabic_stem
+\dFd regres?ion.pg_catalog.arabic_stem
+\dFd nonesuch.pg_catalog.arabic_stem
+\dFp host.regression.pg_catalog.default
+\dFp ^regression.pg_catalog.default
+\dFp nonesuch.pg_catalog.default
+\dFt host.regression.pg_catalog.ispell
+\dFt regression$.pg_catalog.ispell
+\dFt nonesuch.pg_catalog.ispell
+\dg nonesuch.pg_database_owner
+\dg regression.pg_database_owner
+\dL host.regression.plpgsql
+\dL *.plpgsql
+\dL nonesuch.plpgsql
+\dn host.regression.public
+\dn """".public
+\dn nonesuch.public
+\do host.regression.public.!=-
+\do "regression|mydb".public.!=-
+\do nonesuch.public.!=-
+\dO host.regression.pg_catalog.POSIX
+\dO .pg_catalog.POSIX
+\dO nonesuch.pg_catalog.POSIX
+\dp host.regression.public.a_star
+\dp "regres+ion".public.a_star
+\dp nonesuch.public.a_star
+\dP host.regression.public.mlparted
+\dP "regres(sion)".public.mlparted
+\dP nonesuch.public.mlparted
+\drds nonesuch.lc_messages
+\drds regression.lc_messages
+\dRp public.mypub
+\dRp regression.mypub
+\dRs public.mysub
+\dRs regression.mysub
+\dT host.regression.public.widget
+\dT "regression{1,2}".public.widget
+\dT nonesuch.public.widget
+\dx regression.plpgsql
+\dx nonesuch.plpgsql
+\dX host.regression.public.func_deps_stat
+\dX "^regression$".public.func_deps_stat
+\dX nonesuch.public.func_deps_stat
+\dy regression.myevt
+\dy nonesuch.myevt
+
+-- check that dots within quoted name segments are not counted
+\dA "no.such.access.method"
+\dt "no.such.table.relation"
+\da "no.such.aggregate.function"
+\dAc "no.such.operator.class"
+\dAf "no.such.operator.family"
+\dAo "no.such.operator.of.operator.family"
+\dAp "no.such.operator.support.function.of.operator.family"
+\db "no.such.tablespace"
+\dc "no.such.conversion"
+\dC "no.such.cast"
+\dd "no.such.object.description"
+\dD "no.such.domain"
+\ddp "no.such.default.access.privilege"
+\di "no.such.index.relation"
+\dm "no.such.materialized.view"
+\ds "no.such.relation"
+\dt "no.such.relation"
+\dv "no.such.relation"
+\des "no.such.foreign.server"
+\dew "no.such.foreign.data.wrapper"
+\df "no.such.function"
+\dF "no.such.text.search.configuration"
+\dFd "no.such.text.search.dictionary"
+\dFp "no.such.text.search.parser"
+\dFt "no.such.text.search.template"
+\dg "no.such.role"
+\dL "no.such.language"
+\dn "no.such.schema"
+\do "no.such.operator"
+\dO "no.such.collation"
+\dp "no.such.access.privilege"
+\dP "no.such.partitioned.relation"
+\drds "no.such.setting"
+\dRp "no.such.publication"
+\dRs "no.such.subscription"
+\dT "no.such.data.type"
+\dx "no.such.installed.extension"
+\dX "no.such.extended.statistics"
+\dy "no.such.event.trigger"
+
+-- again, but with dotted schema qualifications.
+\dA "no.such.schema"."no.such.access.method"
+\dt "no.such.schema"."no.such.table.relation"
+\da "no.such.schema"."no.such.aggregate.function"
+\dAc "no.such.schema"."no.such.operator.class"
+\dAf "no.such.schema"."no.such.operator.family"
+\dAo "no.such.schema"."no.such.operator.of.operator.family"
+\dAp "no.such.schema"."no.such.operator.support.function.of.operator.family"
+\db "no.such.schema"."no.such.tablespace"
+\dc "no.such.schema"."no.such.conversion"
+\dC "no.such.schema"."no.such.cast"
+\dd "no.such.schema"."no.such.object.description"
+\dD "no.such.schema"."no.such.domain"
+\ddp "no.such.schema"."no.such.default.access.privilege"
+\di "no.such.schema"."no.such.index.relation"
+\dm "no.such.schema"."no.such.materialized.view"
+\ds "no.such.schema"."no.such.relation"
+\dt "no.such.schema"."no.such.relation"
+\dv "no.such.schema"."no.such.relation"
+\des "no.such.schema"."no.such.foreign.server"
+\dew "no.such.schema"."no.such.foreign.data.wrapper"
+\df "no.such.schema"."no.such.function"
+\dF "no.such.schema"."no.such.text.search.configuration"
+\dFd "no.such.schema"."no.such.text.search.dictionary"
+\dFp "no.such.schema"."no.such.text.search.parser"
+\dFt "no.such.schema"."no.such.text.search.template"
+\dg "no.such.schema"."no.such.role"
+\dL "no.such.schema"."no.such.language"
+\do "no.such.schema"."no.such.operator"
+\dO "no.such.schema"."no.such.collation"
+\dp "no.such.schema"."no.such.access.privilege"
+\dP "no.such.schema"."no.such.partitioned.relation"
+\drds "no.such.schema"."no.such.setting"
+\dRp "no.such.schema"."no.such.publication"
+\dRs "no.such.schema"."no.such.subscription"
+\dT "no.such.schema"."no.such.data.type"
+\dx "no.such.schema"."no.such.installed.extension"
+\dX "no.such.schema"."no.such.extended.statistics"
+\dy "no.such.schema"."no.such.event.trigger"
+
+-- again, but with current database and dotted schema qualifications.
+\dt regression."no.such.schema"."no.such.table.relation"
+\da regression."no.such.schema"."no.such.aggregate.function"
+\dc regression."no.such.schema"."no.such.conversion"
+\dC regression."no.such.schema"."no.such.cast"
+\dd regression."no.such.schema"."no.such.object.description"
+\dD regression."no.such.schema"."no.such.domain"
+\di regression."no.such.schema"."no.such.index.relation"
+\dm regression."no.such.schema"."no.such.materialized.view"
+\ds regression."no.such.schema"."no.such.relation"
+\dt regression."no.such.schema"."no.such.relation"
+\dv regression."no.such.schema"."no.such.relation"
+\df regression."no.such.schema"."no.such.function"
+\dF regression."no.such.schema"."no.such.text.search.configuration"
+\dFd regression."no.such.schema"."no.such.text.search.dictionary"
+\dFp regression."no.such.schema"."no.such.text.search.parser"
+\dFt regression."no.such.schema"."no.such.text.search.template"
+\do regression."no.such.schema"."no.such.operator"
+\dO regression."no.such.schema"."no.such.collation"
+\dp regression."no.such.schema"."no.such.access.privilege"
+\dP regression."no.such.schema"."no.such.partitioned.relation"
+\dT regression."no.such.schema"."no.such.data.type"
+\dX regression."no.such.schema"."no.such.extended.statistics"
+
+-- again, but with dotted database and dotted schema qualifications.
+\dt "no.such.database"."no.such.schema"."no.such.table.relation"
+\da "no.such.database"."no.such.schema"."no.such.aggregate.function"
+\dc "no.such.database"."no.such.schema"."no.such.conversion"
+\dC "no.such.database"."no.such.schema"."no.such.cast"
+\dd "no.such.database"."no.such.schema"."no.such.object.description"
+\dD "no.such.database"."no.such.schema"."no.such.domain"
+\ddp "no.such.database"."no.such.schema"."no.such.default.access.privilege"
+\di "no.such.database"."no.such.schema"."no.such.index.relation"
+\dm "no.such.database"."no.such.schema"."no.such.materialized.view"
+\ds "no.such.database"."no.such.schema"."no.such.relation"
+\dt "no.such.database"."no.such.schema"."no.such.relation"
+\dv "no.such.database"."no.such.schema"."no.such.relation"
+\df "no.such.database"."no.such.schema"."no.such.function"
+\dF "no.such.database"."no.such.schema"."no.such.text.search.configuration"
+\dFd "no.such.database"."no.such.schema"."no.such.text.search.dictionary"
+\dFp "no.such.database"."no.such.schema"."no.such.text.search.parser"
+\dFt "no.such.database"."no.such.schema"."no.such.text.search.template"
+\do "no.such.database"."no.such.schema"."no.such.operator"
+\dO "no.such.database"."no.such.schema"."no.such.collation"
+\dp "no.such.database"."no.such.schema"."no.such.access.privilege"
+\dP "no.such.database"."no.such.schema"."no.such.partitioned.relation"
+\dT "no.such.database"."no.such.schema"."no.such.data.type"
+\dX "no.such.database"."no.such.schema"."no.such.extended.statistics"