Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc4e63f7

Browse files
committed
Added new commands and intelligence to psql tab completion.
1 parentc7558b3 commitc4e63f7

File tree

1 file changed

+130
-50
lines changed

1 file changed

+130
-50
lines changed

‎src/bin/psql/tab-complete.c

Lines changed: 130 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,44 @@
33
*
44
* Copyright 2000 by PostgreSQL Global Development Group
55
*
6-
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.19 2000/05/05 08:44:27 petere Exp $
6+
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.20 2000/06/25 14:25:51 petere Exp $
77
*/
88

9-
/*-----------
10-
This file implements a somewhat more sophisticated readline "TAB completion"
11-
in psql. It is not intended to be AI, to replace learning SQL, or to relieve
12-
you from thinking about what you're doing. Also it does not always give you
13-
all the syntactically legal completions, only those that are the most common
14-
or the ones that the programmer felt most like implementing.
15-
16-
CAVEAT: Tab completion causes queries to be sent to the backend. The number
17-
tuples returned gets limited, in most default installations to 101, but if
18-
you still don't like this prospect, you can turn off tab completion in your
19-
~/.inputrc (or else ${INPUTRC}) file so:
20-
$if psql
21-
TAB: self-insert
22-
$endif
23-
See `man 3 readline` or `info readline` for the full details. Also, hence the
24-
25-
BUGS:
26-
* If you split your queries across lines, this whole things gets confused.
27-
(To fix this, one would have to read psql's query buffer rather than
28-
readline's line buffer, which would require some major revisions of
29-
things.)
30-
* Table or attribute names with spaces in it will equally confuse it.
31-
* Quotes, parenthesis, and other funny characters are not handled all that
32-
gracefully.
33-
-------------*/
9+
/*----------------------------------------------------------------------
10+
* This file implements a somewhat more sophisticated readline "TAB
11+
* completion" in psql. It is not intended to be AI, to replace
12+
* learning SQL, or to relieve you from thinking about what you're
13+
* doing. Also it does not always give you all the syntactically legal
14+
* completions, only those that are the most common or the ones that
15+
* the programmer felt most like implementing.
16+
*
17+
* CAVEAT: Tab completion causes queries to be sent to the backend.
18+
* The number tuples returned gets limited, in most default
19+
* installations to 101, but if you still don't like this prospect,
20+
* you can turn off tab completion in your ~/.inputrc (or else
21+
* ${INPUTRC}) file so:
22+
*
23+
* $if psql
24+
* set disable-completion on
25+
* $endif
26+
*
27+
* See `man 3 readline' or `info readline' for the full details. Also,
28+
* hence the
29+
*
30+
* BUGS:
31+
*
32+
* - If you split your queries across lines, this whole things gets
33+
* confused. (To fix this, one would have to read psql's query
34+
* buffer rather than readline's line buffer, which would require
35+
* some major revisions of things.)
36+
*
37+
* - Table or attribute names with spaces in it will equally confuse
38+
* it.
39+
*
40+
* - Quotes, parenthesis, and other funny characters are not handled
41+
* all that gracefully.
42+
*----------------------------------------------------------------------
43+
*/
3444

