Skip to content

Commit 643b022

Browse files
committed
Add tab-completion for REASSIGN OWNED BY and DROP OWNED BY. Also fix some
whitespace issues nearby. DROP OWNED BY is actually a bit kludgy, but it seems better to do it this way rather than duplicating the words_after_create list just to add a single element.
1 parent d73336f commit 643b022

File tree

1 file changed

+106
-27
lines changed

1 file changed

+106
-27
lines changed

src/bin/psql/tab-complete.c

Lines changed: 106 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright (c) 2000-2006, PostgreSQL Global Development Group
55
*
6-
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.149 2006/03/05 15:58:52 momjian Exp $
6+
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.150 2006/04/02 09:02:41 alvherre Exp $
77
*/
88

99
/*----------------------------------------------------------------------
@@ -465,6 +465,7 @@ static const pgsql_thing_t words_after_create[] = {
465465
/* Forward declaration of functions */
466466
static char **psql_completion(char *text, int start, int end);
467467
static char *create_command_generator(const char *text, int state);
468+
static char *drop_command_generator(const char *text, int state);
468469
static char *complete_from_query(const char *text, int state);
469470
static char *complete_from_schema_query(const char *text, int state);
470471
static char *_complete_from_query(int is_schema_query,
@@ -521,11 +522,13 @@ psql_completion(char *text, int start, int end)
521522
*prev5_wd;
522523

523524
static const char *const sql_commands[] = {
524-
"ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER", "COMMENT",
525-
"COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE FROM", "DROP", "END", "EXECUTE",
526-
"EXPLAIN", "FETCH", "GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY",
527-
"PREPARE", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK", "SAVEPOINT",
528-
"SELECT", "SET", "SHOW", "START", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", NULL
525+
"ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER",
526+
"COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE",
527+
"DELETE FROM", "DROP", "END", "EXECUTE", "EXPLAIN", "FETCH", "GRANT",
528+
"INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "PREPARE",
529+
"REASSIGN", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK",
530+
"SAVEPOINT", "SELECT", "SET", "SHOW", "START", "TRUNCATE", "UNLISTEN",
531+
"UPDATE", "VACUUM", NULL
529532
};
530533

531534
static const char *const backslash_commands[] = {
@@ -536,7 +539,8 @@ psql_completion(char *text, int start, int end)
536539
"\\e", "\\echo", "\\encoding",
537540
"\\f", "\\g", "\\h", "\\help", "\\H", "\\i", "\\l",
538541
"\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
539-
"\\o", "\\p", "\\password", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\T",
542+
"\\o", "\\p", "\\password", "\\pset", "\\q", "\\qecho", "\\r",
543+
"\\set", "\\t", "\\T",
540544
"\\timing", "\\unset", "\\x", "\\w", "\\z", "\\!", NULL
541545
};
542546

@@ -570,15 +574,19 @@ psql_completion(char *text, int start, int end)
570574
else if (!prev_wd)
571575
COMPLETE_WITH_LIST(sql_commands);
572576

573-
/* CREATE or DROP but not ALTER (TABLE|DOMAIN|GROUP) sth DROP */
574-
/* complete with something you can create or drop */
575-
else if (pg_strcasecmp(prev_wd, "CREATE") == 0 ||
576-
(pg_strcasecmp(prev_wd, "DROP") == 0 &&
577-
pg_strcasecmp(prev3_wd, "TABLE") != 0 &&
578-
pg_strcasecmp(prev3_wd, "DOMAIN") != 0 &&
579-
pg_strcasecmp(prev3_wd, "GROUP") != 0))
577+
/* CREATE */
578+
/* complete with something you can create */
579+
else if (pg_strcasecmp(prev_wd, "CREATE") == 0)
580580
matches = completion_matches(text, create_command_generator);
581581

582+
/* DROP, except ALTER (TABLE|DOMAIN|GROUP) sth DROP */
583+
/* complete with something you can drop */
584+
else if (pg_strcasecmp(prev_wd, "DROP") == 0 &&
585+
pg_strcasecmp(prev3_wd, "TABLE") != 0 &&
586+
pg_strcasecmp(prev3_wd, "DOMAIN") != 0 &&
587+
pg_strcasecmp(prev3_wd, "GROUP") != 0)
588+
matches = completion_matches(text, drop_command_generator);
589+
582590
/* ALTER */
583591

584592
/*
@@ -1248,23 +1256,22 @@ psql_completion(char *text, int start, int end)
12481256
pg_strcasecmp(prev3_wd, "AGGREGATE") == 0 &&
12491257
prev_wd[strlen(prev_wd) - 1] == ')'))
12501258
{
1251-
12521259
if ((pg_strcasecmp(prev3_wd, "DROP") == 0) && (pg_strcasecmp(prev2_wd, "FUNCTION") == 0))
1253-
{
1254-
if (find_open_parenthesis(end))
1260+
{
1261+
if (find_open_parenthesis(end))
12551262
{
12561263
static const char func_args_query[] = "select pg_catalog.oidvectortypes(proargtypes)||')' from pg_proc where proname='%s'";
1257-
char *tmp_buf = malloc(strlen(func_args_query) + strlen(prev_wd));
1258-
sprintf(tmp_buf, func_args_query, prev_wd);
1259-
COMPLETE_WITH_QUERY(tmp_buf);
1260-
free(tmp_buf);
1264+
char *tmp_buf = malloc(strlen(func_args_query) + strlen(prev_wd));
1265+
sprintf(tmp_buf, func_args_query, prev_wd);
1266+
COMPLETE_WITH_QUERY(tmp_buf);
1267+
free(tmp_buf);
12611268
}
12621269
else
12631270
{
1264-
COMPLETE_WITH_CONST("(");
1271+
COMPLETE_WITH_CONST("(");
12651272
}
1266-
}
1267-
else
1273+
}
1274+
else
12681275
{
12691276
static const char *const list_DROPCR[] =
12701277
{"CASCADE", "RESTRICT", NULL};
@@ -1274,14 +1281,22 @@ psql_completion(char *text, int start, int end)
12741281
}
12751282
else if (pg_strcasecmp(prev4_wd, "DROP") == 0 &&
12761283
pg_strcasecmp(prev3_wd, "FUNCTION") == 0 &&
1277-
pg_strcasecmp(prev_wd, "(") == 0 )
1284+
pg_strcasecmp(prev_wd, "(") == 0)
12781285
{
12791286
static const char func_args_query[] = "select pg_catalog.oidvectortypes(proargtypes)||')' from pg_proc where proname='%s'";
12801287
char *tmp_buf = malloc(strlen(func_args_query) + strlen(prev2_wd));
12811288
sprintf(tmp_buf, func_args_query, prev2_wd);
12821289
COMPLETE_WITH_QUERY(tmp_buf);
12831290
free(tmp_buf);
12841291
}
1292+
/* DROP OWNED BY */
1293+
else if (pg_strcasecmp(prev2_wd, "DROP") == 0 &&
1294+
pg_strcasecmp(prev_wd, "OWNED") == 0)
1295+
COMPLETE_WITH_CONST("BY");
1296+
else if (pg_strcasecmp(prev3_wd, "DROP") == 0 &&
1297+
pg_strcasecmp(prev2_wd, "OWNED") == 0 &&
1298+
pg_strcasecmp(prev_wd, "BY") == 0)
1299+
COMPLETE_WITH_QUERY(Query_for_list_of_roles);
12851300

12861301

12871302

@@ -1502,7 +1517,7 @@ psql_completion(char *text, int start, int end)
15021517
else if (pg_strcasecmp(prev_wd, "NOTIFY") == 0)
15031518
COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s'");
15041519

1505-
/* OWNER TO - complete with available roles*/
1520+
/* OWNER TO - complete with available roles */
15061521
else if (pg_strcasecmp(prev2_wd, "OWNER") == 0 &&
15071522
pg_strcasecmp(prev_wd, "TO") == 0)
15081523
COMPLETE_WITH_QUERY(Query_for_list_of_roles);
@@ -1526,6 +1541,25 @@ psql_completion(char *text, int start, int end)
15261541
COMPLETE_WITH_LIST(list_PREPARE);
15271542
}
15281543

