-----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 [EMAIL PROTECTED]
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

Reply via email to