@@ -598,10 +598,13 @@ typedef struct
598
598
const char * name ;
599
599
const char * query ; /* simple query, or NULL */
600
600
const SchemaQuery * squery ; /* schema query, or NULL */
601
- const bool noshow ; /* NULL or true if this word should not show
602
- * up after CREATE or DROP */
601
+ const bits32 flags ; /* visibility flags, see below */
603
602
} pgsql_thing_t ;
604
603
604
+ #define THING_NO_CREATE (1 << 0) /* should not show up after CREATE */
605
+ #define THING_NO_DROP (1 << 1) /* should not show up after DROP */
606
+ #define THING_NO_SHOW (THING_NO_CREATE | THING_NO_DROP)
607
+
605
608
static const pgsql_thing_t words_after_create [] = {
606
609
{"AGGREGATE" , NULL , & Query_for_list_of_aggregates },
607
610
{"CAST" , NULL , NULL }, /* Casts have complex structures for names, so
@@ -612,10 +615,10 @@ static const pgsql_thing_t words_after_create[] = {
612
615
* CREATE CONSTRAINT TRIGGER is not supported here because it is designed
613
616
* to be used only by pg_dump.
614
617
*/
615
- {"CONFIGURATION" , Query_for_list_of_ts_configurations , NULL , true },
618
+ {"CONFIGURATION" , Query_for_list_of_ts_configurations , NULL , THING_NO_SHOW },
616
619
{"CONVERSION" , "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'" },
617
620
{"DATABASE" , Query_for_list_of_databases },
618
- {"DICTIONARY" , Query_for_list_of_ts_dictionaries , NULL , true },
621
+ {"DICTIONARY" , Query_for_list_of_ts_dictionaries , NULL , THING_NO_SHOW },
619
622
{"DOMAIN" , NULL , & Query_for_list_of_domains },
620
623
{"EXTENSION" , Query_for_list_of_extensions },
621
624
{"FOREIGN DATA WRAPPER" , NULL , NULL },
@@ -626,24 +629,26 @@ static const pgsql_thing_t words_after_create[] = {
626
629
{"INDEX" , NULL , & Query_for_list_of_indexes },
627
630
{"OPERATOR" , NULL , NULL }, /* Querying for this is probably not such a
628
631
* good idea. */
629
- {"PARSER" , Query_for_list_of_ts_parsers , NULL , true},
632
+ {"OWNED" , NULL , NULL , THING_NO_CREATE }, /* for DROP OWNED BY ... */
633
+ {"PARSER" , Query_for_list_of_ts_parsers , NULL , THING_NO_SHOW },
630
634
{"ROLE" , Query_for_list_of_roles },
631
635
{"RULE" , "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'" },
632
636
{"SCHEMA" , Query_for_list_of_schemas },
633
637
{"SEQUENCE" , NULL , & Query_for_list_of_sequences },
634
638
{"SERVER" , Query_for_list_of_servers },
635
639
{"TABLE" , NULL , & Query_for_list_of_tables },
636
640
{"TABLESPACE" , Query_for_list_of_tablespaces },
637
- {"TEMP" , NULL , NULL }, /* for CREATE TEMP TABLE ... */
638
- {"TEMPLATE" , Query_for_list_of_ts_templates , NULL , true },
641
+ {"TEMP" , NULL , NULL , THING_NO_DROP }, /* for CREATE TEMP TABLE ... */
642
+ {"TEMPLATE" , Query_for_list_of_ts_templates , NULL , THING_NO_SHOW },
639
643
{"TEXT SEARCH" , NULL , NULL },
640
644
{"TRIGGER" , "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s'" },
641
645
{"TYPE" , NULL , & Query_for_list_of_datatypes },
642
- {"UNIQUE" , NULL , NULL }, /* for CREATE UNIQUE INDEX ... */
646
+ {"UNIQUE" , NULL , NULL , THING_NO_DROP }, /* for CREATE UNIQUE INDEX ... */
647
+ {"UNLOGGED" , NULL , NULL , THING_NO_DROP },/* for CREATE UNLOGGED TABLE ... */
643
648
{"USER" , Query_for_list_of_roles },
644
649
{"USER MAPPING FOR" , NULL , NULL },
645
650
{"VIEW" , NULL , & Query_for_list_of_views },
646
- {NULL , NULL , NULL , false } /* end of list */
651
+ {NULL } /* end of list */
647
652
};
648
653
649
654
@@ -1771,6 +1776,12 @@ psql_completion(char *text, int start, int end)
1771
1776
1772
1777
COMPLETE_WITH_LIST (list_TEMP );
1773
1778
}
1779
+ /* Complete "CREATE UNLOGGED" with TABLE */
1780
+ else if (pg_strcasecmp (prev2_wd , "CREATE" ) == 0 &&
1781
+ pg_strcasecmp (prev_wd , "UNLOGGED" ) == 0 )
1782
+ {
1783
+ COMPLETE_WITH_CONST ("TABLE" );
1784
+ }
1774
1785
1775
1786
/* CREATE TABLESPACE */
1776
1787
else if (pg_strcasecmp (prev3_wd , "CREATE" ) == 0 &&
@@ -2858,11 +2869,11 @@ psql_completion(char *text, int start, int end)
2858
2869
*/
2859
2870
2860
2871
/*
2861
- * This one gives you one from a list of things you can put after CREATE
2862
- * as defined above .
2872
+ * Common routine for create_command_generator and drop_command_generator.
2873
+ * Entries that have 'excluded' flags are not returned .
2863
2874
*/
2864
2875
static char *
2865
- create_command_generator (const char * text , int state )
2876
+ create_or_drop_command_generator (const char * text , int state , bits32 excluded )
2866
2877
{
2867
2878
static int list_index ,
2868
2879
string_length ;
@@ -2879,57 +2890,30 @@ create_command_generator(const char *text, int state)
2879
2890
while ((name = words_after_create [list_index ++ ].name ))
2880
2891
{
2881
2892
if ((pg_strncasecmp (name , text , string_length ) == 0 ) &&
2882
- !words_after_create [list_index - 1 ].noshow )
2893
+ !( words_after_create [list_index - 1 ].flags & excluded ) )
2883
2894
return pg_strdup (name );
2884
2895
}
2885
2896
/* if nothing matches, return NULL */
2886
2897
return NULL ;
2887
2898
}
2888
2899
2900
+ /*
2901
+ * This one gives you one from a list of things you can put after CREATE
2902
+ * as defined above.
2903
+ */
2904
+ static char *
2905
+ create_command_generator (const char * text , int state )
2906
+ {
2907
+ return create_or_drop_command_generator (text , state , THING_NO_CREATE );
2908
+ }
2909
+
2889
2910
/*
2890
2911
* This function gives you a list of things you can put after a DROP command.
2891
- * Very similar to create_command_generator, but has an additional entry for
2892
- * OWNED BY. (We do it this way in order not to duplicate the
2893
- * words_after_create list.)
2894
2912
*/
2895
2913
static char *
2896
2914
drop_command_generator (const char * text , int state )
2897
2915
{
2898
- static int list_index ,
2899
- string_length ;
2900
- const char * name ;
2901
-
2902
- if (state == 0 )
2903
- {
2904
- /* If this is the first time for this completion, init some values */
2905
- list_index = 0 ;
2906
- string_length = strlen (text );
2907
-
2908
- /*
2909
- * DROP can be followed by "OWNED BY", which is not found in the list
2910
- * for CREATE matches, so make it the first state. (We do not make it
2911
- * the last state because it would be more difficult to detect when we
2912
- * have to return NULL instead.)
2913
- *
2914
- * Make sure we advance to the next state.
2915
- */
2916
- list_index ++ ;
2917
- if (pg_strncasecmp ("OWNED" , text , string_length ) == 0 )
2918
- return pg_strdup ("OWNED" );
2919
- }
2920
-
2921
- /*
2922
- * In subsequent attempts, try to complete with the same items we use for
2923
- * CREATE
2924
- */
2925
- while ((name = words_after_create [list_index ++ - 1 ].name ))
2926
- {
2927
- if ((pg_strncasecmp (name , text , string_length ) == 0 ) && (!words_after_create [list_index - 2 ].noshow ))
2928
- return pg_strdup (name );
2929
- }
2930
-
2931
- /* if nothing matches, return NULL */
2932
- return NULL ;
2916
+ return create_or_drop_command_generator (text , state , THING_NO_DROP );
2933
2917
}
2934
2918
2935
2919
/* The following two functions are wrappers for _complete_from_query */
0 commit comments