Re: psql tab-completion improvements

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Greg Sabino Mullane <greg(at)turnstep(dot)com>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: psql tab-completion improvements
Date: 2004-09-10 01:32:18
Message-ID: 200409100132.i8A1WIM02993@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches


Is this for 8.0? Seems it is fixes.

---------------------------------------------------------------------------

Greg Sabino Mullane wrote:
[ There is text before PGP section. ]
>
[ PGP not available, raw data follows ]
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> NotDashEscaped: You need GnuPG to verify this message
>
>
> Some improvements for the tab-completion of psql. This should
> address all of the items in the todo list and adds some new
> things as well. Specifically:
>
> * Add support for ALTER SEQUENCE ...
> * Add "RENAME TO" for ALTER TRIGGER xx ON yy
> * Pick proper table for ALTER TRIGGER xx ON ...
> * Support for ALTER USER xxx ...
> * Fix ALTER GROUP xxx DROP ...
> * Fix ALTER DOMAIN xxx DROP ...
> * Remove "OWNER TO" from ALTER DOMAIN xx DROP ...
> * Fix ALTER DOMAIN xx SET DEFAULT ..
> * Prevent ALTER INDEX xxx SET TABLESPACE from using "TO"
> * Support for ALTER LANGUAGE xxx (RENAME TO)
> * More support for ALTER TABLE xxx ALTER COLUMN xxx ...
> * More support for COPY
>
> --
> Greg Sabino Mullane greg(at)turnstep(dot)com
> PGP Key: 0x14964AC8 200408311930
>
>
>
>
> Index: tab-complete.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/tab-complete.c,v
> retrieving revision 1.114
> diff -c -r1.114 tab-complete.c
> *** tab-complete.c 29 Aug 2004 05:06:54 -0000 1.114
> --- tab-complete.c 31 Aug 2004 23:25:07 -0000
> ***************
> *** 386,391 ****
> --- 386,400 ----
> " and pg_catalog.quote_ident(c1.relname)='%s'"\
> " and pg_catalog.pg_table_is_visible(c2.oid)"
>
> + /* the silly-looking length condition is just to eat up the current word */
> + #define Query_for_list_of_tables_for_trigger \
> + "SELECT pg_catalog.quote_ident(relname) "\
> + " FROM pg_catalog.pg_class"\
> + " WHERE (%d = length('%s'))"\
> + " AND oid IN "\
> + " (SELECT tgrelid FROM pg_catalog.pg_trigger "\
> + " WHERE pg_catalog.quote_ident(tgname)='%s')"
> +
> /*
> * This is a list of all "things" in Pgsql, which can show up after CREATE or
> * DROP; and there is also a query to get a list of them.
> ***************
> *** 637,647 ****
> else if (!prev_wd)
> COMPLETE_WITH_LIST(sql_commands);
>
> ! /* CREATE or DROP but not ALTER TABLE sth DROP */
> /* complete with something you can create or drop */
> else if (pg_strcasecmp(prev_wd, "CREATE") == 0 ||
> (pg_strcasecmp(prev_wd, "DROP") == 0 &&
> ! pg_strcasecmp(prev3_wd, "TABLE") != 0))
> matches = completion_matches(text, create_command_generator);
>
> /* ALTER */
> --- 646,658 ----
> else if (!prev_wd)
> COMPLETE_WITH_LIST(sql_commands);
>
> ! /* CREATE or DROP but not ALTER (TABLE|DOMAIN|GROUP) sth DROP */
> /* complete with something you can create or drop */
> else if (pg_strcasecmp(prev_wd, "CREATE") == 0 ||
> (pg_strcasecmp(prev_wd, "DROP") == 0 &&
> ! pg_strcasecmp(prev3_wd, "TABLE") != 0 &&
> ! pg_strcasecmp(prev3_wd, "DOMAIN") != 0 &&
> ! pg_strcasecmp(prev3_wd, "GROUP") != 0))
> matches = completion_matches(text, create_command_generator);
>
> /* ALTER */
> ***************
> *** 694,699 ****
> --- 705,726 ----
> COMPLETE_WITH_LIST(list_ALTERINDEX);
> }
>
> + /* ALTER LANGUAGE <name> */
> + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev2_wd, "LANGUAGE") == 0)
> + COMPLETE_WITH_CONST("RENAME TO");
> +
> + /* ALTER USER <name> */
> + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev2_wd, "USER") == 0)
> + {
> + static const char *const list_ALTERUSER[] =
> + {"ENCRYPTED", "UNENCRYPTED", "CREATEDB", "NOCREATEDB", "CREATEUSER",
> + "NOCREATEUSER", "VALID UNTIL", "RENAME TO", "SET", "RESET", NULL};
> +
> + COMPLETE_WITH_LIST(list_ALTERUSER);
> + }
> +
> /* ALTER DOMAIN <name> */
> else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> pg_strcasecmp(prev2_wd, "DOMAIN") == 0)
> ***************
> *** 709,715 ****
> pg_strcasecmp(prev_wd, "DROP") == 0)
> {
> static const char *const list_ALTERDOMAIN2[] =
> ! {"CONSTRAINT", "DEFAULT", "NOT NULL", "OWNER TO", NULL};
>
> COMPLETE_WITH_LIST(list_ALTERDOMAIN2);
> }
> --- 736,742 ----
> pg_strcasecmp(prev_wd, "DROP") == 0)
> {
> static const char *const list_ALTERDOMAIN2[] =
> ! {"CONSTRAINT", "DEFAULT", "NOT NULL", NULL};
>
> COMPLETE_WITH_LIST(list_ALTERDOMAIN2);
> }
> ***************
> *** 723,733 ****
>
> COMPLETE_WITH_LIST(list_ALTERDOMAIN3);
> }
> /* ALTER TRIGGER <name>, add ON */
> else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> ! pg_strcasecmp(prev2_wd, "TRIGGER") == 0 &&
> ! pg_strcasecmp(prev_wd, "ON") != 0)
> ! COMPLETE_WITH_CONST("ON");
>
> /*
> * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
> --- 750,785 ----
>
> COMPLETE_WITH_LIST(list_ALTERDOMAIN3);
> }
> + /* ALTER SEQUENCE <name> */
> + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev2_wd, "SEQUENCE") == 0)
> + {
> + static const char *const list_ALTERSCHEMA[] =
> + {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE", NULL};
> +
> + COMPLETE_WITH_LIST(list_ALTERSCHEMA);
> + }
> + /* ALTER SEQUENCE <name> NO */
> + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev3_wd, "SEQUENCE") == 0 &&
> + pg_strcasecmp(prev_wd, "NO") == 0)
> + {
> + static const char *const list_ALTERSCHEMA2[] =
> + {"MINVALUE", "MAXVALUE", "CYCLE", NULL};
> +
> + COMPLETE_WITH_LIST(list_ALTERSCHEMA2);
> + }
> /* ALTER TRIGGER <name>, add ON */
> else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> ! pg_strcasecmp(prev2_wd, "TRIGGER") == 0)
> ! COMPLETE_WITH_CONST("ON");
> !
> ! else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
> ! pg_strcasecmp(prev3_wd, "TRIGGER") == 0)
> ! {
> ! completion_info_charp = prev2_wd;
> ! COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger);
> ! }
>
> /*
> * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
> ***************
> *** 737,742 ****
> --- 789,799 ----
> pg_strcasecmp(prev_wd, "ON") == 0)
> COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
>
> + /* ALTER TRIGGER <name> ON <name> */
> + else if (pg_strcasecmp(prev4_wd, "TRIGGER") == 0 &&
> + pg_strcasecmp(prev2_wd, "ON") == 0)
> + COMPLETE_WITH_CONST("RENAME TO");
> +
> /*
> * If we detect ALTER TABLE <name>, suggest either ADD, DROP, ALTER,
> * RENAME, CLUSTER ON or OWNER
> ***************
> *** 756,761 ****
> --- 813,823 ----
> pg_strcasecmp(prev_wd, "RENAME") == 0))
> COMPLETE_WITH_ATTR(prev2_wd);
>
> + /* ALTER TABLE xxx RENAME yyy */
> + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
> + pg_strcasecmp(prev2_wd, "RENAME") == 0)
> + COMPLETE_WITH_CONST("TO");
> +
> /* If we have TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
> else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
> pg_strcasecmp(prev_wd, "DROP") == 0)
> ***************
> *** 770,775 ****
> --- 832,850 ----
> pg_strcasecmp(prev2_wd, "DROP") == 0 &&
> pg_strcasecmp(prev_wd, "COLUMN") == 0)
> COMPLETE_WITH_ATTR(prev3_wd);
> + /* ALTER TABLE ALTER [COLUMN] <foo> */
> + else if ((pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> + pg_strcasecmp(prev2_wd, "COLUMN") == 0) ||
> + (pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
> + pg_strcasecmp(prev2_wd, "ALTER") == 0))
> + {
> + /* DROP ... does not work well yet */
> + static const char *const list_COLUMNALTER[] =
> + {"TYPE", "SET DEFAULT", "DROP DEFAULT", "SET NOT NULL", "DROP NOT NULL",
> + "SET STATISTICS", "SET STORAGE", NULL};
> +
> + COMPLETE_WITH_LIST(list_COLUMNALTER);
> + }
> else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
> pg_strcasecmp(prev_wd, "CLUSTER") == 0)
> COMPLETE_WITH_CONST("ON");
> ***************
> *** 817,828 ****
> else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> pg_strcasecmp(prev2_wd, "TYPE") == 0)
> COMPLETE_WITH_CONST("OWNER TO");
> ! /* complete ALTER GROUP <foo> with ADD or DROP */
> else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> pg_strcasecmp(prev2_wd, "GROUP") == 0)
> {
> static const char *const list_ALTERGROUP[] =
> ! {"ADD", "DROP", NULL};
>
> COMPLETE_WITH_LIST(list_ALTERGROUP);
> }
> --- 892,903 ----
> else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> pg_strcasecmp(prev2_wd, "TYPE") == 0)
> COMPLETE_WITH_CONST("OWNER TO");
> ! /* complete ALTER GROUP <foo> */
> else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
> pg_strcasecmp(prev2_wd, "GROUP") == 0)
> {
> static const char *const list_ALTERGROUP[] =
> ! {"ADD USER", "DROP USER", "RENAME TO", NULL};
>
> COMPLETE_WITH_LIST(list_ALTERGROUP);
> }
> ***************
> *** 926,937 ****
> else if (pg_strcasecmp(prev2_wd, "COPY") == 0 ||
> pg_strcasecmp(prev2_wd, "\\copy") == 0 ||
> pg_strcasecmp(prev2_wd, "BINARY") == 0)
> ! {
> ! static const char *const list_FROMTO[] =
> ! {"FROM", "TO", NULL};
>
> ! COMPLETE_WITH_LIST(list_FROMTO);
> ! }
>
> /* CREATE INDEX */
> /* First off we complete CREATE UNIQUE with "INDEX" */
> --- 1001,1043 ----
> else if (pg_strcasecmp(prev2_wd, "COPY") == 0 ||
> pg_strcasecmp(prev2_wd, "\\copy") == 0 ||
> pg_strcasecmp(prev2_wd, "BINARY") == 0)
> ! {
> ! static const char *const list_FROMTO[] =
> ! {"FROM", "TO", NULL};
> !
> ! COMPLETE_WITH_LIST(list_FROMTO);
> ! }
> ! /* If we have COPY|BINARY <sth> FROM|TO, complete with filename */
> ! else if ((pg_strcasecmp(prev3_wd, "COPY") == 0 ||
> ! pg_strcasecmp(prev3_wd, "\\copy") == 0 ||
> ! pg_strcasecmp(prev3_wd, "BINARY") == 0) &&
> ! (pg_strcasecmp(prev_wd, "FROM") == 0 ||
> ! pg_strcasecmp(prev_wd, "TO") == 0))
> ! matches = completion_matches(text, filename_completion_function);
>
> ! /* Handle COPY|BINARY <sth> FROM|TO filename */
> ! else if ((pg_strcasecmp(prev4_wd, "COPY") == 0 ||
> ! pg_strcasecmp(prev4_wd, "\\copy") == 0 ||
> ! pg_strcasecmp(prev4_wd, "BINARY") == 0) &&
> ! (pg_strcasecmp(prev2_wd, "FROM") == 0 ||
> ! pg_strcasecmp(prev2_wd, "TO") == 0))
> ! {
> ! static const char *const list_COPY[] =
> ! {"BINARY", "OIDS", "DELIMETER", "NULL", "CSV", NULL};
> !
> ! COMPLETE_WITH_LIST(list_COPY);
> ! }
> !
> ! /* Handle COPY|BINARY <sth> FROM|TO filename CSV */
> ! else if (pg_strcasecmp(prev_wd, "CSV") == 0 &&
> ! (pg_strcasecmp(prev3_wd, "FROM") == 0 ||
> ! pg_strcasecmp(prev3_wd, "TO") == 0))
> ! {
> ! static const char *const list_CSV[] =
> ! {"QUOTE", "ESCAPE", "FORCE QUOTE", NULL};
> !
> ! COMPLETE_WITH_LIST(list_CSV);
> ! }
>
> /* CREATE INDEX */
> /* First off we complete CREATE UNIQUE with "INDEX" */
> ***************
> *** 1353,1359 ****
> COMPLETE_WITH_QUERY(Query_for_list_of_users);
> /* Complete SET <var> with "TO" */
> else if (pg_strcasecmp(prev2_wd, "SET") == 0 &&
> ! pg_strcasecmp(prev4_wd, "UPDATE") != 0)
> COMPLETE_WITH_CONST("TO");
> /* Suggest possible variable values */
> else if (pg_strcasecmp(prev3_wd, "SET") == 0 &&
> --- 1459,1467 ----
> COMPLETE_WITH_QUERY(Query_for_list_of_users);
> /* Complete SET <var> with "TO" */
> else if (pg_strcasecmp(prev2_wd, "SET") == 0 &&
> ! pg_strcasecmp(prev4_wd, "UPDATE") != 0 &&
> ! pg_strcasecmp(prev_wd, "TABLESPACE") != 0 &&
> ! pg_strcasecmp(prev4_wd, "DOMAIN") != 0)
> COMPLETE_WITH_CONST("TO");
> /* Suggest possible variable values */
> else if (pg_strcasecmp(prev3_wd, "SET") == 0 &&
> ***************
> *** 1432,1438 ****
>
> /* ... FROM ... */
> /* TODO: also include SRF ? */
> ! else if (pg_strcasecmp(prev_wd, "FROM") == 0)
> COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL);
>
>
> --- 1540,1548 ----
>
> /* ... FROM ... */
> /* TODO: also include SRF ? */
> ! else if (pg_strcasecmp(prev_wd, "FROM") == 0 &&
> ! pg_strcasecmp(prev3_wd, "COPY") != 0 &&
> ! pg_strcasecmp(prev3_wd, "\\copy") != 0)
> COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL);
>
>
>
>
> -----BEGIN PGP SIGNATURE-----
>
> iD8DBQFBNQrPvJuQZxSWSsgRAqU2AKDEoTixdsiLcpZOKpY4Na1UNZmmSgCcDsxQ
> 7gyOrB6e2Pvtt5KrecRVULA=
> =/xhb
> -----END PGP SIGNATURE-----
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
> http://archives.postgresql.org
>
[ Decrypting message... End of raw data. ]

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

In response to

Responses

Browse pgsql-patches by date

  From Date Subject
Next Message Greg Sabino Mullane 2004-09-10 02:05:02 Re: psql tab-completion improvements
Previous Message Alvaro Herrera 2004-09-10 01:01:54 Re: Clarification of action on Delete