55
55
#include "catalog/pg_trigger_d.h"
56
56
#include "catalog/pg_type_d.h"
57
57
#include "common/connect.h"
58
+ #include "common/shortest_dec.h"
58
59
#include "dumputils.h"
59
60
#include "fe_utils/option_utils.h"
60
61
#include "fe_utils/string_utils.h"
@@ -432,6 +433,9 @@ main(int argc, char **argv)
432
433
pg_logging_set_level(PG_LOG_WARNING);
433
434
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
434
435
436
+ /* ensure that locale does not affect floating point interpretation */
437
+ setlocale(LC_NUMERIC, "C");
438
+
435
439
/*
436
440
* Initialize what we need for parallel execution, especially for thread
437
441
* support on Windows.
@@ -6289,7 +6293,8 @@ getFuncs(Archive *fout, int *numFuncs)
6289
6293
*
6290
6294
*/
6291
6295
static RelStatsInfo *
6292
- getRelationStatistics(Archive *fout, DumpableObject *rel, char relkind)
6296
+ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
6297
+ float reltuples, int32 relallvisible, char relkind)
6293
6298
{
6294
6299
if (!fout->dopt->dumpStatistics)
6295
6300
return NULL;
@@ -6314,6 +6319,9 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, char relkind)
6314
6319
dobj->components |= DUMP_COMPONENT_STATISTICS;
6315
6320
dobj->name = pg_strdup(rel->name);
6316
6321
dobj->namespace = rel->namespace;
6322
+ info->relpages = relpages;
6323
+ info->reltuples = reltuples;
6324
+ info->relallvisible = relallvisible;
6317
6325
info->relkind = relkind;
6318
6326
info->postponed_def = false;
6319
6327
@@ -6349,6 +6357,8 @@ getTables(Archive *fout, int *numTables)
6349
6357
int i_relhasindex;
6350
6358
int i_relhasrules;
6351
6359
int i_relpages;
6360
+ int i_reltuples;
6361
+ int i_relallvisible;
6352
6362
int i_toastpages;
6353
6363
int i_owning_tab;
6354
6364
int i_owning_col;
@@ -6399,7 +6409,7 @@ getTables(Archive *fout, int *numTables)
6399
6409
"c.relowner, "
6400
6410
"c.relchecks, "
6401
6411
"c.relhasindex, c.relhasrules, c.relpages, "
6402
- "c.relhastriggers, "
6412
+ "c.reltuples, c.relallvisible, c. relhastriggers, "
6403
6413
"c.relpersistence, "
6404
6414
"c.reloftype, "
6405
6415
"c.relacl, "
@@ -6563,6 +6573,8 @@ getTables(Archive *fout, int *numTables)
6563
6573
i_relhasindex = PQfnumber(res, "relhasindex");
6564
6574
i_relhasrules = PQfnumber(res, "relhasrules");
6565
6575
i_relpages = PQfnumber(res, "relpages");
6576
+ i_reltuples = PQfnumber(res, "reltuples");
6577
+ i_relallvisible = PQfnumber(res, "relallvisible");
6566
6578
i_toastpages = PQfnumber(res, "toastpages");
6567
6579
i_owning_tab = PQfnumber(res, "owning_tab");
6568
6580
i_owning_col = PQfnumber(res, "owning_col");
@@ -6607,6 +6619,9 @@ getTables(Archive *fout, int *numTables)
6607
6619
6608
6620
for (i = 0; i < ntups; i++)
6609
6621
{
6622
+ float reltuples = strtof(PQgetvalue(res, i, i_reltuples), NULL);
6623
+ int32 relallvisible = atoi(PQgetvalue(res, i, i_relallvisible));
6624
+
6610
6625
tblinfo[i].dobj.objType = DO_TABLE;
6611
6626
tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
6612
6627
tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
@@ -6706,7 +6721,8 @@ getTables(Archive *fout, int *numTables)
6706
6721
6707
6722
/* Add statistics */
6708
6723
if (tblinfo[i].interesting)
6709
- getRelationStatistics(fout, &tblinfo[i].dobj, tblinfo[i].relkind);
6724
+ getRelationStatistics(fout, &tblinfo[i].dobj, tblinfo[i].relpages,
6725
+ reltuples, relallvisible, tblinfo[i].relkind);
6710
6726
6711
6727
/*
6712
6728
* Read-lock target tables to make sure they aren't DROPPED or altered
@@ -6948,6 +6964,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
6948
6964
i_oid,
6949
6965
i_indrelid,
6950
6966
i_indexname,
6967
+ i_relpages,
6968
+ i_reltuples,
6969
+ i_relallvisible,
6951
6970
i_parentidx,
6952
6971
i_indexdef,
6953
6972
i_indnkeyatts,
@@ -7000,6 +7019,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7000
7019
appendPQExpBuffer(query,
7001
7020
"SELECT t.tableoid, t.oid, i.indrelid, "
7002
7021
"t.relname AS indexname, "
7022
+ "t.relpages, t.reltuples, t.relallvisible, "
7003
7023
"pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
7004
7024
"i.indkey, i.indisclustered, "
7005
7025
"c.contype, c.conname, "
@@ -7100,6 +7120,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7100
7120
i_oid = PQfnumber(res, "oid");
7101
7121
i_indrelid = PQfnumber(res, "indrelid");
7102
7122
i_indexname = PQfnumber(res, "indexname");
7123
+ i_relpages = PQfnumber(res, "relpages");
7124
+ i_reltuples = PQfnumber(res, "reltuples");
7125
+ i_relallvisible = PQfnumber(res, "relallvisible");
7103
7126
i_parentidx = PQfnumber(res, "parentidx");
7104
7127
i_indexdef = PQfnumber(res, "indexdef");
7105
7128
i_indnkeyatts = PQfnumber(res, "indnkeyatts");
@@ -7165,6 +7188,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7165
7188
char contype;
7166
7189
char indexkind;
7167
7190
RelStatsInfo *relstats;
7191
+ int32 relpages = atoi(PQgetvalue(res, j, i_relpages));
7192
+ float reltuples = strtof(PQgetvalue(res, j, i_reltuples), NULL);
7193
+ int32 relallvisible = atoi(PQgetvalue(res, j, i_relallvisible));
7168
7194
7169
7195
indxinfo[j].dobj.objType = DO_INDEX;
7170
7196
indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
@@ -7199,7 +7225,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7199
7225
indexkind = RELKIND_PARTITIONED_INDEX;
7200
7226
7201
7227
contype = *(PQgetvalue(res, j, i_contype));
7202
- relstats = getRelationStatistics(fout, &indxinfo[j].dobj, indexkind);
7228
+ relstats = getRelationStatistics(fout, &indxinfo[j].dobj, relpages,
7229
+ reltuples, relallvisible, indexkind);
7203
7230
7204
7231
if (contype == 'p' || contype == 'u' || contype == 'x')
7205
7232
{
@@ -9826,18 +9853,6 @@ dumpComment(Archive *fout, const char *type,
9826
9853
catalogId, subid, dumpId, NULL);
9827
9854
}
9828
9855
9829
- /*
9830
- * Tabular description of the parameters to pg_restore_relation_stats()
9831
- * param_name, param_type
9832
- */
9833
- static const char *rel_stats_arginfo[][2] = {
9834
- {"relation", "regclass"},
9835
- {"version", "integer"},
9836
- {"relpages", "integer"},
9837
- {"reltuples", "real"},
9838
- {"relallvisible", "integer"},
9839
- };
9840
-
9841
9856
/*
9842
9857
* Tabular description of the parameters to pg_restore_attribute_stats()
9843
9858
* param_name, param_type
@@ -9862,30 +9877,6 @@ static const char *att_stats_arginfo[][2] = {
9862
9877
{"range_bounds_histogram", "text"},
9863
9878
};
9864
9879
9865
- /*
9866
- * getRelStatsExportQuery --
9867
- *
9868
- * Generate a query that will fetch all relation (e.g. pg_class)
9869
- * stats for a given relation.
9870
- */
9871
- static void
9872
- getRelStatsExportQuery(PQExpBuffer query, Archive *fout,
9873
- const char *schemaname, const char *relname)
9874
- {
9875
- resetPQExpBuffer(query);
9876
- appendPQExpBufferStr(query,
9877
- "SELECT c.oid::regclass AS relation, "
9878
- "current_setting('server_version_num') AS version, "
9879
- "c.relpages, c.reltuples, c.relallvisible "
9880
- "FROM pg_class c "
9881
- "JOIN pg_namespace n "
9882
- "ON n.oid = c.relnamespace "
9883
- "WHERE n.nspname = ");
9884
- appendStringLiteralAH(query, schemaname, fout);
9885
- appendPQExpBufferStr(query, " AND c.relname = ");
9886
- appendStringLiteralAH(query, relname, fout);
9887
- }
9888
-
9889
9880
/*
9890
9881
* getAttStatsExportQuery --
9891
9882
*
@@ -9897,21 +9888,22 @@ getAttStatsExportQuery(PQExpBuffer query, Archive *fout,
9897
9888
const char *schemaname, const char *relname)
9898
9889
{
9899
9890
resetPQExpBuffer(query);
9900
- appendPQExpBufferStr(query,
9901
- "SELECT c.oid::regclass AS relation, "
9902
- "s.attname,"
9903
- "s.inherited,"
9904
- "current_setting('server_version_num') AS version, "
9905
- "s.null_frac,"
9906
- "s.avg_width,"
9907
- "s.n_distinct,"
9908
- "s.most_common_vals,"
9909
- "s.most_common_freqs,"
9910
- "s.histogram_bounds,"
9911
- "s.correlation,"
9912
- "s.most_common_elems,"
9913
- "s.most_common_elem_freqs,"
9914
- "s.elem_count_histogram,");
9891
+ appendPQExpBuffer(query,
9892
+ "SELECT c.oid::regclass AS relation, "
9893
+ "s.attname,"
9894
+ "s.inherited,"
9895
+ "'%u'::integer AS version, "
9896
+ "s.null_frac,"
9897
+ "s.avg_width,"
9898
+ "s.n_distinct,"
9899
+ "s.most_common_vals,"
9900
+ "s.most_common_freqs,"
9901
+ "s.histogram_bounds,"
9902
+ "s.correlation,"
9903
+ "s.most_common_elems,"
9904
+ "s.most_common_elem_freqs,"
9905
+ "s.elem_count_histogram,",
9906
+ fout->remoteVersion);
9915
9907
9916
9908
if (fout->remoteVersion >= 170000)
9917
9909
appendPQExpBufferStr(query,
@@ -9964,34 +9956,21 @@ appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname,
9964
9956
* Append a formatted pg_restore_relation_stats statement.
9965
9957
*/
9966
9958
static void
9967
- appendRelStatsImport(PQExpBuffer out, Archive *fout, PGresult *res )
9959
+ appendRelStatsImport(PQExpBuffer out, Archive *fout, const RelStatsInfo *rsinfo )
9968
9960
{
9969
- const char *sep = "";
9961
+ const char *qualname = fmtQualifiedId(rsinfo->dobj.namespace->dobj.name, rsinfo->dobj.name);
9962
+ char reltuples_str[FLOAT_SHORTEST_DECIMAL_LEN];
9970
9963
9971
- if (PQntuples(res) == 0)
9972
- return;
9964
+ float_to_shortest_decimal_buf(rsinfo->reltuples, reltuples_str);
9973
9965
9974
9966
appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
9975
-
9976
- for (int argno = 0; argno < lengthof(rel_stats_arginfo); argno++)
9977
- {
9978
- const char *argname = rel_stats_arginfo[argno][0];
9979
- const char *argtype = rel_stats_arginfo[argno][1];
9980
- int fieldno = PQfnumber(res, argname);
9981
-
9982
- if (fieldno < 0)
9983
- pg_fatal("relation stats export query missing field '%s'",
9984
- argname);
9985
-
9986
- if (PQgetisnull(res, 0, fieldno))
9987
- continue;
9988
-
9989
- appendPQExpBufferStr(out, sep);
9990
- appendNamedArgument(out, fout, argname, PQgetvalue(res, 0, fieldno), argtype);
9991
-
9992
- sep = ",\n";
9993
- }
9994
- appendPQExpBufferStr(out, "\n);\n");
9967
+ appendPQExpBuffer(out, "\t'relation', '%s'::regclass,\n", qualname);
9968
+ appendPQExpBuffer(out, "\t'version', '%u'::integer,\n",
9969
+ fout->remoteVersion);
9970
+ appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
9971
+ appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", reltuples_str);
9972
+ appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer\n);\n",
9973
+ rsinfo->relallvisible);
9995
9974
}
9996
9975
9997
9976
/*
@@ -10086,15 +10065,11 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
10086
10065
tag = createPQExpBuffer();
10087
10066
appendPQExpBufferStr(tag, fmtId(dobj->name));
10088
10067
10089
- query = createPQExpBuffer();
10090
10068
out = createPQExpBuffer();
10091
10069
10092
- getRelStatsExportQuery(query, fout, dobj->namespace->dobj.name,
10093
- dobj->name);
10094
- res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10095
- appendRelStatsImport(out, fout, res);
10096
- PQclear(res);
10070
+ appendRelStatsImport(out, fout, rsinfo);
10097
10071
10072
+ query = createPQExpBuffer();
10098
10073
getAttStatsExportQuery(query, fout, dobj->namespace->dobj.name,
10099
10074
dobj->name);
10100
10075
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
0 commit comments