1544+
/* REASSIGN OWNED BY xxx TO yyy */
1545+
else if (pg_strcasecmp(prev_wd, "REASSIGN") == 0)
1546+
COMPLETE_WITH_CONST("OWNED");
1547+
else if (pg_strcasecmp(prev_wd, "OWNED") == 0 &&
1548+
pg_strcasecmp(prev2_wd, "REASSIGN") == 0)
1549+
COMPLETE_WITH_CONST("BY");
1550+
else if (pg_strcasecmp(prev_wd, "BY") == 0 &&
1551+
pg_strcasecmp(prev2_wd, "OWNED") == 0 &&
1552+
pg_strcasecmp(prev3_wd, "REASSIGN") == 0)
1553+
COMPLETE_WITH_QUERY(Query_for_list_of_roles);
1554+
else if (pg_strcasecmp(prev2_wd, "BY") == 0 &&
1555+
pg_strcasecmp(prev3_wd, "OWNED") == 0 &&
1556+
pg_strcasecmp(prev4_wd, "REASSIGN") == 0)
1557+
COMPLETE_WITH_CONST("TO");
1558+
else if (pg_strcasecmp(prev_wd, "TO") == 0 &&
1559+
pg_strcasecmp(prev3_wd, "BY") == 0 &&
1560+
pg_strcasecmp(prev4_wd, "OWNED") == 0 &&
1561+
pg_strcasecmp(prev5_wd, "REASSIGN") == 0)
1562+
COMPLETE_WITH_QUERY(Query_for_list_of_roles);
15291563

