Skip to content

Commit 631e7f6

Browse files
committed
Improve tab-completion of DROP and ALTER ENABLE/DISABLE on triggers and rules.
At "DROP RULE/TRIGGER triggername ON ...", tab-complete tables that have a rule/trigger with that name. At "ALTER TABLE tablename ENABLE/DISABLE TRIGGER/RULE ...", tab-complete to rules/triggers on that table. Previously, we would tab-complete to all rules or triggers, not just those that are on that table. Also, filter out internal RI triggers from the list. You can't DROP them, and enabling/disabling them is such a rare (and dangerous) operation that it seems better to hide them. Andreas Karlsson, reviewed by Ian Barwick.
1 parent f8ad8bd commit 631e7f6

File tree

1 file changed

+113
-1
lines changed

1 file changed

+113
-1
lines changed

src/bin/psql/tab-complete.c

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,14 @@ static const SchemaQuery Query_for_list_of_matviews = {
625625
" (SELECT conrelid FROM pg_catalog.pg_constraint "\
626626
" WHERE pg_catalog.quote_ident(conname)='%s')"
627627

628+
/* the silly-looking length condition is just to eat up the current word */
629+
#define Query_for_rule_of_table \
630+
"SELECT pg_catalog.quote_ident(rulename) "\
631+
" FROM pg_catalog.pg_class c1, pg_catalog.pg_rewrite "\
632+
" WHERE c1.oid=ev_class and (%d = pg_catalog.length('%s'))"\
633+
" and pg_catalog.quote_ident(c1.relname)='%s'"\
634+
" and pg_catalog.pg_table_is_visible(c1.oid)"
635+
628636
/* the silly-looking length condition is just to eat up the current word */
629637
#define Query_for_list_of_tables_for_rule \
630638
"SELECT pg_catalog.quote_ident(relname) "\
@@ -634,6 +642,15 @@ static const SchemaQuery Query_for_list_of_matviews = {
634642
" (SELECT ev_class FROM pg_catalog.pg_rewrite "\
635643
" WHERE pg_catalog.quote_ident(rulename)='%s')"
636644

645+
/* the silly-looking length condition is just to eat up the current word */
646+
#define Query_for_trigger_of_table \
647+
"SELECT pg_catalog.quote_ident(tgname) "\
648+
" FROM pg_catalog.pg_class c1, pg_catalog.pg_trigger "\
649+
" WHERE c1.oid=tgrelid and (%d = pg_catalog.length('%s'))"\
650+
" and pg_catalog.quote_ident(c1.relname)='%s'"\
651+
" and pg_catalog.pg_table_is_visible(c1.oid)"\
652+
" and not tgisinternal"
653+
637654
/* the silly-looking length condition is just to eat up the current word */
638655
#define Query_for_list_of_tables_for_trigger \
639656
"SELECT pg_catalog.quote_ident(relname) "\
@@ -774,7 +791,7 @@ static const pgsql_thing_t words_after_create[] = {
774791
{"TEMP", NULL, NULL, THING_NO_DROP}, /* for CREATE TEMP TABLE ... */
775792
{"TEMPLATE", Query_for_list_of_ts_templates, NULL, THING_NO_SHOW},
776793
{"TEXT SEARCH", NULL, NULL},
777-
{"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s'"},
794+
{"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s' AND NOT tgisinternal"},
778795
{"TYPE", NULL, &Query_for_list_of_datatypes},
779796
{"UNIQUE", NULL, NULL, THING_NO_DROP}, /* for CREATE UNIQUE INDEX ... */
780797
{"UNLOGGED", NULL, NULL, THING_NO_DROP}, /* for CREATE UNLOGGED TABLE
@@ -1409,6 +1426,38 @@ psql_completion(const char *text, int start, int end)
14091426

14101427
COMPLETE_WITH_LIST(list_ALTERENABLE2);
14111428
}
1429+
else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
1430+
pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
1431+
pg_strcasecmp(prev2_wd, "ENABLE") == 0 &&
1432+
pg_strcasecmp(prev_wd, "RULE") == 0)
1433+
{
1434+
completion_info_charp = prev3_wd;
1435+
COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1436+
}
1437+
else if (pg_strcasecmp(prev6_wd, "ALTER") == 0 &&
1438+
pg_strcasecmp(prev5_wd, "TABLE") == 0 &&
1439+
pg_strcasecmp(prev3_wd, "ENABLE") == 0 &&
1440+
pg_strcasecmp(prev_wd, "RULE") == 0)
1441+
{
1442+
completion_info_charp = prev4_wd;
1443+
COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1444+
}
1445+
else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
1446+
pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
1447+
pg_strcasecmp(prev2_wd, "ENABLE") == 0 &&
1448+
pg_strcasecmp(prev_wd, "TRIGGER") == 0)
1449+
{
1450+
completion_info_charp = prev3_wd;
1451+
COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1452+
}
1453+
else if (pg_strcasecmp(prev6_wd, "ALTER") == 0 &&
1454+
pg_strcasecmp(prev5_wd, "TABLE") == 0 &&
1455+
pg_strcasecmp(prev3_wd, "ENABLE") == 0 &&
1456+
pg_strcasecmp(prev_wd, "TRIGGER") == 0)
1457+
{
1458+
completion_info_charp = prev4_wd;
1459+
COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1460+
}
14121461
/* ALTER TABLE xxx INHERIT */
14131462
else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
14141463
pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
@@ -1424,6 +1473,7 @@ psql_completion(const char *text, int start, int end)
14241473
{
14251474
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "");
14261475
}
1476+
/* ALTER TABLE xxx DISABLE */
14271477
else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
14281478
pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
14291479
pg_strcasecmp(prev_wd, "DISABLE") == 0)
@@ -1433,6 +1483,22 @@ psql_completion(const char *text, int start, int end)
14331483

14341484
COMPLETE_WITH_LIST(list_ALTERDISABLE);
14351485
}
1486+
else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
1487+
pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
1488+
pg_strcasecmp(prev2_wd, "DISABLE") == 0 &&
1489+
pg_strcasecmp(prev_wd, "RULE") == 0)
1490+
{
1491+
completion_info_charp = prev3_wd;
1492+
COMPLETE_WITH_QUERY(Query_for_rule_of_table);
1493+
}
1494+
else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
1495+
pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
1496+
pg_strcasecmp(prev2_wd, "DISABLE") == 0 &&
1497+
pg_strcasecmp(prev_wd, "TRIGGER") == 0)
1498+
{
1499+
completion_info_charp = prev3_wd;
1500+
COMPLETE_WITH_QUERY(Query_for_trigger_of_table);
1501+
}
14361502

