@@ -67,10 +67,20 @@ static intprocess_global_sql_commands(PGconn *conn, const char *dumpdirpath,
6767const char * outfile );
6868static void copy_or_print_global_file (const char * outfile ,FILE * pfile );
6969static int get_dbnames_list_to_restore (PGconn * conn ,
70- SimpleOidStringList * dbname_oid_list ,
70+ SimplePtrList * dbname_oid_list ,
7171SimpleStringList db_exclude_patterns );
7272static int get_dbname_oid_list_from_mfile (const char * dumpdirpath ,
73- SimpleOidStringList * dbname_oid_list );
73+ SimplePtrList * dbname_oid_list );
74+
75+ /*
76+ * Stores a database OID and the corresponding name.
77+ */
78+ typedef struct DbOidName
79+ {
80+ Oid oid ;
81+ char str [FLEXIBLE_ARRAY_MEMBER ];/* null-terminated string here */
82+ }DbOidName ;
83+
7484
7585int
7686main (int argc ,char * * argv )
@@ -927,7 +937,7 @@ read_one_statement(StringInfo inBuf, FILE *pfile)
927937 */
928938static int
929939get_dbnames_list_to_restore (PGconn * conn ,
930- SimpleOidStringList * dbname_oid_list ,
940+ SimplePtrList * dbname_oid_list ,
931941SimpleStringList db_exclude_patterns )
932942{
933943int count_db = 0 ;
@@ -943,21 +953,22 @@ get_dbnames_list_to_restore(PGconn *conn,
943953 * Process one by one all dbnames and if specified to skip restoring, then
944954 * remove dbname from list.
945955 */
946- for (SimpleOidStringListCell * db_cell = dbname_oid_list -> head ;
956+ for (SimplePtrListCell * db_cell = dbname_oid_list -> head ;
947957db_cell ;db_cell = db_cell -> next )
948958{
959+ DbOidName * dbidname = (DbOidName * )db_cell -> ptr ;
949960bool skip_db_restore = false;
950961PQExpBuffer db_lit = createPQExpBuffer ();
951962
952- appendStringLiteralConn (db_lit ,db_cell -> str ,conn );
963+ appendStringLiteralConn (db_lit ,dbidname -> str ,conn );
953964
954965for (SimpleStringListCell * pat_cell = db_exclude_patterns .head ;pat_cell ;pat_cell = pat_cell -> next )
955966{
956967/*
957968 * If there is an exact match then we don't need to try a pattern
958969 * match
959970 */
960- if (pg_strcasecmp (db_cell -> str ,pat_cell -> val )== 0 )
971+ if (pg_strcasecmp (dbidname -> str ,pat_cell -> val )== 0 )
961972skip_db_restore = true;
962973/* Otherwise, try a pattern match if there is a connection */
963974else if (conn )
@@ -972,7 +983,7 @@ get_dbnames_list_to_restore(PGconn *conn,
972983if (dotcnt > 0 )
973984{
974985pg_log_error ("improper qualified name (too many dotted names): %s" ,
975- db_cell -> str );
986+ dbidname -> str );
976987PQfinish (conn );
977988exit_nicely (1 );
978989}
@@ -982,7 +993,7 @@ get_dbnames_list_to_restore(PGconn *conn,
982993if ((PQresultStatus (res )== PGRES_TUPLES_OK )&& PQntuples (res ))
983994{
984995skip_db_restore = true;
985- pg_log_info ("database \"%s\" matches exclude pattern: \"%s\"" ,db_cell -> str ,pat_cell -> val );
996+ pg_log_info ("database \"%s\" matches exclude pattern: \"%s\"" ,dbidname -> str ,pat_cell -> val );
986997}
987998
988999PQclear (res );
@@ -1001,8 +1012,8 @@ get_dbnames_list_to_restore(PGconn *conn,
10011012 */
10021013if (skip_db_restore )
10031014{
1004- pg_log_info ("excluding database \"%s\"" ,db_cell -> str );
1005- db_cell -> oid = InvalidOid ;
1015+ pg_log_info ("excluding database \"%s\"" ,dbidname -> str );
1016+ dbidname -> oid = InvalidOid ;
10061017}
10071018else
10081019{
@@ -1024,13 +1035,14 @@ get_dbnames_list_to_restore(PGconn *conn,
10241035 * Returns, total number of database names in map.dat file.
10251036 */
10261037static int
1027- get_dbname_oid_list_from_mfile (const char * dumpdirpath ,SimpleOidStringList * dbname_oid_list )
1038+ get_dbname_oid_list_from_mfile (const char * dumpdirpath ,SimplePtrList * dbname_oid_list )
10281039{
1040+ StringInfoData linebuf ;
10291041FILE * pfile ;
10301042char map_file_path [MAXPGPATH ];
1031- char line [MAXPGPATH ];
10321043int count = 0 ;
10331044
1045+
10341046/*
10351047 * If there is only global.dat file in dump, then return from here as
10361048 * there is no database to restore.
@@ -1049,32 +1061,43 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimpleOidStringList *dbn
10491061if (pfile == NULL )
10501062pg_fatal ("could not open \"%s\": %m" ,map_file_path );
10511063
1064+ initStringInfo (& linebuf );
1065+
10521066/* Append all the dbname/db_oid combinations to the list. */
1053- while (( fgets ( line , MAXPGPATH , pfile )) != NULL )
1067+ while (pg_get_line_buf ( pfile , & linebuf ) )
10541068{
10551069Oid db_oid = InvalidOid ;
1056- char db_oid_str [MAXPGPATH + 1 ]= "" ;
10571070char * dbname ;
1071+ DbOidName * dbidname ;
1072+ int namelen ;
1073+ char * p = linebuf .data ;
10581074
10591075/* Extract dboid. */
1060- sscanf (line ,"%u" ,& db_oid );
1061- sscanf (line ,"%20s" ,db_oid_str );
1076+ while (isdigit (* p ))
1077+ p ++ ;
1078+ if (p > linebuf .data && * p == ' ' )
1079+ {
1080+ sscanf (linebuf .data ,"%u" ,& db_oid );
1081+ p ++ ;
1082+ }
10621083
10631084/* dbname is the rest of the line */
1064- dbname = line + strlen (db_oid_str )+ 1 ;
1085+ dbname = p ;
1086+ namelen = strlen (dbname );
10651087
1066- /* Remove \n from dbname. */
1067- dbname [strlen (dbname )- 1 ]= '\0' ;
1088+ /* Report error and exit if the file has any corrupted data. */
1089+ if (!OidIsValid (db_oid )|| namelen <=1 )
1090+ pg_fatal ("invalid entry in \"%s\" at line: %d" ,map_file_path ,
1091+ count + 1 );
10681092
10691093pg_log_info ("found database \"%s\" (OID: %u) in \"%s\"" ,
10701094dbname ,db_oid ,map_file_path );
10711095
1072- /* Report error and exit if the file has any corrupted data. */
1073- if (!OidIsValid (db_oid )|| strlen (dbname )== 0 )
1074- pg_fatal ("invalid entry in \"%s\" at line : %d" ,map_file_path ,
1075- count + 1 );
1096+ dbidname = pg_malloc (offsetof(DbOidName ,str )+ namelen + 1 );
1097+ dbidname -> oid = db_oid ;
1098+ strlcpy (dbidname -> str ,dbname ,namelen );
10761099
1077- simple_oid_string_list_append (dbname_oid_list ,db_oid , dbname );
1100+ simple_ptr_list_append (dbname_oid_list ,dbidname );
10781101count ++ ;
10791102}
10801103
@@ -1100,7 +1123,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
11001123SimpleStringList db_exclude_patterns ,RestoreOptions * opts ,
11011124int numWorkers )
11021125{
1103- SimpleOidStringList dbname_oid_list = {NULL ,NULL };
1126+ SimplePtrList dbname_oid_list = {NULL ,NULL };
11041127int num_db_restore = 0 ;
11051128int num_total_db ;
11061129int n_errors_total ;
@@ -1116,7 +1139,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
11161139
11171140num_total_db = get_dbname_oid_list_from_mfile (dumpdirpath ,& dbname_oid_list );
11181141
1119- /* If map.dat has noentry , return after processing global.dat */
1142+ /* If map.dat has noentries , return after processing global.dat */
11201143if (dbname_oid_list .head == NULL )
11211144return process_global_sql_commands (conn ,dumpdirpath ,opts -> filename );
11221145
@@ -1164,20 +1187,20 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
11641187pg_log_info ("need to restore %d databases out of %d databases" ,num_db_restore ,num_total_db );
11651188
11661189/*
1167- * Till now, we made a list of databases, those needs to be restored after
1168- * skipping names of exclude-database. Now we can launch parallel workers
1169- * to restore these databases.
1190+ * We have a list of databases to restore after processing the
1191+ * exclude-database switch(es). Now we can restore them one by one.
11701192 */
1171- for (SimpleOidStringListCell * db_cell = dbname_oid_list .head ;
1193+ for (SimplePtrListCell * db_cell = dbname_oid_list .head ;
11721194db_cell ;db_cell = db_cell -> next )
11731195{
1196+ DbOidName * dbidname = (DbOidName * )db_cell -> ptr ;
11741197char subdirpath [MAXPGPATH ];
11751198char subdirdbpath [MAXPGPATH ];
11761199char dbfilename [MAXPGPATH ];
11771200int n_errors ;
11781201
11791202/* ignore dbs marked for skipping */
1180- if (db_cell -> oid == InvalidOid )
1203+ if (dbidname -> oid == InvalidOid )
11811204continue ;
11821205
11831206/*
@@ -1197,27 +1220,27 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
11971220 * {oid}.dmp file, use it. Otherwise try to use a directory called
11981221 * {oid}
11991222 */
1200- snprintf (dbfilename ,MAXPGPATH ,"%u.tar" ,db_cell -> oid );
1223+ snprintf (dbfilename ,MAXPGPATH ,"%u.tar" ,dbidname -> oid );
12011224if (file_exists_in_directory (subdirdbpath ,dbfilename ))
1202- snprintf (subdirpath ,MAXPGPATH ,"%s/databases/%u.tar" ,dumpdirpath ,db_cell -> oid );
1225+ snprintf (subdirpath ,MAXPGPATH ,"%s/databases/%u.tar" ,dumpdirpath ,dbidname -> oid );
12031226else
12041227{
1205- snprintf (dbfilename ,MAXPGPATH ,"%u.dmp" ,db_cell -> oid );
1228+ snprintf (dbfilename ,MAXPGPATH ,"%u.dmp" ,dbidname -> oid );
12061229
12071230if (file_exists_in_directory (subdirdbpath ,dbfilename ))
1208- snprintf (subdirpath ,MAXPGPATH ,"%s/databases/%u.dmp" ,dumpdirpath ,db_cell -> oid );
1231+ snprintf (subdirpath ,MAXPGPATH ,"%s/databases/%u.dmp" ,dumpdirpath ,dbidname -> oid );
12091232else
1210- snprintf (subdirpath ,MAXPGPATH ,"%s/databases/%u" ,dumpdirpath ,db_cell -> oid );
1233+ snprintf (subdirpath ,MAXPGPATH ,"%s/databases/%u" ,dumpdirpath ,dbidname -> oid );
12111234}
12121235
1213- pg_log_info ("restoring database \"%s\"" ,db_cell -> str );
1236+ pg_log_info ("restoring database \"%s\"" ,dbidname -> str );
12141237
12151238/* If database is already created, then don't set createDB flag. */
12161239if (opts -> cparams .dbname )
12171240{
12181241PGconn * test_conn ;
12191242
1220- test_conn = ConnectDatabase (db_cell -> str ,NULL ,opts -> cparams .pghost ,
1243+ test_conn = ConnectDatabase (dbidname -> str ,NULL ,opts -> cparams .pghost ,
12211244opts -> cparams .pgport ,opts -> cparams .username ,TRI_DEFAULT ,
12221245false,progname ,NULL ,NULL ,NULL ,NULL );
12231246if (test_conn )
@@ -1226,7 +1249,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
12261249
12271250/* Use already created database for connection. */
12281251opts -> createDB = 0 ;
1229- opts -> cparams .dbname = db_cell -> str ;
1252+ opts -> cparams .dbname = dbidname -> str ;
12301253}
12311254else
12321255{
@@ -1251,7 +1274,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
12511274if (n_errors )
12521275{
12531276n_errors_total += n_errors ;
1254- pg_log_warning ("errors ignored on database \"%s\" restore: %d" ,db_cell -> str ,n_errors );
1277+ pg_log_warning ("errors ignored on database \"%s\" restore: %d" ,dbidname -> str ,n_errors );
12551278}
12561279
12571280count ++ ;
@@ -1261,7 +1284,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
12611284pg_log_info ("number of restored databases is %d" ,num_db_restore );
12621285
12631286/* Free dbname and dboid list. */
1264- simple_oid_string_list_destroy (& dbname_oid_list );
1287+ simple_ptr_list_destroy (& dbname_oid_list );
12651288
12661289return n_errors_total ;
12671290}