3
3
*
4
4
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
5
5
*
6
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.110 2004/08/2004:29:32 momjian Exp $
6
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.111 2004/08/2019:24:59 momjian Exp $
7
7
*/
8
8
9
9
/*----------------------------------------------------------------------
@@ -328,6 +328,10 @@ static const SchemaQuery Query_for_list_of_views = {
328
328
"SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\
329
329
" WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s'"
330
330
331
+ #define Query_for_list_of_tablespaces \
332
+ "SELECT pg_catalog.quote_ident(spcname) FROM pg_catalog.pg_tablespace "\
333
+ " WHERE substring(pg_catalog.quote_ident(spcname),1,%d)='%s'"
334
+
331
335
#define Query_for_list_of_encodings \
332
336
" SELECT DISTINCT pg_catalog.pg_encoding_to_char(conforencoding) "\
333
337
" FROM pg_catalog.pg_conversion "\
@@ -365,6 +369,15 @@ static const SchemaQuery Query_for_list_of_views = {
365
369
" and pg_catalog.quote_ident(c2.relname)='%s'"\
366
370
" and pg_catalog.pg_table_is_visible(c2.oid)"
367
371
372
+ /* the silly-looking length condition is just to eat up the current word */
373
+ #define Query_for_index_of_table \
374
+ "SELECT pg_catalog.quote_ident(c2.relname) "\
375
+ " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
376
+ " WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
377
+ " and (%d = length('%s'))"\
378
+ " and pg_catalog.quote_ident(c1.relname)='%s'"\
379
+ " and pg_catalog.pg_table_is_visible(c2.oid)"
380
+
368
381
/*
369
382
* This is a list of all "things" in Pgsql, which can show up after CREATE or
370
383
* DROP; and there is also a query to get a list of them.
@@ -394,6 +407,7 @@ static const pgsql_thing_t words_after_create[] = {
394
407
{"SCHEMA" ,Query_for_list_of_schemas },
395
408
{"SEQUENCE" ,NULL ,& Query_for_list_of_sequences },
396
409
{"TABLE" ,NULL ,& Query_for_list_of_tables },
410
+ {"TABLESPACE" ,Query_for_list_of_tablespaces },
397
411
{"TEMP" ,NULL ,NULL },/* for CREATE TEMP TABLE ... */
398
412
{"TRIGGER" ,"SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s'" },
399
413
{"TYPE" ,NULL ,& Query_for_list_of_datatypes },
@@ -461,7 +475,7 @@ psql_completion(char *text, int start, int end)
461
475
462
476
static const char * const sql_commands []= {
463
477
"ABORT" ,"ALTER" ,"ANALYZE" ,"BEGIN" ,"CHECKPOINT" ,"CLOSE" ,"CLUSTER" ,"COMMENT" ,
464
- "COMMIT" ,"COPY" ,"CREATE" ,"DEALLOCATE" ,"DECLARE" ,"DELETE" ,"DROP" ,"EXECUTE" ,
478
+ "COMMIT" ,"COPY" ,"CREATE" ,"DEALLOCATE" ,"DECLARE" ,"DELETE" ,"DROP" ,"END" , " EXECUTE" ,
465
479
"EXPLAIN" ,"FETCH" ,"GRANT" ,"INSERT" ,"LISTEN" ,"LOAD" ,"LOCK" ,"MOVE" ,"NOTIFY" ,
466
480
"PREPARE" ,"REINDEX" ,"RELEASE" ,"RESET" ,"REVOKE" ,"ROLLBACK" ,"SAVEPOINT" ,
467
481
"SELECT" ,"SET" ,"SHOW" ,"START" ,"TRUNCATE" ,"UNLISTEN" ,"UPDATE" ,"VACUUM" ,NULL
@@ -575,9 +589,9 @@ psql_completion(char *text, int start, int end)
575
589
576
590
static const char * const backslash_commands []= {
577
591
"\\a" ,"\\connect" ,"\\C" ,"\\cd" ,"\\copy" ,"\\copyright" ,
578
- "\\d" ,"\\da" ,"\\dc " ,"\\dC " ,"\\dd " ,"\\dD " ,"\\df " ,"\\dg" , "\\di " ,
579
- "\\dl " ,"\\dn " ,"\\do " ,"\\dp " ,"\\ds " ,"\\dS " ,"\\dt " ,"\\dT " ,
580
- "\\dv" ,"\\du" ,
592
+ "\\d" ,"\\da" ,"\\db " ,"\\dc " ,"\\dC " ,"\\dd " ,"\\dD " ,"\\df " ,
593
+ "\\dg " ,"\\di " ,"\\dl " ,"\\dn " ,"\\do " ,"\\dp " ,"\\ds " ,"\\dS " ,
594
+ "\\dt" , "\\dT" , "\\ dv" ,"\\du" ,
581
595
"\\e" ,"\\echo" ,"\\encoding" ,
582
596
"\\f" ,"\\g" ,"\\h" ,"\\help" ,"\\H" ,"\\i" ,"\\l" ,
583
597
"\\lo_import" ,"\\lo_export" ,"\\lo_list" ,"\\lo_unlink" ,
@@ -632,11 +646,25 @@ psql_completion(char *text, int start, int end)
632
646
pg_strcasecmp (prev3_wd ,"TABLE" )!= 0 )
633
647
{
634
648
static const char * const list_ALTER []=
635
- {"DATABASE" ,"GROUP" ,"SCHEMA" ,"TABLE" ,"TRIGGER" ,"USER" ,"INDEX" ,
636
- NULL };
649
+ {"AGGREGATE" ,"CONVERSATION" ,"DATABASE" ,"DOMAIN" ,"FUNCTION" ,
650
+ "GROUP" ,"LANGUAGE" ,"OPERATOR" ,"SCHEMA" ,"SEQUENCE" ,"TABLE" ,
651
+ "TABLESPACE" ,"TRIGGER" ,"TYPE" ,"USER" ,NULL };
637
652
638
653
COMPLETE_WITH_LIST (list_ALTER );
639
654
}
655
+
656
+ /* ALTER AGGREGATE,CONVERSION,FUNCTION,SCHEMA <name> */
657
+ else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
658
+ (pg_strcasecmp (prev2_wd ,"AGGREGATE" )== 0 ||
659
+ pg_strcasecmp (prev2_wd ,"CONVERSION" )== 0 ||
660
+ pg_strcasecmp (prev2_wd ,"FUNCTION" )== 0 ||
661
+ pg_strcasecmp (prev2_wd ,"SCHEMA" )== 0 ))
662
+ {
663
+ static const char * const list_ALTERGEN []=
664
+ {"OWNER TO" ,"RENAME TO" ,NULL };
665
+
666
+ COMPLETE_WITH_LIST (list_ALTERGEN );
667
+ }
640
668
641
669
/* ALTER DATABASE <name> */
642
670
else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
@@ -649,17 +677,47 @@ psql_completion(char *text, int start, int end)
649
677
}
650
678
/* ALTER INDEX <name> */
651
679
else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
652
- pg_strcasecmp (prev2_wd ,"INDEX" )== 0 )
653
- {
654
- static const char * const list_ALTERINDEX []=
655
- {"SET TABLESPACE" ,"OWNER TO" ,"RENAME TO" ,NULL };
656
-
657
- COMPLETE_WITH_LIST (list_ALTERINDEX );
658
- }
680
+ pg_strcasecmp (prev2_wd ,"INDEX" )== 0 )
681
+ {
682
+ static const char * const list_ALTERINDEX []=
683
+ {"SET TABLESPACE" ,"OWNER TO" ,"RENAME TO" ,NULL };
684
+
685
+ COMPLETE_WITH_LIST (list_ALTERINDEX );
686
+ }
687
+
688
+ /* ALTER DOMAIN <name> */
689
+ else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
690
+ pg_strcasecmp (prev2_wd ,"DOMAIN" )== 0 )
691
+ {
692
+ static const char * const list_ALTERDOMAIN []=
693
+ {"ADD" ,"DROP" ,"OWNER TO" ,"SET" ,NULL };
659
694
695
+ COMPLETE_WITH_LIST (list_ALTERDOMAIN );
696
+ }
697
+ /* ALTER DOMAIN <sth> DROP */
698
+ else if (pg_strcasecmp (prev4_wd ,"ALTER" )== 0 &&
699
+ pg_strcasecmp (prev3_wd ,"DOMAIN" )== 0 &&
700
+ pg_strcasecmp (prev_wd ,"DROP" )== 0 )
701
+ {
702
+ static const char * const list_ALTERDOMAIN2 []=
703
+ {"CONSTRAINT" ,"DEFAULT" ,"NOT NULL" ,"OWNER TO" ,NULL };
704
+
705
+ COMPLETE_WITH_LIST (list_ALTERDOMAIN2 );
706
+ }
707
+ /* ALTER DOMAIN <sth> SET */
708
+ else if (pg_strcasecmp (prev4_wd ,"ALTER" )== 0 &&
709
+ pg_strcasecmp (prev3_wd ,"DOMAIN" )== 0 &&
710
+ pg_strcasecmp (prev_wd ,"SET" )== 0 )
711
+ {
712
+ static const char * const list_ALTERDOMAIN3 []=
713
+ {"DEFAULT" ,"NOT NULL" ,NULL };
714
+
715
+ COMPLETE_WITH_LIST (list_ALTERDOMAIN3 );
716
+ }
660
717
/* ALTER TRIGGER <name>, add ON */
661
718
else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
662
- pg_strcasecmp (prev2_wd ,"TRIGGER" )== 0 )
719
+ pg_strcasecmp (prev2_wd ,"TRIGGER" )== 0 &&
720
+ pg_strcasecmp (prev_wd ,"ON" )!= 0 )
663
721
COMPLETE_WITH_CONST ("ON" );
664
722
665
723
/*
@@ -672,13 +730,14 @@ psql_completion(char *text, int start, int end)
672
730
673
731
/*
674
732
* If we detect ALTER TABLE <name>, suggest either ADD, DROP, ALTER,
675
- * RENAME, or OWNER
733
+ * RENAME,CLUSTER ON or OWNER
676
734
*/
677
735
else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
678
736
pg_strcasecmp (prev2_wd ,"TABLE" )== 0 )
679
737
{
680
738
static const char * const list_ALTER2 []=
681
- {"ADD" ,"ALTER" ,"DROP" ,"RENAME" ,"OWNER TO" ,NULL };
739
+ {"ADD" ,"ALTER" ,"CLUSTER ON" ,"DROP" ,"RENAME" ,"OWNER TO" ,
740
+ "SET" ,NULL };
682
741
683
742
COMPLETE_WITH_LIST (list_ALTER2 );
684
743
}
@@ -702,7 +761,53 @@ psql_completion(char *text, int start, int end)
702
761
pg_strcasecmp (prev2_wd ,"DROP" )== 0 &&
703
762
pg_strcasecmp (prev_wd ,"COLUMN" )== 0 )
704
763
COMPLETE_WITH_ATTR (prev3_wd );
764
+ else if (pg_strcasecmp (prev3_wd ,"TABLE" )== 0 &&
765
+ pg_strcasecmp (prev_wd ,"CLUSTER" )== 0 )
766
+ COMPLETE_WITH_CONST ("ON" );
767
+ else if (pg_strcasecmp (prev4_wd ,"TABLE" )== 0 &&
768
+ pg_strcasecmp (prev2_wd ,"CLUSTER" )== 0 &&
769
+ pg_strcasecmp (prev_wd ,"ON" )== 0 )
770
+ {
771
+ completion_info_charp = prev3_wd ;
772
+ COMPLETE_WITH_QUERY (Query_for_index_of_table );
773
+ }
774
+ /* If we have TABLE <sth> SET, provide WITHOUT or TABLESPACE */
775
+ else if (pg_strcasecmp (prev3_wd ,"TABLE" )== 0 &&
776
+ pg_strcasecmp (prev_wd ,"SET" )== 0 )
777
+ {
778
+ static const char * const list_TABLESET []=
779
+ {"WITHOUT" ,"TABLESPACE" ,NULL };
780
+
781
+ COMPLETE_WITH_LIST (list_TABLESET );
782
+ }
783
+ /* If we have TABLE <sth> SET TABLESPACE provide a list of tablespaces*/
784
+ else if (pg_strcasecmp (prev4_wd ,"TABLE" )== 0 &&
785
+ pg_strcasecmp (prev2_wd ,"SET" )== 0 &&
786
+ pg_strcasecmp (prev_wd ,"TABLESPACE" )== 0 )
787
+ COMPLETE_WITH_QUERY (Query_for_list_of_tablespaces );
788
+ /* If we have TABLE <sth> SET WITHOUT provide CLUSTER or OIDS*/
789
+ else if (pg_strcasecmp (prev4_wd ,"TABLE" )== 0 &&
790
+ pg_strcasecmp (prev2_wd ,"SET" )== 0 &&
791
+ pg_strcasecmp (prev_wd ,"WITHOUT" )== 0 )
792
+ {
793
+ static const char * const list_TABLESET2 []=
794
+ {"CLUSTER" ,"OIDS" ,NULL };
705
795
796
+ COMPLETE_WITH_LIST (list_TABLESET2 );
797
+ }
798
+ /* we have ALTER TABLESPACE, so suggest RENAME TO, OWNER TO */
799
+ else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
800
+ pg_strcasecmp (prev2_wd ,"TABLESPACE" )== 0 )
801
+ {
802
+ static const char * const list_ALTERTSPC []=
803
+ {"RENAME TO" ,"OWNER TO" ,NULL };
804
+
805
+ COMPLETE_WITH_LIST (list_ALTERTSPC );
806
+ }
807
+ /* complete ALTER TYPE <foo> with OWNER TO */
808
+ else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
809
+ pg_strcasecmp (prev2_wd ,"TYPE" )== 0 )
810
+ COMPLETE_WITH_CONST ("OWNER TO" );
706
811
/* complete ALTER GROUP <foo> with ADD or DROP */
707
812
else if (pg_strcasecmp (prev3_wd ,"ALTER" )== 0 &&
708
813
pg_strcasecmp (prev2_wd ,"GROUP" )== 0 )
@@ -744,20 +849,26 @@ psql_completion(char *text, int start, int end)
744
849
745
850
COMPLETE_WITH_LIST (list_TRANS );
746
851
}
852
+ /* RELEASE SAVEPOINT */
853
+ else if (pg_strcasecmp (prev_wd ,"RELEASE" )== 0 )
854
+ COMPLETE_WITH_CONST ("SAVEPOINT" );
747
855
/* ROLLBACK*/
748
856
else if (pg_strcasecmp (prev_wd ,"ROLLBACK" )== 0 )
749
857
{
750
858
static const char * const list_TRANS []=
751
- {"WORK" ,"TRANSACTION" ,"TO" ,NULL };
859
+ {"WORK" ,"TRANSACTION" ,"TO SAVEPOINT " ,NULL };
752
860
753
861
COMPLETE_WITH_LIST (list_TRANS );
754
862
}
755
863
/* CLUSTER */
756
- /* If the previous word is CLUSTER, produce list of indexes. */
757
- else if (pg_strcasecmp (prev_wd ,"CLUSTER" )== 0 )
864
+ /* If the previous word is CLUSTER and not without produce list
865
+ * of indexes. */
866
+ else if (pg_strcasecmp (prev_wd ,"CLUSTER" )== 0 &&
867
+ pg_strcasecmp (prev2_wd ,"WITHOUT" )!= 0 )
758
868
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_indexes ,NULL );
759
869
/* If we have CLUSTER <sth>, then add "ON" */
760
- else if (pg_strcasecmp (prev2_wd ,"CLUSTER" )== 0 )
870
+ else if (pg_strcasecmp (prev2_wd ,"CLUSTER" )== 0 &&
871
+ pg_strcasecmp (prev_wd ,"ON" )!= 0 )
761
872
COMPLETE_WITH_CONST ("ON" );
762
873
763
874
/*
@@ -778,9 +889,9 @@ psql_completion(char *text, int start, int end)
778
889
pg_strcasecmp (prev_wd ,"ON" )== 0 )
779
890
{
780
891
static const char * const list_COMMENT []=
781
- {"DATABASE " ,"INDEX " ,"RULE " ,"SCHEMA " ,"SEQUENCE " ,"TABLE " ,
782
- "TYPE" ,"VIEW" ,"COLUMN" ,"AGGREGATE" ,"FUNCTION" , "OPERATOR " ,
783
- "TRIGGER" ,"CONSTRAINT" ,"DOMAIN" ,NULL };
892
+ {"CAST " ,"CONVERSION " ,"DATABASE " ,"INDEX " ,"LANGUAGE " ,"RULE" , "SCHEMA " ,
893
+ "SEQUENCE" , "TABLE" , " TYPE" ,"VIEW" ,"COLUMN" ,"AGGREGATE" ,"FUNCTION" ,
894
+ "OPERATOR" , " TRIGGER" ,"CONSTRAINT" ,"DOMAIN" ,NULL };
784
895
785
896
COMPLETE_WITH_LIST (list_COMMENT );
786
897
}
@@ -935,7 +1046,7 @@ psql_completion(char *text, int start, int end)
935
1046
pg_strcasecmp (prev_wd ,"MOVE" )== 0 )
936
1047
{
937
1048
static const char * const list_FETCH1 []=
938
- {"FORWARD " ,"BACKWARD" ,"RELATIVE" ,NULL };
1049
+ {"ABSOLUT " ,"BACKWARD" , "FORWARD " ,"RELATIVE" ,NULL };
939
1050
940
1051
COMPLETE_WITH_LIST (list_FETCH1 );
941
1052
}
@@ -996,7 +1107,8 @@ psql_completion(char *text, int start, int end)
996
1107
" UNION SELECT 'DATABASE'"
997
1108
" UNION SELECT 'FUNCTION'"
998
1109
" UNION SELECT 'LANGUAGE'"
999
- " UNION SELECT 'SCHEMA'" );
1110
+ " UNION SELECT 'SCHEMA'"
1111
+ " UNION SELECT 'TABLESPACE'" );
1000
1112
1001
1113
/* Complete "GRANT/REVOKE * ON * " with "TO" */
1002
1114
else if ((pg_strcasecmp (prev4_wd ,"GRANT" )== 0 ||
@@ -1011,14 +1123,16 @@ psql_completion(char *text, int start, int end)
1011
1123
COMPLETE_WITH_QUERY (Query_for_list_of_languages );
1012
1124
else if (pg_strcasecmp (prev_wd ,"SCHEMA" )== 0 )
1013
1125
COMPLETE_WITH_QUERY (Query_for_list_of_schemas );
1126
+ else if (pg_strcasecmp (prev_wd ,"TABLESPACE" )== 0 )
1127
+ COMPLETE_WITH_QUERY (Query_for_list_of_tablespaces );
1014
1128
else
1015
1129
COMPLETE_WITH_CONST ("TO" );
1016
1130
}
1017
1131
1018
1132
/*
1019
1133
* TODO: to complete with user name we need prev5_wd -- wait for a
1020
1134
* more general solution there same for GRANT <sth> ON { DATABASE |
1021
- * FUNCTION | LANGUAGE | SCHEMA } xxx TO
1135
+ * FUNCTION | LANGUAGE | SCHEMA| TABLESPACE } xxx TO
1022
1136
*/
1023
1137
1024
1138
/* INSERT */
@@ -1098,7 +1212,10 @@ psql_completion(char *text, int start, int end)
1098
1212
/* NOTIFY */
1099
1213
else if (pg_strcasecmp (prev_wd ,"NOTIFY" )== 0 )
1100
1214
COMPLETE_WITH_QUERY ("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s'" );
1101
-
1215
+ /* OWNER TO - complete with available users*/
1216
+ else if (pg_strcasecmp (prev2_wd ,"OWNER" )== 0 &&
1217
+ pg_strcasecmp (prev_wd ,"TO" )== 0 )
1218
+ COMPLETE_WITH_QUERY (Query_for_list_of_users );
1102
1219
/* REINDEX */
1103
1220
else if (pg_strcasecmp (prev_wd ,"REINDEX" )== 0 )
1104
1221
{
@@ -1147,16 +1264,20 @@ psql_completion(char *text, int start, int end)
1147
1264
COMPLETE_WITH_LIST (my_list );
1148
1265
}
1149
1266
else if ((pg_strcasecmp (prev3_wd ,"SET" )== 0
1267
+ || pg_strcasecmp (prev3_wd ,"BEGIN" )== 0
1150
1268
|| pg_strcasecmp (prev3_wd ,"START" )== 0
1151
1269
|| (pg_strcasecmp (prev4_wd ,"CHARACTERISTICS" )== 0
1152
1270
&& pg_strcasecmp (prev3_wd ,"AS" )== 0 ))
1153
- && pg_strcasecmp (prev2_wd ,"TRANSACTION" )== 0
1271
+ && (pg_strcasecmp (prev2_wd ,"TRANSACTION" )== 0
1272
+ || pg_strcasecmp (prev2_wd ,"WORK" )== 0 )
1154
1273
&& pg_strcasecmp (prev_wd ,"ISOLATION" )== 0 )
1155
1274
COMPLETE_WITH_CONST ("LEVEL" );
1156
1275
else if ((pg_strcasecmp (prev4_wd ,"SET" )== 0
1276
+ || pg_strcasecmp (prev4_wd ,"BEGIN" )== 0
1157
1277
|| pg_strcasecmp (prev4_wd ,"START" )== 0
1158
1278
|| pg_strcasecmp (prev4_wd ,"AS" )== 0 )
1159
- && pg_strcasecmp (prev3_wd ,"TRANSACTION" )== 0
1279
+ && (pg_strcasecmp (prev3_wd ,"TRANSACTION" )== 0
1280
+ || pg_strcasecmp (prev3_wd ,"WORK" )== 0 )
1160
1281
&& pg_strcasecmp (prev2_wd ,"ISOLATION" )== 0
1161
1282
&& pg_strcasecmp (prev_wd ,"LEVEL" )== 0 )
1162
1283
{
@@ -1165,7 +1286,8 @@ psql_completion(char *text, int start, int end)
1165
1286
1166
1287
COMPLETE_WITH_LIST (my_list );
1167
1288
}
1168
- else if (pg_strcasecmp (prev4_wd ,"TRANSACTION" )== 0 &&
1289
+ else if ((pg_strcasecmp (prev4_wd ,"TRANSACTION" )== 0 ||
1290
+ pg_strcasecmp (prev4_wd ,"WORK" )== 0 )&&
1169
1291
pg_strcasecmp (prev3_wd ,"ISOLATION" )== 0 &&
1170
1292
pg_strcasecmp (prev2_wd ,"LEVEL" )== 0 &&
1171
1293
pg_strcasecmp (prev_wd ,"READ" )== 0 )
@@ -1175,14 +1297,18 @@ psql_completion(char *text, int start, int end)
1175
1297
1176
1298
COMPLETE_WITH_LIST (my_list );
1177
1299
}
1178
- else if (pg_strcasecmp (prev4_wd ,"TRANSACTION" )== 0 &&
1300
+ else if ((pg_strcasecmp (prev4_wd ,"TRANSACTION" )== 0 ||
1301
+ pg_strcasecmp (prev4_wd ,"WORK" )== 0 )&&
1179
1302
pg_strcasecmp (prev3_wd ,"ISOLATION" )== 0 &&
1180
1303
pg_strcasecmp (prev2_wd ,"LEVEL" )== 0 &&
1181
1304
pg_strcasecmp (prev_wd ,"REPEATABLE" )== 0 )
1182
1305
COMPLETE_WITH_CONST ("READ" );
1183
1306
else if ((pg_strcasecmp (prev3_wd ,"SET" )== 0 ||
1184
- pg_strcasecmp (prev3_wd ,"AS" )== 0 )&&
1185
- pg_strcasecmp (prev2_wd ,"TRANSACTION" )== 0 &&
1307
+ pg_strcasecmp (prev3_wd ,"BEGIN" )== 0 ||
1308
+ pg_strcasecmp (prev3_wd ,"START" )== 0 ||
1309
+ pg_strcasecmp (prev3_wd ,"AS" )== 0 )&&
1310
+ (pg_strcasecmp (prev2_wd ,"TRANSACTION" )== 0 ||
1311
+ pg_strcasecmp (prev2_wd ,"WORK" )== 0 )&&
1186
1312
pg_strcasecmp (prev_wd ,"READ" )== 0 )
1187
1313
{
1188
1314
static const char * const my_list []=
@@ -1306,6 +1432,8 @@ psql_completion(char *text, int start, int end)
1306
1432
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tisv ,NULL );
1307
1433
else if (strcmp (prev_wd ,"\\da" )== 0 )
1308
1434
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_aggregates ,NULL );
1435
+ else if (strcmp (prev_wd ,"\\db" )== 0 )
1436
+ COMPLETE_WITH_QUERY (Query_for_list_of_tablespaces );
1309
1437
else if (strcmp (prev_wd ,"\\dD" )== 0 )
1310
1438
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_domains ,NULL );
1311
1439
else if (strcmp (prev_wd ,"\\df" )== 0 || strcmp (prev_wd ,"\\df+" )== 0 )