14371503
/* ALTER TABLE xxx ALTER */
14381504
else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
@@ -2587,6 +2653,29 @@ psql_completion(const char *text, int start, int end)
25872653
COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH);
25882654
}
25892655

2656+
/* DROP TRIGGER */
2657+
else if (pg_strcasecmp(prev3_wd, "DROP") == 0 &&
2658+
pg_strcasecmp(prev2_wd, "TRIGGER") == 0)
2659+
{
2660+
COMPLETE_WITH_CONST("ON");
2661+
}
2662+
else if (pg_strcasecmp(prev4_wd, "DROP") == 0 &&
2663+
pg_strcasecmp(prev3_wd, "TRIGGER") == 0 &&
2664+
pg_strcasecmp(prev_wd, "ON") == 0)
2665+
{
2666+
completion_info_charp = prev2_wd;
2667+
COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
2668+
}
2669+
else if (pg_strcasecmp(prev5_wd, "DROP") == 0 &&
2670+
pg_strcasecmp(prev4_wd, "TRIGGER") == 0 &&
2671+
pg_strcasecmp(prev2_wd, "ON") == 0)
2672+
{
2673+
static const char *const list_DROPCR[] =
2674+
{"CASCADE", "RESTRICT", NULL};
2675+
2676+
COMPLETE_WITH_LIST(list_DROPCR);
2677+
}
2678+
25902679
/* DROP EVENT TRIGGER */
25912680
else if (pg_strcasecmp(prev2_wd, "DROP") == 0 &&
25922681
pg_strcasecmp(prev_wd, "EVENT") == 0)
@@ -2600,6 +2689,29 @@ psql_completion(const char *text, int start, int end)
26002689
COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers);
26012690
}
26022691

2692+
/* DROP RULE */
2693+
else if (pg_strcasecmp(prev3_wd, "DROP") == 0 &&
2694+
pg_strcasecmp(prev2_wd, "RULE") == 0)
2695+
{
2696+
COMPLETE_WITH_CONST("ON");
2697+
}
2698+
else if (pg_strcasecmp(prev4_wd, "DROP") == 0 &&
2699+
pg_strcasecmp(prev3_wd, "RULE") == 0 &&
2700+
pg_strcasecmp(prev_wd, "ON") == 0)
2701+
{
2702+
completion_info_charp = prev2_wd;
2703+
COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
2704+
}
2705+
else if (pg_strcasecmp(prev5_wd, "DROP") == 0 &&
2706+
pg_strcasecmp(prev4_wd, "RULE") == 0 &&
2707+
pg_strcasecmp(prev2_wd, "ON") == 0)
2708+
{
2709+
static const char *const list_DROPCR[] =
2710+
{"CASCADE", "RESTRICT", NULL};
2711+
2712+
COMPLETE_WITH_LIST(list_DROPCR);
2713+
}
2714+
26032715
/* EXECUTE, but not EXECUTE embedded in other commands */
26042716
else if (pg_strcasecmp(prev_wd, "EXECUTE") == 0 &&
26052717
prev2_wd[0] == '\0')

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