@@ -3363,30 +3363,42 @@ match_previous_words(int pattern_id,
33633363 Matches ("COPY|\\copy" , MatchAny , "FROM" , "PROGRAM" , MatchAny ))
33643364 COMPLETE_WITH ("WITH (" , "WHERE" );
33653365
3366- /* Complete COPY <sth> FROM [PROGRAM] filename WITH ( */
3367- else if (Matches ("COPY|\\copy" , MatchAny , "FROM" , MatchAnyExcept ("PROGRAM" ), "WITH" , "(" ) ||
3368- Matches ("COPY|\\copy" , MatchAny , "FROM" , "PROGRAM" , MatchAny , "WITH" , "(" ))
3369- COMPLETE_WITH (Copy_from_options );
3370-
3371- /* Complete COPY <sth> TO [PROGRAM] filename WITH ( */
3372- else if (Matches ("COPY|\\copy" , MatchAny , "TO" , MatchAnyExcept ("PROGRAM" ), "WITH" , "(" ) ||
3373- Matches ("COPY|\\copy" , MatchAny , "TO" , "PROGRAM" , MatchAny , "WITH" , "(" ))
3374- COMPLETE_WITH (Copy_to_options );
3375-
3376- /* Complete COPY <sth> FROM|TO [PROGRAM] <sth> WITH (FORMAT */
3377- else if (Matches ("COPY|\\copy" , MatchAny , "FROM|TO" , MatchAnyExcept ("PROGRAM" ), "WITH" , "(" , "FORMAT" ) ||
3378- Matches ("COPY|\\copy" , MatchAny , "FROM|TO" , "PROGRAM" , MatchAny , "WITH" , "(" , "FORMAT" ))
3379- COMPLETE_WITH ("binary" , "csv" , "text" );
3380-
3381- /* Complete COPY <sth> FROM [PROGRAM] filename WITH (ON_ERROR */
3382- else if (Matches ("COPY|\\copy" , MatchAny , "FROM" , MatchAnyExcept ("PROGRAM" ), "WITH" , "(" , "ON_ERROR" ) ||
3383- Matches ("COPY|\\copy" , MatchAny , "FROM" , "PROGRAM" , MatchAny , "WITH" , "(" , "ON_ERROR" ))
3384- COMPLETE_WITH ("stop" , "ignore" );
3385-
3386- /* Complete COPY <sth> FROM [PROGRAM] filename WITH (LOG_VERBOSITY */
3387- else if (Matches ("COPY|\\copy" , MatchAny , "FROM" , MatchAnyExcept ("PROGRAM" ), "WITH" , "(" , "LOG_VERBOSITY" ) ||
3388- Matches ("COPY|\\copy" , MatchAny , "FROM" , "PROGRAM" , MatchAny , "WITH" , "(" , "LOG_VERBOSITY" ))
3389- COMPLETE_WITH ("silent" , "default" , "verbose" );
3366+ /* Complete COPY <sth> FROM|TO [PROGRAM] filename WITH ( */
3367+ else if (HeadMatches ("COPY|\\copy" , MatchAny , "FROM|TO" , MatchAnyExcept ("PROGRAM" ), "WITH" , "(" ) ||
3368+ HeadMatches ("COPY|\\copy" , MatchAny , "FROM|TO" , "PROGRAM" , MatchAny , "WITH" , "(" ))
3369+ {
3370+ if (!HeadMatches ("COPY|\\copy" , MatchAny , "FROM|TO" , MatchAnyExcept ("PROGRAM" ), "WITH" , "(*)" ) &&
3371+ !HeadMatches ("COPY|\\copy" , MatchAny , "FROM|TO" , "PROGRAM" , MatchAny , "WITH" , "(*)" ))
3372+ {
3373+ /*
3374+ * This fires if we're in an unfinished parenthesized option list.
3375+ * get_previous_words treats a completed parenthesized option list
3376+ * as one word, so the above tests are correct.
3377+ */
3378+
3379+ if (ends_with (prev_wd , '(' ) || ends_with (prev_wd , ',' ))
3380+ {
3381+ if (HeadMatches ("COPY|\\copy" , MatchAny , "FROM" ))
3382+ COMPLETE_WITH (Copy_from_options );
3383+ else
3384+ COMPLETE_WITH (Copy_to_options );
3385+ }
3386+
3387+ /* Complete COPY <sth> FROM|TO filename WITH (FORMAT */
3388+ else if (TailMatches ("FORMAT" ))
3389+ COMPLETE_WITH ("binary" , "csv" , "text" );
3390+
3391+ /* Complete COPY <sth> FROM filename WITH (ON_ERROR */
3392+ else if (TailMatches ("ON_ERROR" ))
3393+ COMPLETE_WITH ("stop" , "ignore" );
3394+
3395+ /* Complete COPY <sth> FROM filename WITH (LOG_VERBOSITY */
3396+ else if (TailMatches ("LOG_VERBOSITY" ))
3397+ COMPLETE_WITH ("silent" , "default" , "verbose" );
3398+ }
3399+
3400+ /* A completed parenthesized option list should be caught below */
3401+ }
33903402
33913403 /* Complete COPY <sth> FROM [PROGRAM] <sth> WITH (<options>) */
33923404 else if (Matches ("COPY|\\copy" , MatchAny , "FROM" , MatchAnyExcept ("PROGRAM" ), "WITH" , MatchAny ) ||
0 commit comments