@@ -976,6 +976,11 @@ static const SchemaQuery Query_for_list_of_statistics = {
976976" and pg_catalog.pg_table_is_visible(c2.oid)"\
977977" and c2.relispartition = 'true'"
978978
979+ #define Query_for_list_of_cursors \
980+ " SELECT pg_catalog.quote_ident(name) "\
981+ " FROM pg_catalog.pg_cursors "\
982+ " WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s'"
983+
979984/*
980985 * These object types were introduced later than our support cutoff of
981986 * server version 7.4. We use the VersionedQuery infrastructure so that
@@ -2284,6 +2289,10 @@ psql_completion(const char *text, int start, int end)
22842289 COMPLETE_WITH_VERSIONED_SCHEMA_QUERY (Query_for_list_of_procedures , NULL );
22852290 else if (Matches ("CALL" , MatchAny ))
22862291 COMPLETE_WITH ("(" );
2292+ /* CLOSE */
2293+ else if (Matches ("CLOSE" ))
2294+ COMPLETE_WITH_QUERY (Query_for_list_of_cursors
2295+ " UNION SELECT 'ALL'" );
22872296/* CLUSTER */
22882297 else if (Matches ("CLUSTER" ))
22892298 COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_clusterables , "UNION SELECT 'VERBOSE'" );
@@ -3002,11 +3011,44 @@ psql_completion(const char *text, int start, int end)
30023011 " UNION SELECT 'ALL'" );
30033012
30043013/* DECLARE */
3014+
3015+ /*
3016+ * Complete DECLARE <name> with one of BINARY, INSENSITIVE, SCROLL, NO
3017+ * SCROLL, and CURSOR.
3018+ */
30053019 else if (Matches ("DECLARE" , MatchAny ))
30063020 COMPLETE_WITH ("BINARY" , "INSENSITIVE" , "SCROLL" , "NO SCROLL" ,
30073021 "CURSOR" );
3022+
3023+ /*
3024+ * Complete DECLARE ... <option> with other options. The PostgreSQL parser
3025+ * allows DECLARE options to be specified in any order. But the
3026+ * tab-completion follows the ordering of them that the SQL standard
3027+ * provides, like the syntax of DECLARE command in the documentation
3028+ * indicates.
3029+ */
3030+ else if (HeadMatches ("DECLARE" ) && TailMatches ("BINARY" ))
3031+ COMPLETE_WITH ("INSENSITIVE" , "SCROLL" , "NO SCROLL" , "CURSOR" );
3032+ else if (HeadMatches ("DECLARE" ) && TailMatches ("INSENSITIVE" ))
3033+ COMPLETE_WITH ("SCROLL" , "NO SCROLL" , "CURSOR" );
3034+ else if (HeadMatches ("DECLARE" ) && TailMatches ("SCROLL" ))
3035+ COMPLETE_WITH ("CURSOR" );
3036+ /* Complete DECLARE ... [options] NO with SCROLL */
3037+ else if (HeadMatches ("DECLARE" ) && TailMatches ("NO" ))
3038+ COMPLETE_WITH ("SCROLL" );
3039+
3040+ /*
3041+ * Complete DECLARE ... CURSOR with one of WITH HOLD, WITHOUT HOLD, and
3042+ * FOR
3043+ */
30083044 else if (HeadMatches ("DECLARE" ) && TailMatches ("CURSOR" ))
30093045 COMPLETE_WITH ("WITH HOLD" , "WITHOUT HOLD" , "FOR" );
3046+ /* Complete DECLARE ... CURSOR WITH|WITHOUT with HOLD */
3047+ else if (HeadMatches ("DECLARE" ) && TailMatches ("CURSOR" , "WITH|WITHOUT" ))
3048+ COMPLETE_WITH ("HOLD" );
3049+ /* Complete DECLARE ... CURSOR WITH|WITHOUT HOLD with FOR */
3050+ else if (HeadMatches ("DECLARE" ) && TailMatches ("CURSOR" , "WITH|WITHOUT" , "HOLD" ))
3051+ COMPLETE_WITH ("FOR" );
30103052
30113053/* DELETE --- can be inside EXPLAIN, RULE, etc */
30123054 /* ... despite which, only complete DELETE with FROM at start of line */
@@ -3167,15 +3209,31 @@ psql_completion(const char *text, int start, int end)
31673209
31683210 /*
31693211 * Complete FETCH with one of ABSOLUTE, BACKWARD, FORWARD, RELATIVE, ALL,
3170- * NEXT, PRIOR, FIRST, LAST
3212+ * NEXT, PRIOR, FIRST, LAST, FROM, IN, and a list of cursors
31713213 */
31723214 else if (Matches ("FETCH|MOVE" ))
3173- COMPLETE_WITH ("ABSOLUTE" , "BACKWARD" , "FORWARD" , "RELATIVE" ,
3174- "ALL" , "NEXT" , "PRIOR" , "FIRST" , "LAST" );
3215+ COMPLETE_WITH_QUERY (Query_for_list_of_cursors
3216+ " UNION SELECT 'ABSOLUTE'"
3217+ " UNION SELECT 'BACKWARD'"
3218+ " UNION SELECT 'FORWARD'"
3219+ " UNION SELECT 'RELATIVE'"
3220+ " UNION SELECT 'ALL'"
3221+ " UNION SELECT 'NEXT'"
3222+ " UNION SELECT 'PRIOR'"
3223+ " UNION SELECT 'FIRST'"
3224+ " UNION SELECT 'LAST'"
3225+ " UNION SELECT 'FROM'"
3226+ " UNION SELECT 'IN'" );
31753227
3176- /* Complete FETCH BACKWARD or FORWARD with one of ALL, FROM, IN */
3228+ /*
3229+ * Complete FETCH BACKWARD or FORWARD with one of ALL, FROM, IN, and a
3230+ * list of cursors
3231+ */
31773232 else if (Matches ("FETCH|MOVE" , "BACKWARD|FORWARD" ))
3178- COMPLETE_WITH ("ALL" , "FROM" , "IN" );
3233+ COMPLETE_WITH_QUERY (Query_for_list_of_cursors
3234+ " UNION SELECT 'ALL'"
3235+ " UNION SELECT 'FROM'"
3236+ " UNION SELECT 'IN'" );
31793237
31803238 /*
31813239 * Complete FETCH <direction> with "FROM" or "IN". These are equivalent,
@@ -3185,7 +3243,13 @@ psql_completion(const char *text, int start, int end)
31853243 else if (Matches ("FETCH|MOVE" , "ABSOLUTE|BACKWARD|FORWARD|RELATIVE" ,
31863244 MatchAnyExcept ("FROM|IN" )) ||
31873245 Matches ("FETCH|MOVE" , "ALL|NEXT|PRIOR|FIRST|LAST" ))
3188- COMPLETE_WITH ("FROM" , "IN" );
3246+ COMPLETE_WITH_QUERY (Query_for_list_of_cursors
3247+ " UNION SELECT 'FROM'"
3248+ " UNION SELECT 'IN'" );
3249+ /* Complete FETCH <direction> "FROM" or "IN" with a list of cursors */
3250+ else if (HeadMatches ("FETCH|MOVE" ) &&
3251+ TailMatches ("FROM|IN" ))
3252+ COMPLETE_WITH_QUERY (Query_for_list_of_cursors );
31893253
31903254/* FOREIGN DATA WRAPPER */
31913255 /* applies in ALTER/DROP FDW and in CREATE SERVER */
0 commit comments