@ -56,6 +56,7 @@
# include "common/connect.h"
# include "common/int.h"
# include "common/relpath.h"
# include "common/shortest_dec.h"
# include "compress_io.h"
# include "dumputils.h"
# include "fe_utils/option_utils.h"
@ -524,6 +525,9 @@ main(int argc, char **argv)
pg_logging_set_level ( PG_LOG_WARNING ) ;
set_pglocale_pgservice ( argv [ 0 ] , PG_TEXTDOMAIN ( " pg_dump " ) ) ;
/* ensure that locale does not affect floating point interpretation */
setlocale ( LC_NUMERIC , " C " ) ;
/*
* Initialize what we need for parallel execution , especially for thread
* support on Windows .
@ -6814,7 +6818,8 @@ getFuncs(Archive *fout)
*
*/
static RelStatsInfo *
getRelationStatistics ( Archive * fout , DumpableObject * rel , char relkind )
getRelationStatistics ( Archive * fout , DumpableObject * rel , int32 relpages ,
float reltuples , int32 relallvisible , char relkind )
{
if ( ! fout - > dopt - > dumpStatistics )
return NULL ;
@ -6839,6 +6844,9 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, char relkind)
dobj - > components | = DUMP_COMPONENT_STATISTICS ;
dobj - > name = pg_strdup ( rel - > name ) ;
dobj - > namespace = rel - > namespace ;
info - > relpages = relpages ;
info - > reltuples = reltuples ;
info - > relallvisible = relallvisible ;
info - > relkind = relkind ;
info - > postponed_def = false ;
@ -6874,6 +6882,8 @@ getTables(Archive *fout, int *numTables)
int i_relhasindex ;
int i_relhasrules ;
int i_relpages ;
int i_reltuples ;
int i_relallvisible ;
int i_toastpages ;
int i_owning_tab ;
int i_owning_col ;
@ -6924,7 +6934,7 @@ getTables(Archive *fout, int *numTables)
" c.relowner, "
" c.relchecks, "
" c.relhasindex, c.relhasrules, c.relpages, "
" c.relhastriggers, "
" c.reltuples, c.relallvisible, c.rel hastriggers, "
" c.relpersistence, "
" c.reloftype, "
" c.relacl, "
@ -7088,6 +7098,8 @@ getTables(Archive *fout, int *numTables)
i_relhasindex = PQfnumber ( res , " relhasindex " ) ;
i_relhasrules = PQfnumber ( res , " relhasrules " ) ;
i_relpages = PQfnumber ( res , " relpages " ) ;
i_reltuples = PQfnumber ( res , " reltuples " ) ;
i_relallvisible = PQfnumber ( res , " relallvisible " ) ;
i_toastpages = PQfnumber ( res , " toastpages " ) ;
i_owning_tab = PQfnumber ( res , " owning_tab " ) ;
i_owning_col = PQfnumber ( res , " owning_col " ) ;
@ -7134,6 +7146,9 @@ getTables(Archive *fout, int *numTables)
for ( i = 0 ; i < ntups ; i + + )
{
float reltuples = strtof ( PQgetvalue ( res , i , i_reltuples ) , NULL ) ;
int32 relallvisible = atoi ( PQgetvalue ( res , i , i_relallvisible ) ) ;
tblinfo [ i ] . dobj . objType = DO_TABLE ;
tblinfo [ i ] . dobj . catId . tableoid = atooid ( PQgetvalue ( res , i , i_reltableoid ) ) ;
tblinfo [ i ] . dobj . catId . oid = atooid ( PQgetvalue ( res , i , i_reloid ) ) ;
@ -7233,7 +7248,8 @@ getTables(Archive *fout, int *numTables)
/* Add statistics */
if ( tblinfo [ i ] . interesting )
getRelationStatistics ( fout , & tblinfo [ i ] . dobj , tblinfo [ i ] . relkind ) ;
getRelationStatistics ( fout , & tblinfo [ i ] . dobj , tblinfo [ i ] . relpages ,
reltuples , relallvisible , tblinfo [ i ] . relkind ) ;
/*
* Read - lock target tables to make sure they aren ' t DROPPED or altered
@ -7499,6 +7515,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
i_oid ,
i_indrelid ,
i_indexname ,
i_relpages ,
i_reltuples ,
i_relallvisible ,
i_parentidx ,
i_indexdef ,
i_indnkeyatts ,
@ -7552,6 +7571,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
appendPQExpBufferStr ( query ,
" SELECT t.tableoid, t.oid, i.indrelid, "
" t.relname AS indexname, "
" t.relpages, t.reltuples, t.relallvisible, "
" pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
" i.indkey, i.indisclustered, "
" c.contype, c.conname, "
@ -7659,6 +7679,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
i_oid = PQfnumber ( res , " oid " ) ;
i_indrelid = PQfnumber ( res , " indrelid " ) ;
i_indexname = PQfnumber ( res , " indexname " ) ;
i_relpages = PQfnumber ( res , " relpages " ) ;
i_reltuples = PQfnumber ( res , " reltuples " ) ;
i_relallvisible = PQfnumber ( res , " relallvisible " ) ;
i_parentidx = PQfnumber ( res , " parentidx " ) ;
i_indexdef = PQfnumber ( res , " indexdef " ) ;
i_indnkeyatts = PQfnumber ( res , " indnkeyatts " ) ;
@ -7725,6 +7748,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
char contype ;
char indexkind ;
RelStatsInfo * relstats ;
int32 relpages = atoi ( PQgetvalue ( res , j , i_relpages ) ) ;
float reltuples = strtof ( PQgetvalue ( res , j , i_reltuples ) , NULL ) ;
int32 relallvisible = atoi ( PQgetvalue ( res , j , i_relallvisible ) ) ;
indxinfo [ j ] . dobj . objType = DO_INDEX ;
indxinfo [ j ] . dobj . catId . tableoid = atooid ( PQgetvalue ( res , j , i_tableoid ) ) ;
@ -7759,7 +7785,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
indexkind = RELKIND_PARTITIONED_INDEX ;
contype = * ( PQgetvalue ( res , j , i_contype ) ) ;
relstats = getRelationStatistics ( fout , & indxinfo [ j ] . dobj , indexkind ) ;
relstats = getRelationStatistics ( fout , & indxinfo [ j ] . dobj , relpages ,
reltuples , relallvisible , indexkind ) ;
if ( contype = = ' p ' | | contype = = ' u ' | | contype = = ' x ' )
{
@ -10383,18 +10410,6 @@ dumpComment(Archive *fout, const char *type,
catalogId , subid , dumpId , NULL ) ;
}
/*
* Tabular description of the parameters to pg_restore_relation_stats ( )
* param_name , param_type
*/
static const char * rel_stats_arginfo [ ] [ 2 ] = {
{ " relation " , " regclass " } ,
{ " version " , " integer " } ,
{ " relpages " , " integer " } ,
{ " reltuples " , " real " } ,
{ " relallvisible " , " integer " } ,
} ;
/*
* Tabular description of the parameters to pg_restore_attribute_stats ( )
* param_name , param_type
@ -10419,30 +10434,6 @@ static const char *att_stats_arginfo[][2] = {
{ " range_bounds_histogram " , " text " } ,
} ;
/*
* getRelStatsExportQuery - -
*
* Generate a query that will fetch all relation ( e . g . pg_class )
* stats for a given relation .
*/
static void
getRelStatsExportQuery ( PQExpBuffer query , Archive * fout ,
const char * schemaname , const char * relname )
{
resetPQExpBuffer ( query ) ;
appendPQExpBufferStr ( query ,
" SELECT c.oid::regclass AS relation, "
" current_setting('server_version_num') AS version, "
" c.relpages, c.reltuples, c.relallvisible "
" FROM pg_class c "
" JOIN pg_namespace n "
" ON n.oid = c.relnamespace "
" WHERE n.nspname = " ) ;
appendStringLiteralAH ( query , schemaname , fout ) ;
appendPQExpBufferStr ( query , " AND c.relname = " ) ;
appendStringLiteralAH ( query , relname , fout ) ;
}
/*
* getAttStatsExportQuery - -
*
@ -10454,21 +10445,22 @@ getAttStatsExportQuery(PQExpBuffer query, Archive *fout,
const char * schemaname , const char * relname )
{
resetPQExpBuffer ( query ) ;
appendPQExpBufferStr ( query ,
" SELECT c.oid::regclass AS relation, "
" s.attname, "
" s.inherited, "
" current_setting('server_version_num') AS version, "
" s.null_frac, "
" s.avg_width, "
" s.n_distinct, "
" s.most_common_vals, "
" s.most_common_freqs, "
" s.histogram_bounds, "
" s.correlation, "
" s.most_common_elems, "
" s.most_common_elem_freqs, "
" s.elem_count_histogram, " ) ;
appendPQExpBuffer ( query ,
" SELECT c.oid::regclass AS relation, "
" s.attname, "
" s.inherited, "
" '%u'::integer AS version, "
" s.null_frac, "
" s.avg_width, "
" s.n_distinct, "
" s.most_common_vals, "
" s.most_common_freqs, "
" s.histogram_bounds, "
" s.correlation, "
" s.most_common_elems, "
" s.most_common_elem_freqs, "
" s.elem_count_histogram, " ,
fout - > remoteVersion ) ;
if ( fout - > remoteVersion > = 170000 )
appendPQExpBufferStr ( query ,
@ -10521,34 +10513,21 @@ appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname,
* Append a formatted pg_restore_relation_stats statement .
*/
static void
appendRelStatsImport ( PQExpBuffer out , Archive * fout , PGresult * res )
appendRelStatsImport ( PQExpBuffer out , Archive * fout , const RelStatsInfo * rsinfo )
{
const char * sep = " " ;
const char * qualname = fmtQualifiedId ( rsinfo - > dobj . namespace - > dobj . name , rsinfo - > dobj . name ) ;
char reltuples_str [ FLOAT_SHORTEST_DECIMAL_LEN ] ;
if ( PQntuples ( res ) = = 0 )
return ;
float_to_shortest_decimal_buf ( rsinfo - > reltuples , reltuples_str ) ;
appendPQExpBufferStr ( out , " SELECT * FROM pg_catalog.pg_restore_relation_stats( \n " ) ;
for ( int argno = 0 ; argno < lengthof ( rel_stats_arginfo ) ; argno + + )
{
const char * argname = rel_stats_arginfo [ argno ] [ 0 ] ;
const char * argtype = rel_stats_arginfo [ argno ] [ 1 ] ;
int fieldno = PQfnumber ( res , argname ) ;
if ( fieldno < 0 )
pg_fatal ( " relation stats export query missing field '%s' " ,
argname ) ;
if ( PQgetisnull ( res , 0 , fieldno ) )
continue ;
appendPQExpBufferStr ( out , sep ) ;
appendNamedArgument ( out , fout , argname , PQgetvalue ( res , 0 , fieldno ) , argtype ) ;
sep = " , \n " ;
}
appendPQExpBufferStr ( out , " \n ); \n " ) ;
appendPQExpBuffer ( out , " \t 'relation', '%s'::regclass, \n " , qualname ) ;
appendPQExpBuffer ( out , " \t 'version', '%u'::integer, \n " ,
fout - > remoteVersion ) ;
appendPQExpBuffer ( out , " \t 'relpages', '%d'::integer, \n " , rsinfo - > relpages ) ;
appendPQExpBuffer ( out , " \t 'reltuples', '%s'::real, \n " , reltuples_str ) ;
appendPQExpBuffer ( out , " \t 'relallvisible', '%d'::integer \n ); \n " ,
rsinfo - > relallvisible ) ;
}
/*
@ -10643,15 +10622,11 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
tag = createPQExpBuffer ( ) ;
appendPQExpBufferStr ( tag , fmtId ( dobj - > name ) ) ;
query = createPQExpBuffer ( ) ;
out = createPQExpBuffer ( ) ;
getRelStatsExportQuery ( query , fout , dobj - > namespace - > dobj . name ,
dobj - > name ) ;
res = ExecuteSqlQuery ( fout , query - > data , PGRES_TUPLES_OK ) ;
appendRelStatsImport ( out , fout , res ) ;
PQclear ( res ) ;
appendRelStatsImport ( out , fout , rsinfo ) ;
query = createPQExpBuffer ( ) ;
getAttStatsExportQuery ( query , fout , dobj - > namespace - > dobj . name ,
dobj - > name ) ;
res = ExecuteSqlQuery ( fout , query - > data , PGRES_TUPLES_OK ) ;