@@ -10415,10 +10415,8 @@ dumpComment(Archive *fout, const char *type,
1041510415 * param_name, param_type
1041610416 */
1041710417static const char *att_stats_arginfo[][2] = {
10418- {"relation", "regclass"},
1041910418{"attname", "name"},
1042010419{"inherited", "boolean"},
10421- {"version", "integer"},
1042210420{"null_frac", "float4"},
1042310421{"avg_width", "integer"},
1042410422{"n_distinct", "float4"},
@@ -10434,60 +10432,6 @@ static const char *att_stats_arginfo[][2] = {
1043410432{"range_bounds_histogram", "text"},
1043510433};
1043610434
10437- /*
10438- * getAttStatsExportQuery --
10439- *
10440- * Generate a query that will fetch all attribute (e.g. pg_statistic)
10441- * stats for a given relation.
10442- */
10443- static void
10444- getAttStatsExportQuery(PQExpBuffer query, Archive *fout,
10445- const char *schemaname, const char *relname)
10446- {
10447- resetPQExpBuffer(query);
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);
10464-
10465- if (fout->remoteVersion >= 170000)
10466- appendPQExpBufferStr(query,
10467- "s.range_length_histogram,"
10468- "s.range_empty_frac,"
10469- "s.range_bounds_histogram ");
10470- else
10471- appendPQExpBufferStr(query,
10472- "NULL AS range_length_histogram,"
10473- "NULL AS range_empty_frac,"
10474- "NULL AS range_bounds_histogram ");
10475-
10476- appendPQExpBufferStr(query,
10477- "FROM pg_stats s "
10478- "JOIN pg_namespace n "
10479- "ON n.nspname = s.schemaname "
10480- "JOIN pg_class c "
10481- "ON c.relname = s.tablename "
10482- "AND c.relnamespace = n.oid "
10483- "WHERE s.schemaname = ");
10484- appendStringLiteralAH(query, schemaname, fout);
10485- appendPQExpBufferStr(query, " AND s.tablename = ");
10486- appendStringLiteralAH(query, relname, fout);
10487- appendPQExpBufferStr(query, " ORDER BY s.attname, s.inherited");
10488- }
10489-
10490-
1049110435/*
1049210436 * appendNamedArgument --
1049310437 *
@@ -10513,17 +10457,17 @@ appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname,
1051310457 * Append a formatted pg_restore_relation_stats statement.
1051410458 */
1051510459static void
10516- appendRelStatsImport(PQExpBuffer out, Archive *fout, const RelStatsInfo *rsinfo)
10460+ appendRelStatsImport(PQExpBuffer out, Archive *fout, const RelStatsInfo *rsinfo,
10461+ const char *qualified_name)
1051710462{
10518- const char *qualname = fmtQualifiedId(rsinfo->dobj.namespace->dobj.name, rsinfo->dobj.name);
1051910463charreltuples_str[FLOAT_SHORTEST_DECIMAL_LEN];
1052010464
1052110465float_to_shortest_decimal_buf(rsinfo->reltuples, reltuples_str);
1052210466
1052310467appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
10524- appendPQExpBuffer(out, "\t'relation', '%s'::regclass,\n", qualname);
1052510468appendPQExpBuffer(out, "\t'version', '%u'::integer,\n",
1052610469 fout->remoteVersion);
10470+ appendPQExpBuffer(out, "\t'relation', '%s'::regclass,\n", qualified_name);
1052710471appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
1052810472appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", reltuples_str);
1052910473appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer\n);\n",
@@ -10536,13 +10480,18 @@ appendRelStatsImport(PQExpBuffer out, Archive *fout, const RelStatsInfo *rsinfo)
1053610480 * Append a series of formatted pg_restore_attribute_stats statements.
1053710481 */
1053810482static void
10539- appendAttStatsImport(PQExpBuffer out, Archive *fout, PGresult *res)
10483+ appendAttStatsImport(PQExpBuffer out, Archive *fout, PGresult *res,
10484+ const char *qualified_name)
1054010485{
1054110486for (int rownum = 0; rownum < PQntuples(res); rownum++)
1054210487{
1054310488const char *sep = "";
1054410489
1054510490appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_attribute_stats(\n");
10491+ appendPQExpBuffer(out, "\t'version', '%u'::integer,\n",
10492+ fout->remoteVersion);
10493+ appendPQExpBuffer(out, "\t'relation', '%s'::regclass,\n",
10494+ qualified_name);
1054610495for (int argno = 0; argno < lengthof(att_stats_arginfo); argno++)
1054710496{
1054810497const char *argname = att_stats_arginfo[argno][0];
@@ -10607,6 +10556,7 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
1060710556DumpableObject *dobj = (DumpableObject *) &rsinfo->dobj;
1060810557DumpId *deps = NULL;
1060910558intndeps = 0;
10559+ const char *qualified_name;
1061010560
1061110561/* nothing to do if we are not dumping statistics */
1061210562if (!fout->dopt->dumpStatistics)
@@ -10622,15 +10572,56 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
1062210572tag = createPQExpBuffer();
1062310573appendPQExpBufferStr(tag, fmtId(dobj->name));
1062410574
10625- out = createPQExpBuffer();
10575+ query = createPQExpBuffer();
10576+ if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
10577+ {
10578+ appendPQExpBufferStr(query,
10579+ "PREPARE getAttributeStats(pg_catalog.name, pg_catalog.name) AS\n"
10580+ "SELECT s.attname, s.inherited, "
10581+ "s.null_frac, s.avg_width, s.n_distinct, "
10582+ "s.most_common_vals, s.most_common_freqs, "
10583+ "s.histogram_bounds, s.correlation, "
10584+ "s.most_common_elems, s.most_common_elem_freqs, "
10585+ "s.elem_count_histogram, ");
10586+
10587+ if (fout->remoteVersion >= 170000)
10588+ appendPQExpBufferStr(query,
10589+ "s.range_length_histogram, s.range_empty_frac, "
10590+ "s.range_bounds_histogram ");
10591+ else
10592+ appendPQExpBufferStr(query,
10593+ "NULL AS range_length_histogram,"
10594+ "NULL AS range_empty_frac,"
10595+ "NULL AS range_bounds_histogram ");
1062610596
10627- appendRelStatsImport(out, fout, rsinfo);
10597+ appendPQExpBufferStr(query,
10598+ "FROM pg_stats s "
10599+ "WHERE s.schemaname = $1 "
10600+ "AND s.tablename = $2 "
10601+ "ORDER BY s.attname, s.inherited");
10602+
10603+ ExecuteSqlStatement(fout, query->data);
10604+
10605+ fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS] = true;
10606+ resetPQExpBuffer(query);
10607+ }
10608+
10609+ appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
10610+ appendStringLiteralAH(query, dobj->namespace->dobj.name, fout);
10611+ appendPQExpBufferStr(query, ", ");
10612+ appendStringLiteralAH(query, dobj->name, fout);
10613+ appendPQExpBufferStr(query, "); ");
1062810614
10629- query = createPQExpBuffer();
10630- getAttStatsExportQuery(query, fout, dobj->namespace->dobj.name,
10631- dobj->name);
1063210615res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10633- appendAttStatsImport(out, fout, res);
10616+
10617+ out = createPQExpBuffer();
10618+
10619+ qualified_name = fmtQualifiedId(rsinfo->dobj.namespace->dobj.name,
10620+ rsinfo->dobj.name);
10621+
10622+ appendRelStatsImport(out, fout, rsinfo, qualified_name);
10623+ appendAttStatsImport(out, fout, res, qualified_name);
10624+
1063410625PQclear(res);
1063510626
1063610627ArchiveEntry(fout, nilCatalogId, createDumpId(),