@@ -659,6 +659,28 @@ static const SchemaQuery Query_for_list_of_updatables = {
659659NULL
660660};
661661
662+ /* Relations supporting MERGE */
663+ static const SchemaQuery Query_for_list_of_mergetargets = {
664+ /* min_server_version */
665+ 110000 ,
666+ /* catname */
667+ "pg_catalog.pg_class c" ,
668+ /* selcondition */
669+ "c.relkind IN (" CppAsString2 (RELKIND_RELATION )", "
670+ CppAsString2 (RELKIND_PARTITIONED_TABLE )") AND "
671+ "c.relhasrules = false AND "
672+ "(c.relhassubclass = false OR "
673+ " c.relkind = " CppAsString2 (RELKIND_PARTITIONED_TABLE )")" ,
674+ /* viscondition */
675+ "pg_catalog.pg_table_is_visible(c.oid)" ,
676+ /* namespace */
677+ "c.relnamespace" ,
678+ /* result */
679+ "pg_catalog.quote_ident(c.relname)" ,
680+ /* qualresult */
681+ NULL
682+ };
683+
662684static const SchemaQuery Query_for_list_of_relations = {
663685/* min_server_version */
6646860 ,
@@ -1605,7 +1627,7 @@ psql_completion(const char *text, int start, int end)
16051627"COMMENT" ,"COMMIT" ,"COPY" ,"CREATE" ,"DEALLOCATE" ,"DECLARE" ,
16061628"DELETE FROM" ,"DISCARD" ,"DO" ,"DROP" ,"END" ,"EXECUTE" ,"EXPLAIN" ,
16071629"FETCH" ,"GRANT" ,"IMPORT" ,"INSERT" ,"LISTEN" ,"LOAD" ,"LOCK" ,
1608- "MOVE" ,"NOTIFY" ,"PREPARE" ,
1630+ "MERGE" , " MOVE" ,"NOTIFY" ,"PREPARE" ,
16091631"REASSIGN" ,"REFRESH MATERIALIZED VIEW" ,"REINDEX" ,"RELEASE" ,
16101632"RESET" ,"REVOKE" ,"ROLLBACK" ,
16111633"SAVEPOINT" ,"SECURITY LABEL" ,"SELECT" ,"SET" ,"SHOW" ,"START" ,
@@ -2999,14 +3021,15 @@ psql_completion(const char *text, int start, int end)
29993021 * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands
30003022 */
30013023else if (Matches1 ("EXPLAIN" ))
3002- COMPLETE_WITH_LIST7 ("SELECT" ,"INSERT" ,"DELETE" ,"UPDATE" ,"DECLARE " ,
3003- "ANALYZE" ,"VERBOSE" );
3024+ COMPLETE_WITH_LIST8 ("SELECT" ,"INSERT" ,"DELETE" ,"UPDATE" ,"MERGE " ,
3025+ "DECLARE" , " ANALYZE" ,"VERBOSE" );
30043026else if (Matches2 ("EXPLAIN" ,"ANALYZE" ))
3005- COMPLETE_WITH_LIST6 ("SELECT" ,"INSERT" ,"DELETE" ,"UPDATE" ,"DECLARE " ,
3006- "VERBOSE" );
3027+ COMPLETE_WITH_LIST7 ("SELECT" ,"INSERT" ,"DELETE" ,"UPDATE" ,"MERGE " ,
3028+ "DECLARE" , " VERBOSE" );
30073029else if (Matches2 ("EXPLAIN" ,"VERBOSE" )||
30083030Matches3 ("EXPLAIN" ,"ANALYZE" ,"VERBOSE" ))
3009- COMPLETE_WITH_LIST5 ("SELECT" ,"INSERT" ,"DELETE" ,"UPDATE" ,"DECLARE" );
3031+ COMPLETE_WITH_LIST6 ("SELECT" ,"INSERT" ,"DELETE" ,"UPDATE" ,"MERGE" ,
3032+ "DECLARE" );
30103033
30113034/* FETCH && MOVE */
30123035/* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
@@ -3229,6 +3252,9 @@ psql_completion(const char *text, int start, int end)
32293252COMPLETE_WITH_CONST ("SCHEMA" );
32303253
32313254/* INSERT --- can be inside EXPLAIN, RULE, etc */
3255+ /* Complete NOT MATCHED THEN INSERT */
3256+ else if (TailMatches4 ("NOT" ,"MATCHED" ,"THEN" ,"INSERT" ))
3257+ COMPLETE_WITH_LIST2 ("VALUES" ,"(" );
32323258/* Complete INSERT with "INTO" */
32333259else if (TailMatches1 ("INSERT" ))
32343260COMPLETE_WITH_CONST ("INTO" );
@@ -3300,6 +3326,55 @@ psql_completion(const char *text, int start, int end)
33003326Matches5 ("LOCK" ,"TABLE" ,MatchAny ,"IN" ,"SHARE" ))
33013327COMPLETE_WITH_LIST3 ("MODE" ,"ROW EXCLUSIVE MODE" ,
33023328"UPDATE EXCLUSIVE MODE" );
3329+ /* MERGE --- can be inside EXPLAIN */
3330+ else if (TailMatches1 ("MERGE" ))
3331+ COMPLETE_WITH_CONST ("INTO" );
3332+ else if (TailMatches2 ("MERGE" ,"INTO" ))
3333+ COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_mergetargets ,NULL );
3334+ else if (TailMatches3 ("MERGE" ,"INTO" ,MatchAny ))
3335+ COMPLETE_WITH_LIST2 ("USING" ,"AS" );
3336+ else if (TailMatches4 ("MERGE" ,"INTO" ,MatchAny ,"USING" ))
3337+ COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tables ,NULL );
3338+ /* with [AS] alias */
3339+ else if (TailMatches5 ("MERGE" ,"INTO" ,MatchAny ,"AS" ,MatchAny ))
3340+ COMPLETE_WITH_CONST ("USING" );
3341+ else if (TailMatches4 ("MERGE" ,"INTO" ,MatchAny ,MatchAny ))
3342+ COMPLETE_WITH_CONST ("USING" );
3343+ else if (TailMatches6 ("MERGE" ,"INTO" ,MatchAny ,"AS" ,MatchAny ,"USING" ))
3344+ COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tables ,NULL );
3345+ else if (TailMatches5 ("MERGE" ,"INTO" ,MatchAny ,MatchAny ,"USING" ))
3346+ COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tables ,NULL );
3347+ /* ON */
3348+ else if (TailMatches5 ("MERGE" ,"INTO" ,MatchAny ,"USING" ,MatchAny ))
3349+ COMPLETE_WITH_CONST ("ON" );
3350+ else if (TailMatches8 ("INTO" ,MatchAny ,"AS" ,MatchAny ,"USING" ,MatchAny ,"AS" ,MatchAny ))
3351+ COMPLETE_WITH_CONST ("ON" );
3352+ else if (TailMatches6 ("INTO" ,MatchAny ,MatchAny ,"USING" ,MatchAny ,MatchAny ))
3353+ COMPLETE_WITH_CONST ("ON" );
3354+ /* ON condition */
3355+ else if (TailMatches5 ("INTO" ,MatchAny ,"USING" ,MatchAny ,"ON" ))
3356+ COMPLETE_WITH_ATTR (prev4_wd ,"" );
3357+ else if (TailMatches9 ("INTO" ,MatchAny ,"AS" ,MatchAny ,"USING" ,MatchAny ,"AS" ,MatchAny ,"ON" ))
3358+ COMPLETE_WITH_ATTR (prev8_wd ,"" );
3359+ else if (TailMatches7 ("INTO" ,MatchAny ,MatchAny ,"USING" ,MatchAny ,MatchAny ,"ON" ))
3360+ COMPLETE_WITH_ATTR (prev6_wd ,"" );
3361+ /* WHEN [NOT] MATCHED */
3362+ else if (TailMatches4 ("USING" ,MatchAny ,"ON" ,MatchAny ))
3363+ COMPLETE_WITH_LIST2 ("WHEN MATCHED" ,"WHEN NOT MATCHED" );
3364+ else if (TailMatches6 ("USING" ,MatchAny ,"AS" ,MatchAny ,"ON" ,MatchAny ))
3365+ COMPLETE_WITH_LIST2 ("WHEN MATCHED" ,"WHEN NOT MATCHED" );
3366+ else if (TailMatches5 ("USING" ,MatchAny ,MatchAny ,"ON" ,MatchAny ))
3367+ COMPLETE_WITH_LIST2 ("WHEN MATCHED" ,"WHEN NOT MATCHED" );
3368+ else if (TailMatches2 ("WHEN" ,"MATCHED" ))
3369+ COMPLETE_WITH_LIST2 ("THEN" ,"AND" );
3370+ else if (TailMatches3 ("WHEN" ,"NOT" ,"MATCHED" ))
3371+ COMPLETE_WITH_LIST2 ("THEN" ,"AND" );
3372+ else if (TailMatches3 ("WHEN" ,"MATCHED" ,"THEN" ))
3373+ COMPLETE_WITH_LIST2 ("UPDATE" ,"DELETE" );
3374+ else if (TailMatches4 ("WHEN" ,"NOT" ,"MATCHED" ,"THEN" ))
3375+ COMPLETE_WITH_LIST2 ("INSERT" ,"DO" );
3376+ else if (TailMatches5 ("WHEN" ,"NOT" ,"MATCHED" ,"THEN" ,"DO" ))
3377+ COMPLETE_WITH_CONST ("NOTHING" );
33033378
33043379/* NOTIFY --- can be inside EXPLAIN, RULE, etc */
33053380else if (TailMatches1 ("NOTIFY" ))