*** a/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
***************
*** 1622,1633 **** psql_completion(char *text, int start, int end)
  		COMPLETE_WITH_CONST("IDENTITY");
  	}
  
! 	/* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
  	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
  			 pg_strcasecmp(prev2_wd, "TABLESPACE") == 0)
  	{
  		static const char *const list_ALTERTSPC[] =
! 		{"RENAME TO", "OWNER TO", "SET", "RESET", NULL};
  
  		COMPLETE_WITH_LIST(list_ALTERTSPC);
  	}
--- 1622,1633 ----
  		COMPLETE_WITH_CONST("IDENTITY");
  	}
  
! 	/* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET, MOVE */
  	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
  			 pg_strcasecmp(prev2_wd, "TABLESPACE") == 0)
  	{
  		static const char *const list_ALTERTSPC[] =
! 		{"RENAME TO", "OWNER TO", "SET", "RESET", "MOVE", NULL};
  
  		COMPLETE_WITH_LIST(list_ALTERTSPC);
  	}
***************
*** 1649,1654 **** psql_completion(char *text, int start, int end)
--- 1649,1675 ----
  
  		COMPLETE_WITH_LIST(list_TABLESPACEOPTIONS);
  	}
+ 	/* ALTER TABLESPACE <foo> MOVE ALL|TABLES|INDEXES|MATERIALIZED VIEWS */
+ 	else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
+ 			 pg_strcasecmp(prev3_wd, "TABLESPACE") == 0 &&
+ 			 pg_strcasecmp(prev_wd, "MOVE") == 0)
+ 	{
+ 		static const char *const list_TABLESPACEMOVETARGETS[] =
+ 		{"ALL", "TABLES", "INDEXES", "MATERIALIZED VIEWS", NULL};
+ 
+ 		COMPLETE_WITH_LIST(list_TABLESPACEMOVETARGETS);
+ 	}
+ 	else if ((pg_strcasecmp(prev4_wd, "TABLESPACE") == 0 &&
+ 			  pg_strcasecmp(prev2_wd, "MOVE") == 0) ||
+ 			 (pg_strcasecmp(prev5_wd, "TABLESPACE") == 0 &&
+ 			  pg_strcasecmp(prev3_wd, "MOVE") == 0 &&
+ 			  pg_strcasecmp(prev2_wd, "MATERIALIZED") == 0))
+ 	{
+ 		static const char *const list_TABLESPACEMOVEOPTIONS[] =
+ 		{"OWNED BY", "TO", NULL};
+ 
+ 		COMPLETE_WITH_LIST(list_TABLESPACEMOVEOPTIONS);
+ 	}
  
  	/* ALTER TEXT SEARCH */
  	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
***************
*** 2559,2566 **** psql_completion(char *text, int start, int end)
  	 * but we may as well tab-complete both: perhaps some users prefer one
  	 * variant or the other.
  	 */
! 	else if (pg_strcasecmp(prev3_wd, "FETCH") == 0 ||
! 			 pg_strcasecmp(prev3_wd, "MOVE") == 0)
  	{
  		static const char *const list_FROMIN[] =
  		{"FROM", "IN", NULL};
--- 2580,2588 ----
  	 * but we may as well tab-complete both: perhaps some users prefer one
  	 * variant or the other.
  	 */
! 	else if ((pg_strcasecmp(prev3_wd, "FETCH") == 0 ||
! 			  pg_strcasecmp(prev3_wd, "MOVE") == 0) &&
! 			 pg_strcasecmp(prev_wd, "TO") != 0)
  	{
  		static const char *const list_FROMIN[] =
  		{"FROM", "IN", NULL};
