3
3
*
4
4
* Copyright (c) 2000-2004, PostgreSQL Global Development Group
5
5
*
6
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.115 2004/09/01 00:10:01 momjian Exp $
6
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.116 2004/09/22 04:25:16 neilc Exp $
7
7
*/
8
8
9
9
/*----------------------------------------------------------------------
@@ -386,6 +386,15 @@ static const SchemaQuery Query_for_list_of_views = {
386
386
" and pg_catalog.quote_ident(c1.relname)='%s'"\
387
387
" and pg_catalog.pg_table_is_visible(c2.oid)"
388
388
389
+ /* the silly-looking length condition is just to eat up the current word */
390
+ #define Query_for_list_of_tables_for_trigger \
391
+ "SELECT pg_catalog.quote_ident(relname) "\
392
+ " FROM pg_catalog.pg_class"\
393
+ " WHERE (%d = length('%s'))"\
394
+ " AND oid IN "\
395
+ " (SELECT tgrelid FROM pg_catalog.pg_trigger "\
396
+ " WHERE pg_catalog.quote_ident(tgname)='%s')"
397
+
389
398
/*
390
399
* This is a list of all "things" in Pgsql, which can show up after CREATE or
391
400
* DROP; and there is also a query to get a list of them.
@@ -637,11 +646,13 @@ psql_completion(char *text, int start, int end)
637
646
else if (!prev_wd )
638
647
COMPLETE_WITH_LIST (sql_commands );
639
648
640
- /* CREATE or DROP but not ALTER TABLE sth DROP */
649
+ /* CREATE or DROP but not ALTER ( TABLE|DOMAIN|GROUP) sth DROP */
641
650
/* complete with something you can create or drop */
642
651
else if (pg_strcasecmp (prev_wd , "CREATE" ) == 0 ||
643
652
(pg_strcasecmp (prev_wd , "DROP" ) == 0 &&
644
- pg_strcasecmp (prev3_wd , "TABLE" ) != 0 ))
653
+ pg_strcasecmp (prev3_wd , "TABLE" ) != 0 &&
654
+ pg_strcasecmp (prev3_wd , "DOMAIN" ) != 0 &&
655
+ pg_strcasecmp (prev3_wd , "GROUP" ) != 0 ))
645
656
matches = completion_matches (text , create_command_generator );
646
657
647
658
/* ALTER */
@@ -694,6 +705,22 @@ psql_completion(char *text, int start, int end)
694
705
COMPLETE_WITH_LIST (list_ALTERINDEX );
695
706
}
696
707
708
+ /* ALTER LANGUAGE <name> */
709
+ else if (pg_strcasecmp (prev3_wd , "ALTER" ) == 0 &&
710
+ pg_strcasecmp (prev2_wd , "LANGUAGE" ) == 0 )
711
+ COMPLETE_WITH_CONST ("RENAME TO" );
712
+
713
+ /* ALTER USER <name> */
714
+ else if (pg_strcasecmp (prev3_wd , "ALTER" ) == 0 &&
715
+ pg_strcasecmp (prev2_wd , "USER" ) == 0 )
716
+ {
717
+ static const char * const list_ALTERUSER [] =
718
+ {"ENCRYPTED" , "UNENCRYPTED" , "CREATEDB" , "NOCREATEDB" , "CREATEUSER" ,
719
+ "NOCREATEUSER" , "VALID UNTIL" , "RENAME TO" , "SET" , "RESET" , NULL };
720
+
721
+ COMPLETE_WITH_LIST (list_ALTERUSER );
722
+ }
723
+
697
724
/* ALTER DOMAIN <name> */
698
725
else if (pg_strcasecmp (prev3_wd , "ALTER" ) == 0 &&
699
726
pg_strcasecmp (prev2_wd , "DOMAIN" ) == 0 )
@@ -709,7 +736,7 @@ psql_completion(char *text, int start, int end)
709
736
pg_strcasecmp (prev_wd , "DROP" ) == 0 )
710
737
{
711
738
static const char * const list_ALTERDOMAIN2 [] =
712
- {"CONSTRAINT" , "DEFAULT" , "NOT NULL" , "OWNER TO" , NULL };
739
+ {"CONSTRAINT" , "DEFAULT" , "NOT NULL" , NULL };
713
740
714
741
COMPLETE_WITH_LIST (list_ALTERDOMAIN2 );
715
742
}
@@ -723,11 +750,36 @@ psql_completion(char *text, int start, int end)
723
750
724
751
COMPLETE_WITH_LIST (list_ALTERDOMAIN3 );
725
752
}
753
+ /* ALTER SEQUENCE <name> */
754
+ else if (pg_strcasecmp (prev3_wd , "ALTER" ) == 0 &&
755
+ pg_strcasecmp (prev2_wd , "SEQUENCE" ) == 0 )
756
+ {
757
+ static const char * const list_ALTERSCHEMA [] =
758
+ {"INCREMENT" , "MINVALUE" , "MAXVALUE" , "RESTART" , "NO" , "CACHE" , "CYCLE" , NULL };
759
+
760
+ COMPLETE_WITH_LIST (list_ALTERSCHEMA );
761
+ }
762
+ /* ALTER SEQUENCE <name> NO */
763
+ else if (pg_strcasecmp (prev4_wd , "ALTER" ) == 0 &&
764
+ pg_strcasecmp (prev3_wd , "SEQUENCE" ) == 0 &&
765
+ pg_strcasecmp (prev_wd , "NO" ) == 0 )
766
+ {
767
+ static const char * const list_ALTERSCHEMA2 [] =
768
+ {"MINVALUE" , "MAXVALUE" , "CYCLE" , NULL };
769
+
770
+ COMPLETE_WITH_LIST (list_ALTERSCHEMA2 );
771
+ }
726
772
/* ALTER TRIGGER <name>, add ON */
727
773
else if (pg_strcasecmp (prev3_wd , "ALTER" ) == 0 &&
728
- pg_strcasecmp (prev2_wd , "TRIGGER" ) == 0 &&
729
- pg_strcasecmp (prev_wd , "ON" ) != 0 )
774
+ pg_strcasecmp (prev2_wd , "TRIGGER" ) == 0 )
730
775
COMPLETE_WITH_CONST ("ON" );
776
+
777
+ else if (pg_strcasecmp (prev4_wd , "ALTER" ) == 0 &&
778
+ pg_strcasecmp (prev3_wd , "TRIGGER" ) == 0 )
779
+ {
780
+ completion_info_charp = prev2_wd ;
781
+ COMPLETE_WITH_QUERY (Query_for_list_of_tables_for_trigger );
782
+ }
731
783
732
784
/*
733
785
* If we have ALTER TRIGGER <sth> ON, then add the correct tablename
@@ -737,6 +789,11 @@ psql_completion(char *text, int start, int end)
737
789
pg_strcasecmp (prev_wd , "ON" ) == 0 )
738
790
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tables , NULL );
739
791
792
+ /* ALTER TRIGGER <name> ON <name> */
793
+ else if (pg_strcasecmp (prev4_wd , "TRIGGER" ) == 0 &&
794
+ pg_strcasecmp (prev2_wd , "ON" ) == 0 )
795
+ COMPLETE_WITH_CONST ("RENAME TO" );
796
+
740
797
/*
741
798
* If we detect ALTER TABLE <name>, suggest either ADD, DROP, ALTER,
742
799
* RENAME, CLUSTER ON or OWNER
@@ -756,6 +813,11 @@ psql_completion(char *text, int start, int end)
756
813
pg_strcasecmp (prev_wd , "RENAME" ) == 0 ))
757
814
COMPLETE_WITH_ATTR (prev2_wd );
758
815
816
+ /* ALTER TABLE xxx RENAME yyy */
817
+ else if (pg_strcasecmp (prev4_wd , "TABLE" ) == 0 &&
818
+ pg_strcasecmp (prev2_wd , "RENAME" ) == 0 )
819
+ COMPLETE_WITH_CONST ("TO" );
820
+
759
821
/* If we have TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
760
822
else if (pg_strcasecmp (prev3_wd , "TABLE" ) == 0 &&
761
823
pg_strcasecmp (prev_wd , "DROP" ) == 0 )
@@ -770,6 +832,19 @@ psql_completion(char *text, int start, int end)
770
832
pg_strcasecmp (prev2_wd , "DROP" ) == 0 &&
771
833
pg_strcasecmp (prev_wd , "COLUMN" ) == 0 )
772
834
COMPLETE_WITH_ATTR (prev3_wd );
835
+ /* ALTER TABLE ALTER [COLUMN] <foo> */
836
+ else if ((pg_strcasecmp (prev3_wd , "ALTER" ) == 0 &&
837
+ pg_strcasecmp (prev2_wd , "COLUMN" ) == 0 ) ||
838
+ (pg_strcasecmp (prev4_wd , "TABLE" ) == 0 &&
839
+ pg_strcasecmp (prev2_wd , "ALTER" ) == 0 ))
840
+ {
841
+ /* DROP ... does not work well yet */
842
+ static const char * const list_COLUMNALTER [] =
843
+ {"TYPE" , "SET DEFAULT" , "DROP DEFAULT" , "SET NOT NULL" ,
844
+ "DROP NOT NULL" , "SET STATISTICS" , "SET STORAGE" , NULL };
845
+
846
+ COMPLETE_WITH_LIST (list_COLUMNALTER );
847
+ }
773
848
else if (pg_strcasecmp (prev3_wd , "TABLE" ) == 0 &&
774
849
pg_strcasecmp (prev_wd , "CLUSTER" ) == 0 )
775
850
COMPLETE_WITH_CONST ("ON" );
@@ -817,12 +892,12 @@ psql_completion(char *text, int start, int end)
817
892
else if (pg_strcasecmp (prev3_wd , "ALTER" ) == 0 &&
818
893
pg_strcasecmp (prev2_wd , "TYPE" ) == 0 )
819
894
COMPLETE_WITH_CONST ("OWNER TO" );
820
- /* complete ALTER GROUP <foo> with ADD or DROP */
895
+ /* complete ALTER GROUP <foo> */
821
896
else if (pg_strcasecmp (prev3_wd , "ALTER" ) == 0 &&
822
897
pg_strcasecmp (prev2_wd , "GROUP" ) == 0 )
823
898
{
824
899
static const char * const list_ALTERGROUP [] =
825
- {"ADD" , "DROP" , NULL };
900
+ {"ADD USER " , "DROP USER" , "RENAME TO " , NULL };
826
901
827
902
COMPLETE_WITH_LIST (list_ALTERGROUP );
828
903
}
@@ -926,12 +1001,43 @@ psql_completion(char *text, int start, int end)
926
1001
else if (pg_strcasecmp (prev2_wd , "COPY" ) == 0 ||
927
1002
pg_strcasecmp (prev2_wd , "\\copy" ) == 0 ||
928
1003
pg_strcasecmp (prev2_wd , "BINARY" ) == 0 )
929
- {
930
- static const char * const list_FROMTO [] =
931
- {"FROM" , "TO" , NULL };
1004
+ {
1005
+ static const char * const list_FROMTO [] =
1006
+ {"FROM" , "TO" , NULL };
1007
+
1008
+ COMPLETE_WITH_LIST (list_FROMTO );
1009
+ }
1010
+ /* If we have COPY|BINARY <sth> FROM|TO, complete with filename */
1011
+ else if ((pg_strcasecmp (prev3_wd , "COPY" ) == 0 ||
1012
+ pg_strcasecmp (prev3_wd , "\\copy" ) == 0 ||
1013
+ pg_strcasecmp (prev3_wd , "BINARY" ) == 0 ) &&
1014
+ (pg_strcasecmp (prev_wd , "FROM" ) == 0 ||
1015
+ pg_strcasecmp (prev_wd , "TO" ) == 0 ))
1016
+ matches = completion_matches (text , filename_completion_function );
932
1017
933
- COMPLETE_WITH_LIST (list_FROMTO );
934
- }
1018
+ /* Handle COPY|BINARY <sth> FROM|TO filename */
1019
+ else if ((pg_strcasecmp (prev4_wd , "COPY" ) == 0 ||
1020
+ pg_strcasecmp (prev4_wd , "\\copy" ) == 0 ||
1021
+ pg_strcasecmp (prev4_wd , "BINARY" ) == 0 ) &&
1022
+ (pg_strcasecmp (prev2_wd , "FROM" ) == 0 ||
1023
+ pg_strcasecmp (prev2_wd , "TO" ) == 0 ))
1024
+ {
1025
+ static const char * const list_COPY [] =
1026
+ {"BINARY" , "OIDS" , "DELIMETER" , "NULL" , "CSV" , NULL };
1027
+
1028
+ COMPLETE_WITH_LIST (list_COPY );
1029
+ }
1030
+
1031
+ /* Handle COPY|BINARY <sth> FROM|TO filename CSV */
1032
+ else if (pg_strcasecmp (prev_wd , "CSV" ) == 0 &&
1033
+ (pg_strcasecmp (prev3_wd , "FROM" ) == 0 ||
1034
+ pg_strcasecmp (prev3_wd , "TO" ) == 0 ))
1035
+ {
1036
+ static const char * const list_CSV [] =
1037
+ {"QUOTE" , "ESCAPE" , "FORCE QUOTE" , NULL };
1038
+
1039
+ COMPLETE_WITH_LIST (list_CSV );
1040
+ }
935
1041
936
1042
/* CREATE INDEX */
937
1043
/* First off we complete CREATE UNIQUE with "INDEX" */
@@ -1353,7 +1459,9 @@ psql_completion(char *text, int start, int end)
1353
1459
COMPLETE_WITH_QUERY (Query_for_list_of_users );
1354
1460
/* Complete SET <var> with "TO" */
1355
1461
else if (pg_strcasecmp (prev2_wd , "SET" ) == 0 &&
1356
- pg_strcasecmp (prev4_wd , "UPDATE" ) != 0 )
1462
+ pg_strcasecmp (prev4_wd , "UPDATE" ) != 0 &&
1463
+ pg_strcasecmp (prev_wd , "TABLESPACE" ) != 0 &&
1464
+ pg_strcasecmp (prev4_wd , "DOMAIN" ) != 0 )
1357
1465
COMPLETE_WITH_CONST ("TO" );
1358
1466
/* Suggest possible variable values */
1359
1467
else if (pg_strcasecmp (prev3_wd , "SET" ) == 0 &&
@@ -1432,7 +1540,9 @@ psql_completion(char *text, int start, int end)
1432
1540
1433
1541
/* ... FROM ... */
1434
1542
/* TODO: also include SRF ? */
1435
- else if (pg_strcasecmp (prev_wd , "FROM" ) == 0 )
1543
+ else if (pg_strcasecmp (prev_wd , "FROM" ) == 0 &&
1544
+ pg_strcasecmp (prev3_wd , "COPY" ) != 0 &&
1545
+ pg_strcasecmp (prev3_wd , "\\copy" ) != 0 )
1436
1546
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tsv , NULL );
1437
1547
1438
1548
0 commit comments