@@ -229,6 +229,7 @@ static bool advisory_lock(PGconn *conn, const char *relid);
229229static bool lock_exclusive (PGconn * conn , const char * relid , const char * lock_query , bool start_xact );
230230static bool kill_ddl (PGconn * conn , Oid relid , bool terminate );
231231static bool lock_access_share (PGconn * conn , Oid relid , const char * target_name );
232+ static void append_order_by_command (StringInfoData * command , const char * orderby , const char * ckey );
232233
233234#define SQLSTATE_INVALID_SCHEMA_NAME "3F000"
234235#define SQLSTATE_UNDEFINED_FUNCTION "42883"
@@ -787,7 +788,7 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize)
787788 /* acquire target tables */
788789 appendStringInfoString (& sql ,
789790 "SELECT t.*,"
790- " coalesce(v.tablespace, t.tablespace_orig) as tablespace_dest"
791+ " quote_ident( coalesce(v.tablespace, t.tablespace_orig) ) as tablespace_dest"
791792 " FROM repack.tables t, "
792793 " (VALUES ($1::text)) as v (tablespace)"
793794 " WHERE " );
@@ -899,6 +900,7 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize)
899900 for (i = 0 ; i < num ; i ++ )
900901 {
901902 repack_table table ;
903+ StringInfoData create_sql ;
902904 StringInfoData copy_sql ;
903905 const char * ckey ;
904906 int c = 0 ;
@@ -938,32 +940,37 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize)
938940 table .sql_pop = getstr (res , i , c ++ );
939941 table .dest_tablespace = getstr (res , i , c ++ );
940942
941- /* Craft Copy SQL */
943+ /* Craft Create_Table and Copy SQLs */
944+ initStringInfo (& create_sql );
945+ printfStringInfo (& create_sql , table .create_table , table .dest_tablespace );
946+
947+ /*
948+ * We need to split the copying of data into the new table into
949+ * separate commands if we need any per-column storage settings.
950+ * Otherwise use just "create table as"
951+ */
942952 initStringInfo (& copy_sql );
943- appendStringInfoString (& copy_sql , table .copy_data );
944- if (!orderby )
945953
954+ /* if columns are altered */
955+ if (table .alter_col_storage )
946956 {
947- if (ckey != NULL )
948- {
949- /* CLUSTER mode */
950- appendStringInfoString (& copy_sql , " ORDER BY " );
951- appendStringInfoString (& copy_sql , ckey );
952- }
957+ /* no data in CREATE TABLE */
958+ appendStringInfoString (& create_sql , " WITH NO DATA" );
953959
954- /* else, VACUUM FULL mode (non-clustered tables) */
955- }
956- else if (! orderby [ 0 ])
957- {
958- /* VACUUM FULL mode (for clustered tables too), do nothing */
959- }
960- else
961- {
962- /* User specified ORDER BY */
963- appendStringInfoString ( & copy_sql , " ORDER BY " );
964- appendStringInfoString ( & copy_sql , orderby ) ;
960+ /* add ORDER BY in copy data */
961+ appendStringInfoString ( & copy_sql , table . copy_data );
962+ append_order_by_command ( & copy_sql , orderby , ckey );
963+ table . copy_data = copy_sql . data ;
964+
965+ } else {
966+
967+ /* copy all data in CREATE TABLE AS with ORDER BY
968+ * allowing parallel SELECT executions */
969+ append_order_by_command ( & create_sql , orderby , ckey );
970+ table . copy_data = NULL ;
965971 }
966- table .copy_data = copy_sql .data ;
972+
973+ table .create_table = create_sql .data ;
967974
968975 repack_one_table (& table , orderby );
969976 }
@@ -977,6 +984,33 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize)
977984 return ret ;
978985}
979986
987+ static void
988+ append_order_by_command (StringInfoData * command , const char * orderby , const char * ckey )
989+ {
990+ if (!orderby )
991+
992+ {
993+ if (ckey != NULL )
994+ {
995+ /* CLUSTER mode */
996+ appendStringInfoString (command , " ORDER BY " );
997+ appendStringInfoString (command , ckey );
998+ }
999+
1000+ /* else, VACUUM FULL mode (non-clustered tables) */
1001+ }
1002+ else if (!orderby [0 ])
1003+ {
1004+ /* VACUUM FULL mode (for clustered tables too), do nothing */
1005+ }
1006+ else
1007+ {
1008+ /* User specified ORDER BY */
1009+ appendStringInfoString (command , " ORDER BY " );
1010+ appendStringInfoString (command , orderby );
1011+ }
1012+ }
1013+
9801014static int
9811015apply_log (PGconn * conn , const repack_table * table , int count )
9821016{
@@ -1524,12 +1558,11 @@ repack_one_table(repack_table *table, const char *orderby)
15241558 * Before copying data to the target table, we need to set the column storage
15251559 * type if its storage type has been changed from the type default.
15261560 */
1527- params [0 ] = utoa (table -> target_oid , buffer );
1528- params [1 ] = table -> dest_tablespace ;
1529- command (table -> create_table , 2 , params );
1561+ command (table -> create_table , 0 , NULL );
15301562 if (table -> alter_col_storage )
15311563 command (table -> alter_col_storage , 0 , NULL );
1532- command (table -> copy_data , 0 , NULL );
1564+ if (table -> copy_data )
1565+ command (table -> copy_data , 0 , NULL );
15331566 temp_obj_num ++ ;
15341567 printfStringInfo (& sql , "SELECT repack.disable_autovacuum('repack.table_%u')" , table -> target_oid );
15351568 if (table -> drop_columns )
0 commit comments