15301564
/* REINDEX */
15311565
else if (pg_strcasecmp(prev_wd, "REINDEX") == 0)
@@ -1909,7 +1943,7 @@ psql_completion(char *text, int start, int end)
19091943
something of that sort.
19101944
*/
19111945

1912-
/* This one gives you one from a list of things you can put after CREATE or DROP
1946+
/* This one gives you one from a list of things you can put after CREATE
19131947
as defined above.
19141948
*/
19151949
static char *
@@ -1935,6 +1969,51 @@ create_command_generator(const char *text, int state)
19351969
return NULL;
19361970
}
19371971

1972+
/*
1973+
* This function gives you a list of things you can put after a DROP command.
1974+
* Very similar to create_command_generator, but has an additional entry for
1975+
* OWNED BY. (We do it this way in order not to duplicate the
1976+
* words_after_create list.)
1977+
*/
1978+
static char *
1979+
drop_command_generator(const char *text, int state)
1980+
{
1981+
static int list_index,
1982+
string_length;
1983+
const char *name;
1984+
1985+
if (state == 0)
1986+
{
1987+
/* If this is the first time for this completion, init some values */
1988+
list_index = 0;
1989+
string_length = strlen(text);
1990+
1991+
/*
1992+
* DROP can be followed by "OWNED BY", which is not found in the list
1993+
* for CREATE matches, so make it the first state. (We do not make it
1994+
* the last state because it would be more difficult to detect when we
1995+
* have to return NULL instead.)
1996+
*
1997+
* Make sure we advance to the next state.
1998+
*/
1999+
list_index++;
2000+
if (pg_strncasecmp("OWNED", text, string_length) == 0)
2001+
return pg_strdup("OWNED");
2002+
}
2003+
2004+
/*
2005+
* In subsequent attempts, try to complete with the same items we use for
2006+
* CREATE
2007+
*/
2008+
while ((name = words_after_create[list_index++ - 1].name))
2009+
{
2010+
if (pg_strncasecmp(name, text, string_length) == 0)
2011+
return pg_strdup(name);
2012+
}
2013+
2014+
/* if nothing matches, return NULL */
2015+
return NULL;
2016+
}
19382017

19392018
/* The following two functions are wrappers for _complete_from_query */
19402019

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy