@@ -463,6 +463,21 @@ static const SchemaQuery Query_for_list_of_tables = {
463463NULL
464464};
465465
466+ static const SchemaQuery Query_for_list_of_partitioned_tables = {
467+ /* catname */
468+ "pg_catalog.pg_class c" ,
469+ /* selcondition */
470+ "c.relkind IN ('P')" ,
471+ /* viscondition */
472+ "pg_catalog.pg_table_is_visible(c.oid)" ,
473+ /* namespace */
474+ "c.relnamespace" ,
475+ /* result */
476+ "pg_catalog.quote_ident(c.relname)" ,
477+ /* qualresult */
478+ NULL
479+ };
480+
466481static const SchemaQuery Query_for_list_of_constraints_with_schema = {
467482/* catname */
468483"pg_catalog.pg_constraint c" ,
@@ -913,6 +928,16 @@ static const SchemaQuery Query_for_list_of_matviews = {
913928" SELECT 'DEFAULT' ) ss "\
914929" WHERE pg_catalog.substring(name,1,%%d)='%%s'"
915930
931+ /* the silly-looking length condition is just to eat up the current word */
932+ #define Query_for_partition_of_table \
933+ "SELECT pg_catalog.quote_ident(c2.relname) "\
934+ " FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_inherits i"\
935+ " WHERE c1.oid=i.inhparent and i.inhrelid=c2.oid"\
936+ " and (%d = pg_catalog.length('%s'))"\
937+ " and pg_catalog.quote_ident(c1.relname)='%s'"\
938+ " and pg_catalog.pg_table_is_visible(c2.oid)"\
939+ " and c2.relispartition = 'true'"
940+
916941/*
917942 * This is a list of all "things" in Pgsql, which can show up after CREATE or
918943 * DROP; and there is also a query to get a list of them.
@@ -1742,7 +1767,8 @@ psql_completion(const char *text, int start, int end)
17421767static const char * const list_ALTER2 []=
17431768{"ADD" ,"ALTER" ,"CLUSTER ON" ,"DISABLE" ,"DROP" ,"ENABLE" ,"INHERIT" ,
17441769"NO INHERIT" ,"RENAME" ,"RESET" ,"OWNER TO" ,"SET" ,
1745- "VALIDATE CONSTRAINT" ,"REPLICA IDENTITY" ,NULL };
1770+ "VALIDATE CONSTRAINT" ,"REPLICA IDENTITY" ,"ATTACH PARTITION" ,
1771+ "DETACH PARTITION" ,NULL };
17461772
17471773COMPLETE_WITH_LIST (list_ALTER2 );
17481774}
@@ -1923,6 +1949,26 @@ psql_completion(const char *text, int start, int end)
19231949COMPLETE_WITH_LIST4 ("FULL" ,"NOTHING" ,"DEFAULT" ,"USING" );
19241950else if (Matches4 ("ALTER" ,"TABLE" ,MatchAny ,"REPLICA" ))
19251951COMPLETE_WITH_CONST ("IDENTITY" );
1952+ /*
1953+ * If we have ALTER TABLE <foo> ATTACH PARTITION, provide a list of
1954+ * tables.
1955+ */
1956+ else if (Matches5 ("ALTER" ,"TABLE" ,MatchAny ,"ATTACH" ,"PARTITION" ))
1957+ COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_tables ,"" );
1958+ /* Limited completion support for partition bound specification */
1959+ else if (TailMatches3 ("ATTACH" ,"PARTITION" ,MatchAny ))
1960+ COMPLETE_WITH_CONST ("FOR VALUES" );
1961+ else if (TailMatches2 ("FOR" ,"VALUES" ))
1962+ COMPLETE_WITH_LIST2 ("FROM (" ,"IN (" );
1963+ /*
1964+ * If we have ALTER TABLE <foo> DETACH PARTITION, provide a list of
1965+ * partitions of <foo>.
1966+ */
1967+ else if (Matches5 ("ALTER" ,"TABLE" ,MatchAny ,"DETACH" ,"PARTITION" ))
1968+ {
1969+ completion_info_charp = prev3_wd ;
1970+ COMPLETE_WITH_QUERY (Query_for_partition_of_table );
1971+ }
19261972
19271973/* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
19281974else if (Matches3 ("ALTER" ,"TABLESPACE" ,MatchAny ))
@@ -2300,6 +2346,15 @@ psql_completion(const char *text, int start, int end)
23002346/* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */
23012347else if (TailMatches2 ("CREATE" ,"UNLOGGED" ))
23022348COMPLETE_WITH_LIST2 ("TABLE" ,"MATERIALIZED VIEW" );
2349+ /* Complete PARTITION BY with RANGE ( or LIST ( or ... */
2350+ else if (TailMatches2 ("PARTITION" ,"BY" ))
2351+ COMPLETE_WITH_LIST2 ("RANGE (" ,"LIST (" );
2352+ /* If we have xxx PARTITION OF, provide a list of partitioned tables */
2353+ else if (TailMatches2 ("PARTITION" ,"OF" ))
2354+ COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_partitioned_tables ,"" );
2355+ /* Limited completion support for partition bound specification */
2356+ else if (TailMatches3 ("PARTITION" ,"OF" ,MatchAny ))
2357+ COMPLETE_WITH_CONST ("FOR VALUES" );
23032358
23042359/* CREATE TABLESPACE */
23052360else if (Matches3 ("CREATE" ,"TABLESPACE" ,MatchAny ))