@@ -108,20 +108,18 @@ create_rel_filename_map(const char *old_data, const char *new_data,
108
108
* relation belongs to the default tablespace, hence relfiles should
109
109
* exist in the data directories.
110
110
*/
111
- strlcpy ( map -> old_tablespace , old_data , sizeof ( map -> old_tablespace )) ;
112
- strlcpy ( map -> new_tablespace , new_data , sizeof ( map -> new_tablespace )) ;
113
- strlcpy ( map -> old_tablespace_suffix , "/base" , sizeof ( map -> old_tablespace_suffix )) ;
114
- strlcpy ( map -> new_tablespace_suffix , "/base" , sizeof ( map -> new_tablespace_suffix )) ;
111
+ map -> old_tablespace = old_data ;
112
+ map -> new_tablespace = new_data ;
113
+ map -> old_tablespace_suffix = "/base" ;
114
+ map -> new_tablespace_suffix = "/base" ;
115
115
}
116
116
else
117
117
{
118
118
/* relation belongs to a tablespace, so use the tablespace location */
119
- strlcpy (map -> old_tablespace , old_rel -> tablespace , sizeof (map -> old_tablespace ));
120
- strlcpy (map -> new_tablespace , new_rel -> tablespace , sizeof (map -> new_tablespace ));
121
- strlcpy (map -> old_tablespace_suffix , old_cluster .tablespace_suffix ,
122
- sizeof (map -> old_tablespace_suffix ));
123
- strlcpy (map -> new_tablespace_suffix , new_cluster .tablespace_suffix ,
124
- sizeof (map -> new_tablespace_suffix ));
119
+ map -> old_tablespace = old_rel -> tablespace ;
120
+ map -> new_tablespace = new_rel -> tablespace ;
121
+ map -> old_tablespace_suffix = old_cluster .tablespace_suffix ;
122
+ map -> new_tablespace_suffix = new_cluster .tablespace_suffix ;
125
123
}
126
124
127
125
map -> old_db_oid = old_db -> db_oid ;
@@ -231,7 +229,7 @@ get_db_infos(ClusterInfo *cluster)
231
229
{
232
230
dbinfos [tupnum ].db_oid = atooid (PQgetvalue (res , tupnum , i_oid ));
233
231
dbinfos [tupnum ].db_name = pg_strdup (PQgetvalue (res , tupnum , i_datname ));
234
- snprintf (dbinfos [tupnum ].db_tblspace , sizeof (dbinfos [tupnum ].db_tblspace ), "%s" ,
232
+ snprintf (dbinfos [tupnum ].db_tablespace , sizeof (dbinfos [tupnum ].db_tablespace ), "%s" ,
235
233
PQgetvalue (res , tupnum , i_spclocation ));
236
234
}
237
235
PQclear (res );
@@ -264,13 +262,15 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
264
262
int num_rels = 0 ;
265
263
char * nspname = NULL ;
266
264
char * relname = NULL ;
265
+ char * tablespace = NULL ;
267
266
int i_spclocation ,
268
267
i_nspname ,
269
268
i_relname ,
270
269
i_oid ,
271
270
i_relfilenode ,
272
271
i_reltablespace ;
273
272
char query [QUERY_ALLOC ];
273
+ char * last_namespace = NULL , * last_tablespace = NULL ;
274
274
275
275
/*
276
276
* pg_largeobject contains user data that does not appear in pg_dumpall
@@ -366,26 +366,53 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
366
366
for (relnum = 0 ; relnum < ntups ; relnum ++ )
367
367
{
368
368
RelInfo * curr = & relinfos [num_rels ++ ];
369
- const char * tblspace ;
370
369
371
370
curr -> reloid = atooid (PQgetvalue (res , relnum , i_oid ));
372
371
373
372
nspname = PQgetvalue (res , relnum , i_nspname );
374
- curr -> nspname = pg_strdup (nspname );
373
+ curr -> nsp_alloc = false;
374
+
375
+ /*
376
+ * Many of the namespace and tablespace strings are identical,
377
+ * so we try to reuse the allocated string pointers where possible
378
+ * to reduce memory consumption.
379
+ */
380
+ /* Can we reuse the previous string allocation? */
381
+ if (last_namespace && strcmp (nspname , last_namespace ) == 0 )
382
+ curr -> nspname = last_namespace ;
383
+ else
384
+ {
385
+ last_namespace = curr -> nspname = pg_strdup (nspname );
386
+ curr -> nsp_alloc = true;
387
+ }
375
388
376
389
relname = PQgetvalue (res , relnum , i_relname );
377
390
curr -> relname = pg_strdup (relname );
378
391
379
392
curr -> relfilenode = atooid (PQgetvalue (res , relnum , i_relfilenode ));
393
+ curr -> tblsp_alloc = false;
380
394
395
+ /* Is the tablespace oid non-zero? */
381
396
if (atooid (PQgetvalue (res , relnum , i_reltablespace )) != 0 )
382
- /* Might be "", meaning the cluster default location. */
383
- tblspace = PQgetvalue (res , relnum , i_spclocation );
397
+ {
398
+ /*
399
+ * The tablespace location might be "", meaning the cluster
400
+ * default location, i.e. pg_default or pg_global.
401
+ */
402
+ tablespace = PQgetvalue (res , relnum , i_spclocation );
403
+
404
+ /* Can we reuse the previous string allocation? */
405
+ if (last_tablespace && strcmp (tablespace , last_tablespace ) == 0 )
406
+ curr -> tablespace = last_tablespace ;
407
+ else
408
+ {
409
+ last_tablespace = curr -> tablespace = pg_strdup (tablespace );
410
+ curr -> tblsp_alloc = true;
411
+ }
412
+ }
384
413
else
385
- /* A zero reltablespace indicates the database tablespace. */
386
- tblspace = dbinfo -> db_tblspace ;
387
-
388
- strlcpy (curr -> tablespace , tblspace , sizeof (curr -> tablespace ));
414
+ /* A zero reltablespace oid indicates the database tablespace. */
415
+ curr -> tablespace = dbinfo -> db_tablespace ;
389
416
}
390
417
PQclear (res );
391
418
@@ -419,8 +446,11 @@ free_rel_infos(RelInfoArr *rel_arr)
419
446
420
447
for (relnum = 0 ; relnum < rel_arr -> nrels ; relnum ++ )
421
448
{
422
- pg_free (rel_arr -> rels [relnum ].nspname );
449
+ if (rel_arr -> rels [relnum ].nsp_alloc )
450
+ pg_free (rel_arr -> rels [relnum ].nspname );
423
451
pg_free (rel_arr -> rels [relnum ].relname );
452
+ if (rel_arr -> rels [relnum ].tblsp_alloc )
453
+ pg_free (rel_arr -> rels [relnum ].tablespace );
424
454
}
425
455
pg_free (rel_arr -> rels );
426
456
rel_arr -> nrels = 0 ;
0 commit comments