@@ -576,20 +576,24 @@ static char *complete_from_query(const char *text, int state);
576
576
static char * complete_from_schema_query (const char * text , int state );
577
577
static char * _complete_from_query (int is_schema_query ,
578
578
const char * text , int state );
579
- static char * complete_from_const (const char * text , int state );
580
579
static char * complete_from_list (const char * text , int state );
580
+ static char * complete_from_const (const char * text , int state );
581
+ static char * * complete_from_variables (char * text ,
582
+ const char * prefix , const char * suffix );
581
583
582
584
static PGresult * exec_query (const char * query );
583
585
584
586
static char * previous_word (int point , int skip );
585
587
586
- #if 0
588
+ #ifdef NOT_USED
587
589
static char * quote_file_name (char * text , int match_type , char * quote_pointer );
588
590
static char * dequote_file_name (char * text , char quote_char );
589
591
#endif
590
592
591
593
592
- /* Initialize the readline library for our purposes. */
594
+ /*
595
+ * Initialize the readline library for our purposes.
596
+ */
593
597
void
594
598
initialize_readline (void )
595
599
{
@@ -607,11 +611,14 @@ initialize_readline(void)
607
611
}
608
612
609
613
610
- /* The completion function. Acc. to readline spec this gets passed the text
611
- entered to far and its start and end in the readline buffer. The return value
612
- is some partially obscure list format that can be generated by the readline
613
- libraries completion_matches() function, so we don't have to worry about it.
614
- */
614
+ /*
615
+ * The completion function.
616
+ *
617
+ * According to readline spec this gets passed the text entered so far and its
618
+ * start and end positions in the readline buffer. The return value is some
619
+ * partially obscure list format that can be generated by readline's
620
+ * completion_matches() function, so we don't have to worry about it.
621
+ */
615
622
static char * *
616
623
psql_completion (char * text , int start , int end )
617
624
{
@@ -1943,7 +1950,7 @@ psql_completion(char *text, int start, int end)
1943
1950
pg_strcasecmp (prev_wd , "WRAPPER" ) == 0 )
1944
1951
COMPLETE_WITH_QUERY (Query_for_list_of_fdws );
1945
1952
1946
- /* GRANT && REVOKE*/
1953
+ /* GRANT && REVOKE */
1947
1954
/* Complete GRANT/REVOKE with a list of privileges */
1948
1955
else if (pg_strcasecmp (prev_wd , "GRANT" ) == 0 ||
1949
1956
pg_strcasecmp (prev_wd , "REVOKE" ) == 0 )
@@ -2512,7 +2519,6 @@ psql_completion(char *text, int start, int end)
2512
2519
pg_strcasecmp (prev3_wd , "\\copy" ) != 0 )
2513
2520
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tsv , NULL );
2514
2521
2515
-
2516
2522
/* Backslash commands */
2517
2523
/* TODO: \dc \dd \dl */
2518
2524
else if (strcmp (prev_wd , "\\connect" ) == 0 || strcmp (prev_wd , "\\c" ) == 0 )
@@ -2582,6 +2588,10 @@ psql_completion(char *text, int start, int end)
2582
2588
2583
2589
COMPLETE_WITH_LIST (my_list );
2584
2590
}
2591
+ else if (strcmp (prev_wd , "\\set" ) == 0 )
2592
+ {
2593
+ matches = complete_from_variables (text , "" , "" );
2594
+ }
2585
2595
else if (strcmp (prev_wd , "\\sf" ) == 0 || strcmp (prev_wd , "\\sf+" ) == 0 )
2586
2596
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_functions , NULL );
2587
2597
else if (strcmp (prev_wd , "\\cd" ) == 0 ||
@@ -2594,6 +2604,16 @@ psql_completion(char *text, int start, int end)
2594
2604
)
2595
2605
matches = completion_matches (text , filename_completion_function );
2596
2606
2607
+ /* Variable interpolation */
2608
+ else if (text [0 ] == ':' && text [1 ] != ':' )
2609
+ {
2610
+ if (text [1 ] == '\'' )
2611
+ matches = complete_from_variables (text , ":'" , "'" );
2612
+ else if (text [1 ] == '"' )
2613
+ matches = complete_from_variables (text , ":\"" , "\"" );
2614
+ else
2615
+ matches = complete_from_variables (text , ":" , "" );
2616
+ }
2597
2617
2598
2618
/*
2599
2619
* Finally, we look through the list of "things", such as TABLE, INDEX and
@@ -2643,23 +2663,24 @@ psql_completion(char *text, int start, int end)
2643
2663
}
2644
2664
2645
2665
2666
+ /*
2667
+ * GENERATOR FUNCTIONS
2668
+ *
2669
+ * These functions do all the actual work of completing the input. They get
2670
+ * passed the text so far and the count how many times they have been called
2671
+ * so far with the same text.
2672
+ * If you read the above carefully, you'll see that these don't get called
2673
+ * directly but through the readline interface.
2674
+ * The return value is expected to be the full completion of the text, going
2675
+ * through a list each time, or NULL if there are no more matches. The string
2676
+ * will be free()'d by readline, so you must run it through strdup() or
2677
+ * something of that sort.
2678
+ */
2646
2679
2647
- /* GENERATOR FUNCTIONS
2648
-
2649
- These functions do all the actual work of completing the input. They get
2650
- passed the text so far and the count how many times they have been called so
2651
- far with the same text.
2652
- If you read the above carefully, you'll see that these don't get called
2653
- directly but through the readline interface.
2654
- The return value is expected to be the full completion of the text, going
2655
- through a list each time, or NULL if there are no more matches. The string
2656
- will be free()'d by readline, so you must run it through strdup() or
2657
- something of that sort.
2658
- */
2659
-
2660
- /* This one gives you one from a list of things you can put after CREATE
2661
- as defined above.
2662
- */
2680
+ /*
2681
+ * This one gives you one from a list of things you can put after CREATE
2682
+ * as defined above.
2683
+ */
2663
2684
static char *
2664
2685
create_command_generator (const char * text , int state )
2665
2686
{
@@ -2677,7 +2698,8 @@ create_command_generator(const char *text, int state)
2677
2698
/* find something that matches */
2678
2699
while ((name = words_after_create [list_index ++ ].name ))
2679
2700
{
2680
- if ((pg_strncasecmp (name , text , string_length ) == 0 ) && !words_after_create [list_index - 1 ].noshow )
2701
+ if ((pg_strncasecmp (name , text , string_length ) == 0 ) &&
2702
+ !words_after_create [list_index - 1 ].noshow )
2681
2703
return pg_strdup (name );
2682
2704
}
2683
2705
/* if nothing matches, return NULL */
@@ -2745,26 +2767,27 @@ complete_from_schema_query(const char *text, int state)
2745
2767
}
2746
2768
2747
2769
2748
- /* This creates a list of matching things, according to a query pointed to
2749
- by completion_charp.
2750
- The query can be one of two kinds:
2751
- - A simple query which must contain a %d and a %s, which will be replaced
2752
- by the string length of the text and the text itself. The query may also
2753
- have up to four more %s in it; the first two such will be replaced by the
2754
- value of completion_info_charp, the next two by the value of
2755
- completion_info_charp2.
2756
- or:
2757
- - A schema query used for completion of both schema and relation names;
2758
- these are more complex and must contain in the following order:
2759
- %d %s %d %s %d %s %s %d %s
2760
- where %d is the string length of the text and %s the text itself.
2761
-
2762
- It is assumed that strings should be escaped to become SQL literals
2763
- (that is, what is in the query is actually ... '%s' ...)
2764
-
2765
- See top of file for examples of both kinds of query.
2766
- */
2767
-
2770
+ /*
2771
+ * This creates a list of matching things, according to a query pointed to
2772
+ * by completion_charp.
2773
+ * The query can be one of two kinds:
2774
+ *
2775
+ * 1. A simple query which must contain a %d and a %s, which will be replaced
2776
+ * by the string length of the text and the text itself. The query may also
2777
+ * have up to four more %s in it; the first two such will be replaced by the
2778
+ * value of completion_info_charp, the next two by the value of
2779
+ * completion_info_charp2.
2780
+ *
2781
+ * 2. A schema query used for completion of both schema and relation names.
2782
+ * These are more complex and must contain in the following order:
2783
+ * %d %s %d %s %d %s %s %d %s
2784
+ * where %d is the string length of the text and %s the text itself.
2785
+ *
2786
+ * It is assumed that strings should be escaped to become SQL literals
2787
+ * (that is, what is in the query is actually ... '%s' ...)
2788
+ *
2789
+ * See top of file for examples of both kinds of query.
2790
+ */
2768
2791
static char *
2769
2792
_complete_from_query (int is_schema_query , const char * text , int state )
2770
2793
{
@@ -2950,10 +2973,11 @@ _complete_from_query(int is_schema_query, const char *text, int state)
2950
2973
}
2951
2974
2952
2975
2953
- /* This function returns in order one of a fixed, NULL pointer terminated list
2954
- of strings (if matching). This can be used if there are only a fixed number
2955
- SQL words that can appear at certain spot.
2956
- */
2976
+ /*
2977
+ * This function returns in order one of a fixed, NULL pointer terminated list
2978
+ * of strings (if matching). This can be used if there are only a fixed number
2979
+ * SQL words that can appear at certain spot.
2980
+ */
2957
2981
static char *
2958
2982
complete_from_list (const char * text , int state )
2959
2983
{
@@ -3006,12 +3030,13 @@ complete_from_list(const char *text, int state)
3006
3030
}
3007
3031
3008
3032
3009
- /* This function returns one fixed string the first time even if it doesn't
3010
- match what's there, and nothing the second time. This should be used if there
3011
- is only one possibility that can appear at a certain spot, so misspellings
3012
- will be overwritten.
3013
- The string to be passed must be in completion_charp.
3014
- */
3033
+ /*
3034
+ * This function returns one fixed string the first time even if it doesn't
3035
+ * match what's there, and nothing the second time. This should be used if
3036
+ * there is only one possibility that can appear at a certain spot, so
3037
+ * misspellings will be overwritten. The string to be passed must be in
3038
+ * completion_charp.
3039
+ */
3015
3040
static char *
3016
3041
complete_from_const (const char * text , int state )
3017
3042
{
@@ -3026,6 +3051,55 @@ complete_from_const(const char *text, int state)
3026
3051
}
3027
3052
3028
3053
3054
+ /*
3055
+ * This function supports completion with the name of a psql variable.
3056
+ * The variable names can be prefixed and suffixed with additional text
3057
+ * to support quoting usages.
3058
+ */
3059
+ static char * *
3060
+ complete_from_variables (char * text , const char * prefix , const char * suffix )
3061
+ {
3062
+ char * * matches ;
3063
+ int overhead = strlen (prefix ) + strlen (suffix ) + 1 ;
3064
+ const char * * varnames ;
3065
+ int nvars = 0 ;
3066
+ int maxvars = 100 ;
3067
+ int i ;
3068
+ struct _variable * ptr ;
3069
+
3070
+ varnames = (const char * * ) pg_malloc ((maxvars + 1 ) * sizeof (char * ));
3071
+
3072
+ for (ptr = pset .vars -> next ; ptr ; ptr = ptr -> next )
3073
+ {
3074
+ char * buffer ;
3075
+
3076
+ if (nvars >= maxvars )
3077
+ {
3078
+ maxvars *= 2 ;
3079
+ varnames = (const char * * ) realloc (varnames ,
3080
+ (maxvars + 1 ) * sizeof (char * ));
3081
+ if (!varnames )
3082
+ {
3083
+ psql_error ("out of memory\n" );
3084
+ exit (EXIT_FAILURE );
3085
+ }
3086
+ }
3087
+
3088
+ buffer = (char * ) pg_malloc (strlen (ptr -> name ) + overhead );
3089
+ sprintf (buffer , "%s%s%s" , prefix , ptr -> name , suffix );
3090
+ varnames [nvars ++ ] = buffer ;
3091
+ }
3092
+
3093
+ varnames [nvars ] = NULL ;
3094
+ COMPLETE_WITH_LIST (varnames );
3095
+
3096
+ for (i = 0 ; i < nvars ; i ++ )
3097
+ free ((void * ) varnames [i ]);
3098
+ free (varnames );
3099
+
3100
+ return matches ;
3101
+ }
3102
+
3029
3103
3030
3104
/* HELPER FUNCTIONS */
3031
3105
@@ -3046,7 +3120,7 @@ exec_query(const char *query)
3046
3120
3047
3121
if (PQresultStatus (result ) != PGRES_TUPLES_OK )
3048
3122
{
3049
- #if 0
3123
+ #ifdef NOT_USED
3050
3124
psql_error ("tab completion query failed: %s\nQuery was:\n%s\n" ,
3051
3125
PQerrorMessage (pset .db ), query );
3052
3126
#endif
@@ -3058,7 +3132,6 @@ exec_query(const char *query)
3058
3132
}
3059
3133
3060
3134
3061
-
3062
3135
/*
3063
3136
* Return the word (space delimited) before point. Set skip > 0 to
3064
3137
* skip that many words; e.g. skip=1 finds the word before the
@@ -3133,7 +3206,7 @@ previous_word(int point, int skip)
3133
3206
return s ;
3134
3207
}
3135
3208
3136
- #if 0
3209
+ #ifdef NOT_USED
3137
3210
3138
3211
/*
3139
3212
* Surround a string with single quotes. This works for both SQL and
@@ -3158,8 +3231,6 @@ quote_file_name(char *text, int match_type, char *quote_pointer)
3158
3231
return s ;
3159
3232
}
3160
3233
3161
-
3162
-
3163
3234
static char *
3164
3235
dequote_file_name (char * text , char quote_char )
3165
3236
{
@@ -3175,6 +3246,6 @@ dequote_file_name(char *text, char quote_char)
3175
3246
3176
3247
return s ;
3177
3248
}
3178
- #endif /* 0 */
3249
+ #endif /* NOT_USED */
3179
3250
3180
3251
#endif /* USE_READLINE */
0 commit comments