From 2bcc43b6f664d0c47cab6d9f5814ea1af3ae8937 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 22 Mar 2022 13:55:15 -0400
Subject: [PATCH 2/2] Remove dbname_is_literal stuff.

---
 src/bin/pg_amcheck/pg_amcheck.c     |  6 ++---
 src/bin/pg_dump/pg_dump.c           | 20 +++------------
 src/bin/pg_dump/pg_dumpall.c        |  2 +-
 src/bin/pg_dump/t/002_pg_dump.pl    |  6 -----
 src/bin/psql/describe.c             | 21 +++++----------
 src/fe_utils/string_utils.c         | 40 ++++++++---------------------
 src/include/fe_utils/string_utils.h |  6 ++---
 src/test/regress/expected/psql.out  | 34 ++++++++++++------------
 8 files changed, 43 insertions(+), 92 deletions(-)

diff --git a/src/bin/pg_amcheck/pg_amcheck.c b/src/bin/pg_amcheck/pg_amcheck.c
index 80fffb1d2e..522dccf15a 100644
--- a/src/bin/pg_amcheck/pg_amcheck.c
+++ b/src/bin/pg_amcheck/pg_amcheck.c
@@ -1339,7 +1339,7 @@ append_database_pattern(PatternInfoArray *pia, const char *pattern, int encoding
 
 	initPQExpBuffer(&buf);
 	patternToSQLRegex(encoding, NULL, NULL, &buf, pattern, false, false,
-					  &dotcnt, NULL);
+					  &dotcnt);
 	if (dotcnt > 0)
 	{
 		pg_log_error("improper qualified name (too many dotted names): %s", pattern);
@@ -1372,7 +1372,7 @@ append_schema_pattern(PatternInfoArray *pia, const char *pattern, int encoding)
 	initPQExpBuffer(&nspbuf);
 
 	patternToSQLRegex(encoding, NULL, &dbbuf, &nspbuf, pattern, false, false,
-					  &dotcnt, NULL);
+					  &dotcnt);
 	if (dotcnt > 1)
 	{
 		pg_log_error("improper qualified name (too many dotted names): %s", pattern);
@@ -1417,7 +1417,7 @@ append_relation_pattern_helper(PatternInfoArray *pia, const char *pattern,
 	initPQExpBuffer(&relbuf);
 
 	patternToSQLRegex(encoding, &dbbuf, &nspbuf, &relbuf, pattern, false,
-					  false, &dotcnt, NULL);
+					  false, &dotcnt);
 	if (dotcnt > 2)
 	{
 		pg_log_error("improper relation name (too many dotted names): %s", pattern);
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 998601ad0c..f93afc9427 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1326,23 +1326,18 @@ expand_schema_name_patterns(Archive *fout,
 	{
 		PQExpBufferData	dbbuf;
 		int		dotcnt;
-		bool	dbname_is_literal;
 
 		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, &dbbuf,
-							  &dotcnt, &dbname_is_literal);
+							  &dotcnt);
 		if (dotcnt > 1)
 			fatal("improper qualified name (too many dotted names): %s",
 				  cell->val);
 		else if (dotcnt == 1)
-		{
-			if (!dbname_is_literal)
-				fatal("database name must be literal: %s", cell->val);
 			prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
-		}
 		termPQExpBuffer(&dbbuf);
 
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -1388,13 +1383,12 @@ expand_extension_name_patterns(Archive *fout,
 	for (cell = patterns->head; cell; cell = cell->next)
 	{
 		int		dotcnt;
-		bool	dbname_is_literal;
 
 		appendPQExpBufferStr(query,
 							 "SELECT oid FROM pg_catalog.pg_extension e\n");
 		processSQLNamePattern(GetConnection(fout), query, cell->val, false,
 							  false, NULL, "e.extname", NULL, NULL, NULL,
-							  &dotcnt, &dbname_is_literal);
+							  &dotcnt);
 		if (dotcnt > 0)
 			fatal("improper qualified name (too many dotted names): %s",
 				  cell->val);
@@ -1442,13 +1436,12 @@ expand_foreign_server_name_patterns(Archive *fout,
 	for (cell = patterns->head; cell; cell = cell->next)
 	{
 		int		dotcnt;
-		bool	dbname_is_literal;
 
 		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, NULL,
-							  &dotcnt, &dbname_is_literal);
+							  &dotcnt);
 		if (dotcnt > 0)
 			fatal("improper qualified name (too many dotted names): %s",
 				  cell->val);
@@ -1496,7 +1489,6 @@ expand_table_name_patterns(Archive *fout,
 	{
 		PQExpBufferData	dbbuf;
 		int		dotcnt;
-		bool	dbname_is_literal;
 
 		/*
 		 * Query must remain ABSOLUTELY devoid of unqualified names.  This
@@ -1517,16 +1509,12 @@ expand_table_name_patterns(Archive *fout,
 		processSQLNamePattern(GetConnection(fout), query, cell->val, true,
 							  false, "n.nspname", "c.relname", NULL,
 							  "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
-							  &dotcnt, &dbname_is_literal);
+							  &dotcnt);
 		if (dotcnt > 2)
 			fatal("improper relation name (too many dotted names): %s",
 				  cell->val);
 		else if (dotcnt == 2)
-		{
-			if (!dbname_is_literal)
-				fatal("database name must be literal: %s", cell->val);
 			prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
-		}
 		termPQExpBuffer(&dbbuf);
 
 		ExecuteSqlStatement(fout, "RESET search_path");
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 6e16371314..c35fb05ee5 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -1232,7 +1232,7 @@ expand_dbname_patterns(PGconn *conn,
 							 "SELECT datname FROM pg_catalog.pg_database n\n");
 		processSQLNamePattern(conn, query, cell->val, false,
 							  false, NULL, "datname", NULL, NULL, NULL,
-							  &dotcnt, NULL);
+							  &dotcnt);
 
 		if (dotcnt > 0)
 		{
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 48b42bda1f..8c52e11ee3 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -3901,12 +3901,6 @@ $node->command_fails_like(
 	'pg_dump: option --table rejects cross-database three part table names'
 );
 
-$node->command_fails_like(
-	[ 'pg_dump', '--table', 'ma??.pg_catalog.pg_class' ],
-	qr/pg_dump: error: database name must be literal: ma\?\?\.pg_catalog\.pg_class/,
-	'pg_dump: option --table rejects non-literal database name'
-);
-
 #########################################
 # Run all runs
 
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index ee585084b1..a34f1713a1 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -5920,14 +5920,12 @@ validateSQLNamePattern(PQExpBuffer buf, const char *pattern, bool have_where,
 {
 	PQExpBufferData	dbbuf;
 	int			dotcnt;
-	bool		dbname_is_literal;
 	bool		added;
 
 	initPQExpBuffer(&dbbuf);
 	added = processSQLNamePattern(pset.db, buf, pattern, have_where, force_escape,
 								  schemavar, namevar, altnamevar,
-								  visibilityrule, &dbbuf, &dotcnt,
-								  &dbname_is_literal);
+								  visibilityrule, &dbbuf, &dotcnt);
 	if (added_clause != NULL)
 		*added_clause = added;
 
@@ -5939,19 +5937,12 @@ validateSQLNamePattern(PQExpBuffer buf, const char *pattern, bool have_where,
 		return false;
 	}
 
-	if (maxparts > 1 && dotcnt == maxparts-1)
+	if (maxparts > 1 && dotcnt == maxparts-1 &&
+		((PQdb(pset.db) == NULL || strcmp(PQdb(pset.db), dbbuf.data) != 0)))
 	{
-		if (!dbname_is_literal)
-		{
-			pg_log_error("database name must be literal: %s", pattern);
-			return false;
-		}
-		else if (PQdb(pset.db) == NULL || strcmp(PQdb(pset.db), dbbuf.data) != 0)
-		{
-			pg_log_error("cross-database references are not implemented: %s",
-						 pattern);
-			return false;
-		}
+		pg_log_error("cross-database references are not implemented: %s",
+					 pattern);
+		return false;
 	}
 	return true;
 }
diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c
index 5e7da77147..5122f8f8e5 100644
--- a/src/fe_utils/string_utils.c
+++ b/src/fe_utils/string_utils.c
@@ -893,7 +893,7 @@ 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,
-					  PQExpBuffer db, int *dotcnt, bool *dbname_is_literal)
+					  PQExpBuffer db, int *dotcnt)
 {
 	PQExpBufferData schemabuf;
 	PQExpBufferData namebuf;
@@ -935,7 +935,7 @@ processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern,
 	 * using appendStringLiteralConn().
 	 */
 	patternToSQLRegex(PQclientEncoding(conn), db, schema, name, pattern,
-					  force_escape, true, dotcnt, dbname_is_literal);
+					  force_escape, true, dotcnt);
 
 	/*
 	 * Now decide what we need to emit.  We may run under a hostile
@@ -1046,8 +1046,7 @@ processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern,
 void
 patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, PQExpBuffer schemabuf,
 				  PQExpBuffer namebuf, const char *pattern, bool force_escape,
-				  bool want_literal_dbname, int *dotcnt,
-				  bool *dbname_is_literal)
+				  bool want_literal_dbname, int *dotcnt)
 {
 	PQExpBufferData buf[3];
 	PQExpBufferData left_literal;
@@ -1055,8 +1054,7 @@ patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, PQExpBuffer schemabuf,
 	PQExpBuffer maxbuf;
 	int			i;
 	bool		inquotes;
-	bool		left,
-				left_is_literal;
+	bool		left;
 	const char *cp;
 
 	Assert(pattern != NULL);
@@ -1078,7 +1076,6 @@ patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, PQExpBuffer schemabuf,
 	left = true;
 	if (want_literal_dbname)
 		initPQExpBuffer(&left_literal);
-	left_is_literal = true;
 	initPQExpBuffer(curbuf);
 	appendPQExpBufferStr(curbuf, "^(");
 	while (*cp)
@@ -1111,23 +1108,15 @@ patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, PQExpBuffer schemabuf,
 		else if (!inquotes && ch == '*')
 		{
 			appendPQExpBufferStr(curbuf, ".*");
-			if (left)
-			{
-				if (want_literal_dbname)
-					appendPQExpBufferChar(&left_literal, '*');
-				left_is_literal = false;
-			}
+			if (left && want_literal_dbname)
+				appendPQExpBufferChar(&left_literal, '*');
 			cp++;
 		}
 		else if (!inquotes && ch == '?')
 		{
 			appendPQExpBufferChar(curbuf, '.');
-			if (left)
-			{
-				if (want_literal_dbname)
-					appendPQExpBufferChar(&left_literal, '?');
-				left_is_literal = false;
-			}
+			if (left && want_literal_dbname)
+				appendPQExpBufferChar(&left_literal, '?');
 			cp++;
 		}
 		else if (!inquotes && ch == '.')
@@ -1183,13 +1172,8 @@ patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, PQExpBuffer schemabuf,
 			i = PQmblenBounded(cp, encoding);
 			while (i--)
 			{
-				if (left)
-				{
-					if (want_literal_dbname)
-						appendPQExpBufferChar(&left_literal, *cp);
-					if (!inquotes && strchr("|+()[]{}.^\\", *cp))
-						left_is_literal = false;
-				}
+				if (left && want_literal_dbname)
+					appendPQExpBufferChar(&left_literal, *cp);
 				appendPQExpBufferChar(curbuf, *cp++);
 			}
 		}
@@ -1217,9 +1201,5 @@ patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, PQExpBuffer schemabuf,
 		else
 			appendPQExpBufferStr(dbnamebuf, curbuf->data);
 		termPQExpBuffer(curbuf);
-		if (dbname_is_literal)
-			*dbname_is_literal = left_is_literal;
 	}
-	else if (dbname_is_literal)
-		*dbname_is_literal = true;		/* treat empty dbname as literal */
 }
diff --git a/src/include/fe_utils/string_utils.h b/src/include/fe_utils/string_utils.h
index 30f4c9caf7..47287c9807 100644
--- a/src/include/fe_utils/string_utils.h
+++ b/src/include/fe_utils/string_utils.h
@@ -56,13 +56,11 @@ extern bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf,
 								  bool have_where, bool force_escape,
 								  const char *schemavar, const char *namevar,
 								  const char *altnamevar, const char *visibilityrule,
-								  PQExpBuffer db, int *dotcnt,
-								  bool *dbname_is_literal);
+								  PQExpBuffer db, int *dotcnt);
 
 extern void patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf,
 							  PQExpBuffer schemabuf, PQExpBuffer namebuf,
 							  const char *pattern, bool force_escape,
-							  bool want_literal_dbname, int *dotcnt,
-							  bool *dbname_is_literal);
+							  bool want_literal_dbname, int *dotcnt);
 
 #endif							/* STRING_UTILS_H */
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index bcf32f7d83..64d8cba5a2 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -5298,13 +5298,13 @@ 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
-database name must be literal: |.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
-database name must be literal: +.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
@@ -5330,37 +5330,37 @@ 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
-database name must be literal: (.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
-database name must be literal: ).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
-database name must be literal: [.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
-database name must be literal: ].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
-database name must be literal: {.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
-database name must be literal: }.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
@@ -5372,25 +5372,25 @@ 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
-database name must be literal: ^.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
-database name must be literal: 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
-database name must be literal: 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
-database name must be literal: 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
@@ -5412,25 +5412,25 @@ 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
-database name must be literal: 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
-database name must be literal: 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
-database name must be literal: 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
-database name must be literal: ^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
@@ -5446,7 +5446,7 @@ 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
-database name must be literal: *.plpgsql
+cross-database references are not implemented: *.plpgsql
 \dL nonesuch.plpgsql
 cross-database references are not implemented: nonesuch.plpgsql
 \dn host.regression.public
-- 
2.24.3 (Apple Git-128)