3545
#include"postgres.h"
3646
#include"tab-complete.h"
@@ -120,6 +130,7 @@ pgsql_thing_t words_after_create[] = {
120130
{"AGGREGATE","SELECT distinct aggname FROM pg_aggregate WHERE substr(aggname,1,%d)='%s'"},
121131
{"DATABASE","SELECT datname FROM pg_database WHERE substr(datname,1,%d)='%s'"},
122132
{"FUNCTION","SELECT distinct proname FROM pg_proc WHERE substr(proname,1,%d)='%s'"},
133+
{"GROUP","SELECT groname FROM pg_group WHERE substr(groname,1,%d)='%s'"},
123134
{"INDEX","SELECT relname FROM pg_class WHERE relkind='i' and substr(relname,1,%d)='%s'"},
124135
{"OPERATOR",NULL},/* Querying for this is probably not such
125136
* a good idea. */
@@ -138,11 +149,11 @@ pgsql_thing_t words_after_create[] = {
138149

139150
/* The query to get a list of tables and a list of indexes, which are used at
140151
various places. */
141-
#defineQuery_for_list_of_tables words_after_create[7].query
142-
#defineQuery_for_list_of_indexes words_after_create[3].query
152+
#defineQuery_for_list_of_tables words_after_create[8].query
153+
#defineQuery_for_list_of_indexes words_after_create[4].query
143154
#defineQuery_for_list_of_databases words_after_create[1].query
144155
#defineQuery_for_list_of_attributes "SELECT a.attname FROM pg_attribute a, pg_class c WHERE c.oid = a.attrelid and a.attnum>0 and substr(a.attname,1,%d)='%s' and c.relname='%s'"
145-
156+
#defineQuery_for_list_of_users words_after_create[13].query
146157

147158
/* A couple of macros to ease typing. You can use these to complete the given
148159
string with
@@ -179,39 +190,45 @@ psql_completion(char *text, int start, int end)
179190
*prev4_wd;
180191

181192
staticchar*sql_commands[]= {
182-
"ABORT","ALTER","BEGIN","CLOSE","CLUSTER","COMMIT","COPY",
193+
"ABORT","ALTER","BEGIN","CLOSE","CLUSTER","COMMENT","COMMIT","COPY",
183194
"CREATE","DECLARE","DELETE","DROP","EXPLAIN","FETCH","GRANT",
184195
"INSERT","LISTEN","LOAD","LOCK","MOVE","NOTIFY","RESET",
185-
"REVOKE","ROLLBACK","SELECT","SET","SHOW","UNLISTEN","UPDATE",
196+
"REVOKE","ROLLBACK","SELECT","SET","SHOW","TRUNCATE","UNLISTEN","UPDATE",
186197
"VACUUM",NULL
187198
};
188199

189200
staticchar*pgsql_variables[]= {
190201
/* these SET arguments are known in gram.y */
191-
"TRANSACTION ISOLATION LEVEL",
202+
"CONSTRAINTS",
192203
"NAMES",
193-
/* rest should match table in src/backend/commands/variable.c */
204+
"TRANSACTION ISOLATION LEVEL",
205+
/* these are treated in backend/commands/variable.c */
194206
"DateStyle",
195207
"TimeZone",
196-
"effective_cache_size",
197-
"random_page_cost",
198-
"cpu_tuple_cost",
199-
"cpu_index_tuple_cost",
200-
"cpu_operator_cost",
208+
"client_encoding",
209+
"server_encoding",
210+
"random_seed",
211+
/* the rest should match USERSET and SUSET entries in
212+
* backend/utils/misc/guc.c, but feel free to leave out the
213+
* esoteric or debug settings */
201214
"enable_seqscan",
202215
"enable_indexscan",
203216
"enable_tidscan",
204217
"enable_sort",
205218
"enable_nestloop",
206219
"enable_mergejoin",
207220
"enable_hashjoin",
208-
"GEQO",
209-
"client_encoding",
210-
"server_encoding",
211-
"KSQO",
221+
"geqo",
222+
"ksqo",
223+
"sql_inheritance",
224+
"sort_mem",
225+
"debug_level",
212226
"max_expr_depth",
213-
"XactIsoLevel",
214-
"PG_Options",
227+
"effective_cache_size",
228+
"random_page_cost",
229+
"cpu_tuple_cost",
230+
"cpu_index_tuple_cost",
231+
"cpu_operator_cost",
215232
NULL
216233
};
217234

@@ -260,25 +277,41 @@ psql_completion(char *text, int start, int end)
260277
matches=completion_matches(text,create_command_generator);
261278

262279
/* ALTER */
263-
/* complete with what you can alter (TABLE or USER) */
280+
/* complete with what you can alter (TABLE, GROUP, USER) */
264281
elseif (strcasecmp(prev_wd,"ALTER")==0)
265282
{
266-
char*list_ALTER[]= {"TABLE","USER",NULL};
283+
char*list_ALTER[]= {"GROUP","TABLE","USER",NULL};
267284

268285
COMPLETE_WITH_LIST(list_ALTER);
269286
}
270-
/* If we detect ALTER TABLE <name>, suggest either"ADD"or"RENAME" */
287+
/* If we detect ALTER TABLE <name>, suggest either ADD, ALTER,or RENAME */
271288
elseif (strcasecmp(prev3_wd,"ALTER")==0&&strcasecmp(prev2_wd,"TABLE")==0)
272289
{
273-
char*list_ALTER2[]= {"ADD","RENAME",NULL};
290+
char*list_ALTER2[]= {"ADD","ALTER","RENAME",NULL};
274291

275292
COMPLETE_WITH_LIST(list_ALTER2);
276293
}
277-
/* If we have TABLE <sth>ADD|RENAME, provide list of columns */
294+
/* If we have TABLE <sth>ALTER|RENAME, provide list of columns */
278295
elseif (strcasecmp(prev3_wd,"TABLE")==0&&
279-
(strcasecmp(prev_wd,"ADD")==0||strcasecmp(prev_wd,"RENAME")==0))
296+
(strcasecmp(prev_wd,"ALTER")==0||strcasecmp(prev_wd,"RENAME")==0))
280297
COMPLETE_WITH_ATTR(prev2_wd);
281298

