56
56
#include "common/connect.h"
57
57
#include "common/int.h"
58
58
#include "common/relpath.h"
59
+ #include "common/shortest_dec.h"
59
60
#include "compress_io.h"
60
61
#include "dumputils.h"
61
62
#include "fe_utils/option_utils.h"
@@ -524,6 +525,9 @@ main(int argc, char **argv)
524
525
pg_logging_set_level(PG_LOG_WARNING);
525
526
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
526
527
528
+ /* ensure that locale does not affect floating point interpretation */
529
+ setlocale(LC_NUMERIC, "C");
530
+
527
531
/*
528
532
* Initialize what we need for parallel execution, especially for thread
529
533
* support on Windows.
@@ -6814,7 +6818,8 @@ getFuncs(Archive *fout)
6814
6818
*
6815
6819
*/
6816
6820
static RelStatsInfo *
6817
- getRelationStatistics(Archive *fout, DumpableObject *rel, char relkind)
6821
+ getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
6822
+ float reltuples, int32 relallvisible, char relkind)
6818
6823
{
6819
6824
if (!fout->dopt->dumpStatistics)
6820
6825
return NULL;
@@ -6839,6 +6844,9 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, char relkind)
6839
6844
dobj->components |= DUMP_COMPONENT_STATISTICS;
6840
6845
dobj->name = pg_strdup(rel->name);
6841
6846
dobj->namespace = rel->namespace;
6847
+ info->relpages = relpages;
6848
+ info->reltuples = reltuples;
6849
+ info->relallvisible = relallvisible;
6842
6850
info->relkind = relkind;
6843
6851
info->postponed_def = false;
6844
6852
@@ -6874,6 +6882,8 @@ getTables(Archive *fout, int *numTables)
6874
6882
int i_relhasindex;
6875
6883
int i_relhasrules;
6876
6884
int i_relpages;
6885
+ int i_reltuples;
6886
+ int i_relallvisible;
6877
6887
int i_toastpages;
6878
6888
int i_owning_tab;
6879
6889
int i_owning_col;
@@ -6924,7 +6934,7 @@ getTables(Archive *fout, int *numTables)
6924
6934
"c.relowner, "
6925
6935
"c.relchecks, "
6926
6936
"c.relhasindex, c.relhasrules, c.relpages, "
6927
- "c.relhastriggers, "
6937
+ "c.reltuples, c.relallvisible, c. relhastriggers, "
6928
6938
"c.relpersistence, "
6929
6939
"c.reloftype, "
6930
6940
"c.relacl, "
@@ -7088,6 +7098,8 @@ getTables(Archive *fout, int *numTables)
7088
7098
i_relhasindex = PQfnumber(res, "relhasindex");
7089
7099
i_relhasrules = PQfnumber(res, "relhasrules");
7090
7100
i_relpages = PQfnumber(res, "relpages");
7101
+ i_reltuples = PQfnumber(res, "reltuples");
7102
+ i_relallvisible = PQfnumber(res, "relallvisible");
7091
7103
i_toastpages = PQfnumber(res, "toastpages");
7092
7104
i_owning_tab = PQfnumber(res, "owning_tab");
7093
7105
i_owning_col = PQfnumber(res, "owning_col");
@@ -7134,6 +7146,9 @@ getTables(Archive *fout, int *numTables)
7134
7146
7135
7147
for (i = 0; i < ntups; i++)
7136
7148
{
7149
+ float reltuples = strtof(PQgetvalue(res, i, i_reltuples), NULL);
7150
+ int32 relallvisible = atoi(PQgetvalue(res, i, i_relallvisible));
7151
+
7137
7152
tblinfo[i].dobj.objType = DO_TABLE;
7138
7153
tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
7139
7154
tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
@@ -7233,7 +7248,8 @@ getTables(Archive *fout, int *numTables)
7233
7248
7234
7249
/* Add statistics */
7235
7250
if (tblinfo[i].interesting)
7236
- getRelationStatistics(fout, &tblinfo[i].dobj, tblinfo[i].relkind);
7251
+ getRelationStatistics(fout, &tblinfo[i].dobj, tblinfo[i].relpages,
7252
+ reltuples, relallvisible, tblinfo[i].relkind);
7237
7253
7238
7254
/*
7239
7255
* Read-lock target tables to make sure they aren't DROPPED or altered
@@ -7499,6 +7515,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7499
7515
i_oid,
7500
7516
i_indrelid,
7501
7517
i_indexname,
7518
+ i_relpages,
7519
+ i_reltuples,
7520
+ i_relallvisible,
7502
7521
i_parentidx,
7503
7522
i_indexdef,
7504
7523
i_indnkeyatts,
@@ -7552,6 +7571,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7552
7571
appendPQExpBufferStr(query,
7553
7572
"SELECT t.tableoid, t.oid, i.indrelid, "
7554
7573
"t.relname AS indexname, "
7574
+ "t.relpages, t.reltuples, t.relallvisible, "
7555
7575
"pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
7556
7576
"i.indkey, i.indisclustered, "
7557
7577
"c.contype, c.conname, "
@@ -7659,6 +7679,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7659
7679
i_oid = PQfnumber(res, "oid");
7660
7680
i_indrelid = PQfnumber(res, "indrelid");
7661
7681
i_indexname = PQfnumber(res, "indexname");
7682
+ i_relpages = PQfnumber(res, "relpages");
7683
+ i_reltuples = PQfnumber(res, "reltuples");
7684
+ i_relallvisible = PQfnumber(res, "relallvisible");
7662
7685
i_parentidx = PQfnumber(res, "parentidx");
7663
7686
i_indexdef = PQfnumber(res, "indexdef");
7664
7687
i_indnkeyatts = PQfnumber(res, "indnkeyatts");
@@ -7725,6 +7748,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7725
7748
char contype;
7726
7749
char indexkind;
7727
7750
RelStatsInfo *relstats;
7751
+ int32 relpages = atoi(PQgetvalue(res, j, i_relpages));
7752
+ float reltuples = strtof(PQgetvalue(res, j, i_reltuples), NULL);
7753
+ int32 relallvisible = atoi(PQgetvalue(res, j, i_relallvisible));
7728
7754
7729
7755
indxinfo[j].dobj.objType = DO_INDEX;
7730
7756
indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
@@ -7759,7 +7785,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
7759
7785
indexkind = RELKIND_PARTITIONED_INDEX;
7760
7786
7761
7787
contype = *(PQgetvalue(res, j, i_contype));
7762
- relstats = getRelationStatistics(fout, &indxinfo[j].dobj, indexkind);
7788
+ relstats = getRelationStatistics(fout, &indxinfo[j].dobj, relpages,
7789
+ reltuples, relallvisible, indexkind);
7763
7790
7764
7791
if (contype == 'p' || contype == 'u' || contype == 'x')
7765
7792
{
@@ -10383,18 +10410,6 @@ dumpComment(Archive *fout, const char *type,
10383
10410
catalogId, subid, dumpId, NULL);
10384
10411
}
10385
10412
10386
- /*
10387
- * Tabular description of the parameters to pg_restore_relation_stats()
10388
- * param_name, param_type
10389
- */
10390
- static const char *rel_stats_arginfo[][2] = {
10391
- {"relation", "regclass"},
10392
- {"version", "integer"},
10393
- {"relpages", "integer"},
10394
- {"reltuples", "real"},
10395
- {"relallvisible", "integer"},
10396
- };
10397
-
10398
10413
/*
10399
10414
* Tabular description of the parameters to pg_restore_attribute_stats()
10400
10415
* param_name, param_type
@@ -10419,30 +10434,6 @@ static const char *att_stats_arginfo[][2] = {
10419
10434
{"range_bounds_histogram", "text"},
10420
10435
};
10421
10436
10422
- /*
10423
- * getRelStatsExportQuery --
10424
- *
10425
- * Generate a query that will fetch all relation (e.g. pg_class)
10426
- * stats for a given relation.
10427
- */
10428
- static void
10429
- getRelStatsExportQuery(PQExpBuffer query, Archive *fout,
10430
- const char *schemaname, const char *relname)
10431
- {
10432
- resetPQExpBuffer(query);
10433
- appendPQExpBufferStr(query,
10434
- "SELECT c.oid::regclass AS relation, "
10435
- "current_setting('server_version_num') AS version, "
10436
- "c.relpages, c.reltuples, c.relallvisible "
10437
- "FROM pg_class c "
10438
- "JOIN pg_namespace n "
10439
- "ON n.oid = c.relnamespace "
10440
- "WHERE n.nspname = ");
10441
- appendStringLiteralAH(query, schemaname, fout);
10442
- appendPQExpBufferStr(query, " AND c.relname = ");
10443
- appendStringLiteralAH(query, relname, fout);
10444
- }
10445
-
10446
10437
/*
10447
10438
* getAttStatsExportQuery --
10448
10439
*
@@ -10454,21 +10445,22 @@ getAttStatsExportQuery(PQExpBuffer query, Archive *fout,
10454
10445
const char *schemaname, const char *relname)
10455
10446
{
10456
10447
resetPQExpBuffer(query);
10457
- appendPQExpBufferStr(query,
10458
- "SELECT c.oid::regclass AS relation, "
10459
- "s.attname,"
10460
- "s.inherited,"
10461
- "current_setting('server_version_num') AS version, "
10462
- "s.null_frac,"
10463
- "s.avg_width,"
10464
- "s.n_distinct,"
10465
- "s.most_common_vals,"
10466
- "s.most_common_freqs,"
10467
- "s.histogram_bounds,"
10468
- "s.correlation,"
10469
- "s.most_common_elems,"
10470
- "s.most_common_elem_freqs,"
10471
- "s.elem_count_histogram,");
10448
+ appendPQExpBuffer(query,
10449
+ "SELECT c.oid::regclass AS relation, "
10450
+ "s.attname,"
10451
+ "s.inherited,"
10452
+ "'%u'::integer AS version, "
10453
+ "s.null_frac,"
10454
+ "s.avg_width,"
10455
+ "s.n_distinct,"
10456
+ "s.most_common_vals,"
10457
+ "s.most_common_freqs,"
10458
+ "s.histogram_bounds,"
10459
+ "s.correlation,"
10460
+ "s.most_common_elems,"
10461
+ "s.most_common_elem_freqs,"
10462
+ "s.elem_count_histogram,",
10463
+ fout->remoteVersion);
10472
10464
10473
10465
if (fout->remoteVersion >= 170000)
10474
10466
appendPQExpBufferStr(query,
@@ -10521,34 +10513,21 @@ appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname,
10521
10513
* Append a formatted pg_restore_relation_stats statement.
10522
10514
*/
10523
10515
static void
10524
- appendRelStatsImport(PQExpBuffer out, Archive *fout, PGresult *res )
10516
+ appendRelStatsImport(PQExpBuffer out, Archive *fout, const RelStatsInfo *rsinfo )
10525
10517
{
10526
- const char *sep = "";
10518
+ const char *qualname = fmtQualifiedId(rsinfo->dobj.namespace->dobj.name, rsinfo->dobj.name);
10519
+ char reltuples_str[FLOAT_SHORTEST_DECIMAL_LEN];
10527
10520
10528
- if (PQntuples(res) == 0)
10529
- return;
10521
+ float_to_shortest_decimal_buf(rsinfo->reltuples, reltuples_str);
10530
10522
10531
10523
appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
10532
-
10533
- for (int argno = 0; argno < lengthof(rel_stats_arginfo); argno++)
10534
- {
10535
- const char *argname = rel_stats_arginfo[argno][0];
10536
- const char *argtype = rel_stats_arginfo[argno][1];
10537
- int fieldno = PQfnumber(res, argname);
10538
-
10539
- if (fieldno < 0)
10540
- pg_fatal("relation stats export query missing field '%s'",
10541
- argname);
10542
-
10543
- if (PQgetisnull(res, 0, fieldno))
10544
- continue;
10545
-
10546
- appendPQExpBufferStr(out, sep);
10547
- appendNamedArgument(out, fout, argname, PQgetvalue(res, 0, fieldno), argtype);
10548
-
10549
- sep = ",\n";
10550
- }
10551
- appendPQExpBufferStr(out, "\n);\n");
10524
+ appendPQExpBuffer(out, "\t'relation', '%s'::regclass,\n", qualname);
10525
+ appendPQExpBuffer(out, "\t'version', '%u'::integer,\n",
10526
+ fout->remoteVersion);
10527
+ appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
10528
+ appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", reltuples_str);
10529
+ appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer\n);\n",
10530
+ rsinfo->relallvisible);
10552
10531
}
10553
10532
10554
10533
/*
@@ -10643,15 +10622,11 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
10643
10622
tag = createPQExpBuffer();
10644
10623
appendPQExpBufferStr(tag, fmtId(dobj->name));
10645
10624
10646
- query = createPQExpBuffer();
10647
10625
out = createPQExpBuffer();
10648
10626
10649
- getRelStatsExportQuery(query, fout, dobj->namespace->dobj.name,
10650
- dobj->name);
10651
- res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10652
- appendRelStatsImport(out, fout, res);
10653
- PQclear(res);
10627
+ appendRelStatsImport(out, fout, rsinfo);
10654
10628
10629
+ query = createPQExpBuffer();
10655
10630
getAttStatsExportQuery(query, fout, dobj->namespace->dobj.name,
10656
10631
dobj->name);
10657
10632
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
0 commit comments