@@ -108,20 +108,18 @@ create_rel_filename_map(const char *old_data, const char *new_data,
108108 * relation belongs to the default tablespace, hence relfiles should
109109 * exist in the data directories.
110110 */
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" ;
115115 }
116116 else
117117 {
118118 /* 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 ;
125123 }
126124
127125 map -> old_db_oid = old_db -> db_oid ;
@@ -231,7 +229,7 @@ get_db_infos(ClusterInfo *cluster)
231229 {
232230 dbinfos [tupnum ].db_oid = atooid (PQgetvalue (res , tupnum , i_oid ));
233231 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" ,
235233 PQgetvalue (res , tupnum , i_spclocation ));
236234 }
237235 PQclear (res );
@@ -264,13 +262,15 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
264262 int num_rels = 0 ;
265263 char * nspname = NULL ;
266264 char * relname = NULL ;
265+ char * tablespace = NULL ;
267266 int i_spclocation ,
268267 i_nspname ,
269268 i_relname ,
270269 i_oid ,
271270 i_relfilenode ,
272271 i_reltablespace ;
273272 char query [QUERY_ALLOC ];
273+ char * last_namespace = NULL , * last_tablespace = NULL ;
274274
275275 /*
276276 * pg_largeobject contains user data that does not appear in pg_dumpall
@@ -366,26 +366,53 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
366366 for (relnum = 0 ; relnum < ntups ; relnum ++ )
367367 {
368368 RelInfo * curr = & relinfos [num_rels ++ ];
369- const char * tblspace ;
370369
371370 curr -> reloid = atooid (PQgetvalue (res , relnum , i_oid ));
372371
373372 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+ }
375388
376389 relname = PQgetvalue (res , relnum , i_relname );
377390 curr -> relname = pg_strdup (relname );
378391
379392 curr -> relfilenode = atooid (PQgetvalue (res , relnum , i_relfilenode ));
393+ curr -> tblsp_alloc = false;
380394
395+ /* Is the tablespace oid non-zero? */
381396 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+ }
384413 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 ;
389416 }
390417 PQclear (res );
391418
@@ -419,8 +446,11 @@ free_rel_infos(RelInfoArr *rel_arr)
419446
420447 for (relnum = 0 ; relnum < rel_arr -> nrels ; relnum ++ )
421448 {
422- pg_free (rel_arr -> rels [relnum ].nspname );
449+ if (rel_arr -> rels [relnum ].nsp_alloc )
450+ pg_free (rel_arr -> rels [relnum ].nspname );
423451 pg_free (rel_arr -> rels [relnum ].relname );
452+ if (rel_arr -> rels [relnum ].tblsp_alloc )
453+ pg_free (rel_arr -> rels [relnum ].tablespace );
424454 }
425455 pg_free (rel_arr -> rels );
426456 rel_arr -> nrels = 0 ;
0 commit comments