299+
/* complete ALTER GROUP <foo> with ADD or DROP */
300+
elseif (strcasecmp(prev3_wd,"ALTER")==0&&strcasecmp(prev2_wd,"GROUP")==0)
301+
{
302+
char*list_ALTERGROUP[]= {"ADD","DROP",NULL};
303+
COMPLETE_WITH_LIST(list_ALTERGROUP);
304+
}
305+
/* complete ALTER GROUP <foo> ADD|DROP with USER */
306+
elseif (strcasecmp(prev4_wd,"ALTER")==0&&strcasecmp(prev3_wd,"GROUP")==0
307+
&& (strcasecmp(prev_wd,"ADD")==0||strcasecmp(prev_wd,"DROP")==0))
308+
COMPLETE_WITH_CONST("USER");
309+
/* complete {ALTER} GROUP <foo> ADD|DROP USER with a user name */
310+
elseif (strcasecmp(prev4_wd,"GROUP")==0
311+
&& (strcasecmp(prev2_wd,"ADD")==0||strcasecmp(prev2_wd,"DROP")==0)
312+
&&strcasecmp(prev_wd,"USER")==0)
313+
COMPLETE_WITH_QUERY(Query_for_list_of_users);
314+
282315
/* CLUSTER */
283316
/* If the previous word is CLUSTER, produce list of indexes. */
284317
elseif (strcasecmp(prev_wd,"CLUSTER")==0)
@@ -304,6 +337,19 @@ psql_completion(char *text, int start, int end)
304337
COMPLETE_WITH_QUERY(query_buffer);
305338
}
306339

340+
/* COMMENT */
341+
elseif (strcasecmp(prev_wd,"COMMENT")==0)
342+
COMPLETE_WITH_CONST("ON");
343+
elseif (strcasecmp(prev2_wd,"COMMENT")==0&&strcasecmp(prev_wd,"ON")==0)
344+
{
345+
char*list_COMMENT[]=
346+
{"DATABASE","INDEX","RULE","SEQUENCE","TABLE","TYPE","VIEW",
347+
"COLUMN","AGGREGATE","FUNCTION","OPERATOR","TRIGGER",NULL};
348+
COMPLETE_WITH_LIST(list_COMMENT);
349+
}
350+
elseif (strcasecmp(prev4_wd,"COMMENT")==0&&strcasecmp(prev3_wd,"ON")==0)
351+
COMPLETE_WITH_CONST("IS");
352+
307353
/* COPY */
308354

309355
/*
@@ -510,6 +556,26 @@ psql_completion(char *text, int start, int end)
510556
COMPLETE_WITH_QUERY(Query_for_list_of_tables);
511557
/* (If you want more with LOCK, you better think about it yourself.) */
512558

559+
/* NOTIFY */
560+
elseif (strcasecmp(prev_wd,"NOTIFY")==0)
561+
COMPLETE_WITH_QUERY("SELECT relname FROM pg_listener WHERE substr(relname,1,%d)='%s'");
562+
563+
/* REINDEX */
564+
elseif (strcasecmp(prev_wd,"REINDEX")==0)
565+
{
566+
char*list_REINDEX[]= {"TABLE","DATABASE","INDEX",NULL};
567+
COMPLETE_WITH_LIST(list_REINDEX);
568+
}
569+
elseif (strcasecmp(prev2_wd,"REINDEX")==0)
570+
{
571+
if (strcasecmp(prev_wd,"TABLE")==0)
572+
COMPLETE_WITH_QUERY(Query_for_list_of_tables);
573+
elseif (strcasecmp(prev_wd,"DATABASE")==0)
574+
COMPLETE_WITH_QUERY(Query_for_list_of_databases);
575+
elseif (strcasecmp(prev_wd,"INDEX")==0)
576+
COMPLETE_WITH_QUERY(Query_for_list_of_indexes);
577+
}
578+
513579
/* SELECT */
514580
/* naah . . . */
515581

@@ -540,6 +606,12 @@ psql_completion(char *text, int start, int end)
540606
strcasecmp(prev2_wd,"LEVEL")==0&&
541607
strcasecmp(prev_wd,"READ")==0)
542608
COMPLETE_WITH_CONST("COMMITTED");
609+
/* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
610+
elseif (strcasecmp(prev3_wd,"SET")==0&&strcasecmp(prev2_wd,"CONSTRAINTS")==0)
611+
{
612+
char*constraint_list[]= {"DEFERRED","IMMEDIATE",NULL};
613+
COMPLETE_WITH_LIST(constraint_list);
614+
}
543615
/* Complete SET <var> with "TO" */
544616
elseif (strcasecmp(prev2_wd,"SET")==0&&
545617
strcasecmp(prev4_wd,"UPDATE")!=0)
@@ -568,6 +640,14 @@ psql_completion(char *text, int start, int end)
568640
}
569641
}
570642

643+
/* TRUNCATE */
644+
elseif (strcasecmp(prev_wd,"TRUNCATE")==0)
645+
COMPLETE_WITH_QUERY(Query_for_list_of_tables);
646+
647+
/* UNLISTEN */
648+
elseif (strcasecmp(prev_wd,"UNLISTEN")==0)
649+
COMPLETE_WITH_QUERY("SELECT relname FROM pg_listener WHERE substr(relname,1,%d)='%s' UNION SELECT '*'::text");
650+
571651
/* UPDATE */
572652
/* If prev. word is UPDATE suggest a list of tables */
573653
elseif (strcasecmp(prev_wd,"UPDATE")==0)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp