On Mon, Jun 11, 2018 at 11:35:51PM +0300, Arthur Zakirov wrote:
> IMHO, I'd leave the code as simple as possible. It is up to you of
> course. But it is easy to add completion for a first attribute, by
> adding the condition (and leave other attributes without completion):
> 
> else if (HeadMatches1("VACUUM") && TailMatches1("("))
>     COMPLETE_WITH_ATTR(prev2_wd, "");

Thanks - I've done this in the attached.  It works well for having minimal
logic.

On Tue, Jun 05, 2018 at 05:29:42PM +0300, Arthur Zakirov wrote:
> On Sun, Jun 03, 2018 at 10:39:22PM -0500, Justin Pryzby wrote:
> > else if (HeadMatches1("EXPLAIN") && previous_words_count==2 && 
> > prev_wd[0]=='(' && ends_with(prev_wd, ')'))
> 
> I think this condition can be replaced by:
> 
> else if (TailMatches2("EXPLAIN", MatchAny) && ends_with(prev_wd, ')'))

I used:
else if (HeadMatches2("EXPLAIN", MatchAny) && ends_with(prev_wd, ')'))

> > I've done https://commitfest.postgresql.org/18/1661/
> 
> Thank you!

Thanks for your repeated reviews ; if this looks+works fine, please set to
R-F-C.

Actually..another thought: since toast tables may be VACUUM-ed, should I
introduce Query_for_list_of_tpmt ?

Update psql tab completion for commits:                                         
                                                                                
                   
                                                                                
                                                                                
                   
Table completion for ANALYZE partitioned_table
3c3bb99330aa9b4c2f6258bfa0265d806bf365c3

Add parenthesized options syntax for ANALYZE.
854dd8cff523bc17972d34772b0e39ad3d6d46a4

Add VACUUM (DISABLE_PAGE_SKIPPING) for emergencies.
ede62e56fbe809baa1a7bc3873d82f12ffe7540b

Allow multiple tables to be specified in one VACUUM or ANALYZE command.
11d8d72c27a64ea4e30adce11cf6c4f3dd3e60db

Add hash partitioning.
1aba8e651ac3e37e1d2d875842de1e0ed22a651e

Parameter toast_tuple_target
c2513365a0a85e77d3c21adb92fe12cfbe0d1897

Parenthesized explain (...)
d4382c4ae7ea1e272f4fee388aac8ff99421471a

Parameter toast_tuple_target controls TOAST for new rows
c2513365a0a85e77d3c21adb92fe12cfbe0d1897

no longer accepts VACUUM ANALYZE VERBOSE
921059bd66c7fb1230c705d3b1a65940800c4cbb

Justin
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 7bb47ea..e913b83 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -705,6 +705,7 @@ static const SchemaQuery Query_for_list_of_tmf = {
        "pg_catalog.pg_class c",
        /* selcondition */
        "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", "
+       CppAsString2(RELKIND_PARTITIONED_TABLE) ", "
        CppAsString2(RELKIND_MATVIEW) ", "
        CppAsString2(RELKIND_FOREIGN_TABLE) ")",
        /* viscondition */
@@ -2222,6 +2223,7 @@ psql_completion(const char *text, int start, int end)
                        "fillfactor",
                        "parallel_workers",
                        "log_autovacuum_min_duration",
+                       "toast_tuple_target",
                        "toast.autovacuum_enabled",
                        "toast.autovacuum_freeze_max_age",
                        "toast.autovacuum_freeze_min_age",
@@ -2703,7 +2705,7 @@ psql_completion(const char *text, int start, int end)
                COMPLETE_WITH_LIST2("TABLE", "MATERIALIZED VIEW");
        /* Complete PARTITION BY with RANGE ( or LIST ( or ... */
        else if (TailMatches2("PARTITION", "BY"))
-               COMPLETE_WITH_LIST2("RANGE (", "LIST (");
+               COMPLETE_WITH_LIST3("RANGE (", "LIST (", "HASH (");
        /* If we have xxx PARTITION OF, provide a list of partitioned tables */
        else if (TailMatches2("PARTITION", "OF"))
                
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables, "");
@@ -2996,14 +2998,21 @@ psql_completion(const char *text, int start, int end)
        else if (Matches1("EXECUTE"))
                COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements);
 
-/* EXPLAIN */
-
-       /*
-        * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able 
commands
-        */
+/* 
+ * EXPLAIN [ ( option [, ...] ) ] statement
+ * EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
+ */
        else if (Matches1("EXPLAIN"))
-               COMPLETE_WITH_LIST7("SELECT", "INSERT", "DELETE", "UPDATE", 
"DECLARE",
-                                                       "ANALYZE", "VERBOSE");
+               COMPLETE_WITH_LIST8("SELECT", "INSERT", "DELETE", "UPDATE", 
"DECLARE",
+                                                       "ANALYZE", "VERBOSE", 
"(");
+       else if (HeadMatches2("EXPLAIN", "("))
+               if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
+                       COMPLETE_WITH_LIST7("ANALYZE", "VERBOSE", "COSTS", 
"BUFFERS", "TIMING", "SUMMARY", "FORMAT");
+               else
+                       COMPLETE_WITH_LIST4(",", ")", "ON", "OFF");
+       else if (HeadMatches2("EXPLAIN", MatchAny) && ends_with(prev_wd, ')'))
+               /* If the parenthesis are balanced, the list is apparently 
parsed as a single word */
+               COMPLETE_WITH_LIST5("SELECT", "INSERT", "DELETE", "UPDATE", 
"DECLARE");
        else if (Matches2("EXPLAIN", "ANALYZE"))
                COMPLETE_WITH_LIST6("SELECT", "INSERT", "DELETE", "UPDATE", 
"DECLARE",
                                                        "VERBOSE");
@@ -3563,33 +3572,46 @@ psql_completion(const char *text, int start, int end)
                COMPLETE_WITH_CONST("OPTIONS");
 
 /*
- * VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ]
- * VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]
+ * VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
+ * VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, 
...] ]
  */
        else if (Matches1("VACUUM"))
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tpm,
                                                                   " UNION 
SELECT 'FULL'"
                                                                   " UNION 
SELECT 'FREEZE'"
                                                                   " UNION 
SELECT 'ANALYZE'"
                                                                   " UNION 
SELECT 'VERBOSE'");
-       else if (Matches2("VACUUM", "FULL|FREEZE"))
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
+       else if (Matches2("VACUUM", "FULL"))
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tpm,
+                                                                  " UNION 
SELECT 'FREEZE'"
                                                                   " UNION 
SELECT 'ANALYZE'"
                                                                   " UNION 
SELECT 'VERBOSE'");
-       else if (Matches3("VACUUM", "FULL|FREEZE", "ANALYZE"))
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
-                                                                  " UNION 
SELECT 'VERBOSE'");
-       else if (Matches3("VACUUM", "FULL|FREEZE", "VERBOSE"))
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
+       else if (Matches2("VACUUM", "FULL|FREEZE") ||
+                                       Matches3("VACUUM", "FULL", "FREEZE"))
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tpm,
+                                                                  " UNION 
SELECT 'VERBOSE'"
                                                                   " UNION 
SELECT 'ANALYZE'");
-       else if (Matches2("VACUUM", "VERBOSE"))
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
+       else if (Matches2("VACUUM", "VERBOSE") ||
+                                       Matches3("VACUUM", "FULL|FREEZE", 
"VERBOSE") ||
+                                       Matches4("VACUUM", "FULL", "FREEZE", 
"VERBOSE"))
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tpm,
                                                                   " UNION 
SELECT 'ANALYZE'");
-       else if (Matches2("VACUUM", "ANALYZE"))
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm,
-                                                                  " UNION 
SELECT 'VERBOSE'");
+       else if (HeadMatches2("VACUUM", "("))
+               if (ends_with(prev_wd, ',') || ends_with(prev_wd, '('))
+                       COMPLETE_WITH_LIST5("FULL", "FREEZE", "ANALYZE", 
"VERBOSE", "DISABLE_PAGE_SKIPPING");
+               else
+                       COMPLETE_WITH_LIST2(",", ")");
+       else if (HeadMatches1("VACUUM") && TailMatches1("("))
+               /* "VACUUM (" should be caught above */
+               COMPLETE_WITH_ATTR(prev2_wd, "");
+       else if (HeadMatches2("VACUUM", MatchAny) && !ends_with(prev_wd, ',') &&
+                       !TailMatches1("ANALYZE") &&
+                       !(previous_words_count==2 && prev_wd[0]=='(' && 
ends_with(prev_wd, ')')))
+               /* Comma to support vacuuming multiple tables */
+               /* Parens to support analyzing a partial column list */
+               COMPLETE_WITH_LIST3(",", "(", ")");
        else if (HeadMatches1("VACUUM"))
-               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tpm, "");
 
 /* WITH [RECURSIVE] */
 
@@ -3600,9 +3622,28 @@ psql_completion(const char *text, int start, int end)
        else if (Matches1("WITH"))
                COMPLETE_WITH_CONST("RECURSIVE");
 
-/* ANALYZE */
-       /* Complete with list of tables */
+/*
+ * ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
+ * ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]
+ */
+       else if (Matches2("ANALYZE", "("))
+               COMPLETE_WITH_CONST("VERBOSE)");
        else if (Matches1("ANALYZE"))
+               COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tmf,
+                               " UNION SELECT 'VERBOSE'"
+                               " UNION SELECT '('"
+                               );
+       else if (HeadMatches1("ANALYZE") && TailMatches1("("))
+               /* "ANALYZE (" should be caught above */
+               COMPLETE_WITH_ATTR(prev2_wd, "");
+       else if (HeadMatches2("ANALYZE", MatchAny) &&
+                                       !ends_with(prev_wd, ',') &&
+                                       !(previous_words_count==2 && 
prev_wd[0]=='(' && ends_with(prev_wd, ')')) &&
+                                       !TailMatches1("VERBOSE"))
+                       /* Support analyze of multiple tables */
+                       /* or analyze table(column1, column2) */
+                       COMPLETE_WITH_LIST3(",", "(", ")");
+       else if (HeadMatches1("ANALYZE"))
                COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tmf, NULL);
 
 /* WHERE */

Reply via email to