Hello, I found that COMPLETE_SCHEMA_QUERY doesn't complete
only-one-matching schema names.

=# alter foreign table <tab>
information_schema.  pg_temp_1.           pg_toast_temp_1.
pg_catalog.          pg_toast.            public.
=# alter foreign table i<tab>
<no complition>

or 

=# alter foreign table pu<tab>
<no complition>

This makes more perplexing behavior with addon query.

=# create schema alpha;
=# alter table <tab>
ALL IN TABLESPACE    pg_catalog.          pg_toast_temp_1.
alpha.               pg_temp_1.           public.
information_schema.  pg_toast.            
=# alter table a<tab>
=# alter table ALL IN TABLESPACE _

Where my alpha has gone?

_complete_from_query adds schema names only if more than one
shcmea names match the current input. The 'i' matches only one
schema name. The reason for the behavior seems not to add a
schema name when qualified names in the schema is added. So the
attached patch does exactly the thing to do. psql behaves as the
following with this patch.

=# create schema alpha;
=# create table alpha.a (a int);
=# create table alpha.b (a int);
=# alter table <tab>
ALL IN TABLESPACE    pg_catalog.          pg_toast_temp_1.
alpha.               pg_temp_1.           public.
information_schema.  pg_toast.            
=# alter table al<tab>
ALL IN TABLESPACE  alpha.a            alpha.b            
=# alter table alp<tab>
=# alter table alpha.
alpha.a  alpha.b  

This seems to me the intended behavior here.

Any comments?

regards,

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
>From c3a1220ecec07af660fc184e5a1d24baa1fe913b Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyot...@lab.ntt.co.jp>
Date: Tue, 29 Mar 2016 12:13:03 +0900
Subject: [PATCH] Fix the condition to decide whether to add schema names.

Currently, COMPLETE_WITH_SCHEMA_QUERY stops completetion for the only
matching schema name for the current input. Schema names are added
only when there's more than one matches for current input but the
correct condition is that there's no qualified names to match. No
qualified names is listed only when there's exactly one matching
schema name.
---
 src/bin/psql/tab-complete.c | 52 ++++++++++++++++++++++++---------------------
 1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 6a81416..631d0d7 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3206,7 +3206,7 @@ _complete_from_query(int is_schema_query, const char *text, int state)
 	 */
 	if (state == 0)
 	{
-		PQExpBufferData query_buffer;
+		PQExpBufferData query_buffer, tmp_buffer;
 		char	   *e_text;
 		char	   *e_info_charp;
 		char	   *e_info_charp2;
@@ -3279,26 +3279,12 @@ _complete_from_query(int is_schema_query, const char *text, int state)
 			}
 
 			/*
-			 * Add in matching schema names, but only if there is more than
-			 * one potential match among schema names.
+			 * Make query to collect matching qualified names, but only if
+			 * there is exactly one schema matching the input-so-far. This
+			 * query is made separatedly since used twice.
 			 */
-			appendPQExpBuffer(&query_buffer, "\nUNION\n"
-						   "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
-							  "FROM pg_catalog.pg_namespace n "
-							  "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
-							  char_length, e_text);
-			appendPQExpBuffer(&query_buffer,
-							  " AND (SELECT pg_catalog.count(*)"
-							  " FROM pg_catalog.pg_namespace"
-			" WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
-							  " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1",
-							  char_length, e_text);
-
-			/*
-			 * Add in matching qualified names, but only if there is exactly
-			 * one schema matching the input-so-far.
-			 */
-			appendPQExpBuffer(&query_buffer, "\nUNION\n"
+			initPQExpBuffer(&tmp_buffer);
+			appendPQExpBuffer(&tmp_buffer, 
 					 "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s "
 							  "FROM %s, pg_catalog.pg_namespace n "
 							  "WHERE %s = n.oid AND ",
@@ -3306,9 +3292,9 @@ _complete_from_query(int is_schema_query, const char *text, int state)
 							  completion_squery->catname,
 							  completion_squery->namespace);
 			if (completion_squery->selcondition)
-				appendPQExpBuffer(&query_buffer, "%s AND ",
+				appendPQExpBuffer(&tmp_buffer, "%s AND ",
 								  completion_squery->selcondition);
-			appendPQExpBuffer(&query_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
+			appendPQExpBuffer(&tmp_buffer, "substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s'",
 							  qualresult,
 							  char_length, e_text);
 
@@ -3316,17 +3302,35 @@ _complete_from_query(int is_schema_query, const char *text, int state)
 			 * This condition exploits the single-matching-schema rule to
 			 * speed up the query
 			 */
-			appendPQExpBuffer(&query_buffer,
+			appendPQExpBuffer(&tmp_buffer,
 			" AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) ="
 							  " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1)",
 							  char_length, e_text);
-			appendPQExpBuffer(&query_buffer,
+			appendPQExpBuffer(&tmp_buffer,
 							  " AND (SELECT pg_catalog.count(*)"
 							  " FROM pg_catalog.pg_namespace"
 			" WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) ="
 							  " substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1",
 							  char_length, e_text);
 
+			/*
+			 * Add in matching schema names, but only if there is no matching
+			 * qualified names.
+			 */
+			appendPQExpBuffer(&query_buffer, "\nUNION\n"
+						   "SELECT pg_catalog.quote_ident(n.nspname) || '.' "
+							  "FROM pg_catalog.pg_namespace n "
+							  "WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s'",
+							  char_length, e_text);
+			appendPQExpBuffer(&query_buffer, " AND NOT EXISTS (%s)", tmp_buffer.data);
+
+			/*
+			 * Add in matching qualified names, but only if there is exactly
+			 * one schema matching the input-so-far.
+			 */
+			appendPQExpBuffer(&query_buffer, "\nUNION\n%s", tmp_buffer.data);
+			termPQExpBuffer(&tmp_buffer);
+
 			/* If an addon query was provided, use it */
 			if (completion_charp)
 				appendPQExpBuffer(&query_buffer, "\n%s", completion_charp);
-- 
1.8.3.1

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to