@@ -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}
116116else
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
127125map -> old_db_oid = old_db -> db_oid ;
@@ -231,7 +229,7 @@ get_db_infos(ClusterInfo *cluster)
231229{
232230dbinfos [tupnum ].db_oid = atooid (PQgetvalue (res ,tupnum ,i_oid ));
233231dbinfos [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" ,
235233PQgetvalue (res ,tupnum ,i_spclocation ));
236234}
237235PQclear (res );
@@ -264,13 +262,15 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
264262int num_rels = 0 ;
265263char * nspname = NULL ;
266264char * relname = NULL ;
265+ char * tablespace = NULL ;
267266int i_spclocation ,
268267i_nspname ,
269268i_relname ,
270269i_oid ,
271270i_relfilenode ,
272271i_reltablespace ;
273272char 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)
366366for (relnum = 0 ;relnum < ntups ;relnum ++ )
367367{
368368RelInfo * curr = & relinfos [num_rels ++ ];
369- const char * tblspace ;
370369
371370curr -> reloid = atooid (PQgetvalue (res ,relnum ,i_oid ));
372371
373372nspname = 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
376389relname = PQgetvalue (res ,relnum ,i_relname );
377390curr -> relname = pg_strdup (relname );
378391
379392curr -> relfilenode = atooid (PQgetvalue (res ,relnum ,i_relfilenode ));
393+ curr -> tblsp_alloc = false;
380394
395+ /* Is the tablespace oid non-zero? */
381396if (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+ }
384413else
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}
390417PQclear (res );
391418
@@ -419,8 +446,11 @@ free_rel_infos(RelInfoArr *rel_arr)
419446
420447for (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 );
423451pg_free (rel_arr -> rels [relnum ].relname );
452+ if (rel_arr -> rels [relnum ].tblsp_alloc )
453+ pg_free (rel_arr -> rels [relnum ].tablespace );
424454}
425455pg_free (rel_arr -> rels );
426456rel_arr -> nrels = 0 ;