]> granicus.if.org Git - postgresql/commitdiff
Fix some issues and improve psql completion for access methods
authorMichael Paquier <michael@paquier.xyz>
Mon, 3 Jun 2019 02:02:32 +0000 (11:02 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 3 Jun 2019 02:02:32 +0000 (11:02 +0900)
The following issues have been spotted:
- CREATE INDEX .. USING suggests both index and table AMs, but it should
consider only index AMs.
- CREATE TABLE .. USING has no completion support.  USING was not being
included in the completion list where it should, and follow-up
suggestions for table AMs have been missing as well.
- CREATE ACCESS METHOD .. TYPE suggests only INDEX, with TABLE missing.

Author: Michael Paquier
Discussion: https://postgr.es/m/20190601191007.GC1905@paquier.xyz

src/bin/psql/tab-complete.c

index c6347b619004b08886bfabada9f76d1688bc65db..5e38f463999858e4515cfab524b91dcb059760ab 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <ctype.h>
 
+#include "catalog/pg_am_d.h"
 #include "catalog/pg_class_d.h"
 
 #include "libpq-fe.h"
@@ -824,6 +825,18 @@ static const SchemaQuery Query_for_list_of_statistics = {
 "   FROM pg_catalog.pg_am "\
 "  WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s'"
 
+#define Query_for_list_of_index_access_methods \
+" SELECT pg_catalog.quote_ident(amname) "\
+"   FROM pg_catalog.pg_am "\
+"  WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s' AND "\
+"   amtype=" CppAsString2(AMTYPE_INDEX)
+
+#define Query_for_list_of_table_access_methods \
+" SELECT pg_catalog.quote_ident(amname) "\
+"   FROM pg_catalog.pg_am "\
+"  WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s' AND "\
+"   amtype=" CppAsString2(AMTYPE_TABLE)
+
 /* the silly-looking length condition is just to eat up the current word */
 #define Query_for_list_of_arguments \
 "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\
@@ -2234,7 +2247,7 @@ psql_completion(const char *text, int start, int end)
                COMPLETE_WITH("TYPE");
        /* Complete "CREATE ACCESS METHOD <name> TYPE" */
        else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE"))
-               COMPLETE_WITH("INDEX");
+               COMPLETE_WITH("INDEX", "TABLE");
        /* Complete "CREATE ACCESS METHOD <name> TYPE <type>" */
        else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny))
                COMPLETE_WITH("HANDLER");
@@ -2322,7 +2335,7 @@ psql_completion(const char *text, int start, int end)
        else if (TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") ||
                         TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING") ||
                         TailMatches("INDEX", "ON", MatchAny, "USING"))
-               COMPLETE_WITH_QUERY(Query_for_list_of_access_methods);
+               COMPLETE_WITH_QUERY(Query_for_list_of_index_access_methods);
        else if (TailMatches("ON", MatchAny, "USING", MatchAny) &&
                         !TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) &&
                         !TailMatches("FOR", MatchAny, MatchAny, MatchAny))
@@ -2490,10 +2503,14 @@ psql_completion(const char *text, int start, int end)
        /* Complete CREATE TABLE name (...) with supported options */
        else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)") ||
                         TailMatches("CREATE", "UNLOGGED", "TABLE", MatchAny, "(*)"))
-               COMPLETE_WITH("INHERITS (", "PARTITION BY", "TABLESPACE", "WITH (");
+               COMPLETE_WITH("INHERITS (", "PARTITION BY", "USING", "TABLESPACE", "WITH (");
        else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)"))
                COMPLETE_WITH("INHERITS (", "ON COMMIT", "PARTITION BY",
                                          "TABLESPACE", "WITH (");
+       /* Complete CREATE TABLE (...) USING with table access methods */
+       else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "USING") ||
+                        TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "USING"))
+               COMPLETE_WITH_QUERY(Query_for_list_of_table_access_methods);
        /* Complete CREATE TABLE (...) WITH with storage parameters */
        else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "WITH", "(") ||
                         TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "WITH", "("))