1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-21 16:02:15 +03:00

Stats: use schemaname/relname instead of regclass.

For import and export, use schemaname/relname rather than
regclass.

This is more natural during export, fits with the other arguments
better, and it gives better control over error handling in case we
need to downgrade more errors to warnings.

Also, use text for the argument types for schemaname, relname, and
attname so that casts to "name" are not required.

Author: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://postgr.es/m/CADkLM=ceOSsx_=oe73QQ-BxUFR2Cwqum7-UP_fPe22DBY0NerA@mail.gmail.com
This commit is contained in:
Jeff Davis
2025-03-25 11:16:06 -07:00
parent 2a420f7995
commit 650ab8aaf1
11 changed files with 579 additions and 289 deletions

View File

@ -30364,14 +30364,15 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<structname>mytable</structname>: <structname>mytable</structname>:
<programlisting> <programlisting>
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'mytable'::regclass, 'schemaname', 'myschema',
'relname', 'mytable',
'relpages', 173::integer, 'relpages', 173::integer,
'reltuples', 10000::real); 'reltuples', 10000::real);
</programlisting> </programlisting>
</para> </para>
<para> <para>
The argument <literal>relation</literal> with a value of type The arguments <literal>schemaname</literal> and
<type>regclass</type> is required, and specifies the table. Other <literal>relname</literal> are required, and specify the table. Other
arguments are the names and values of statistics corresponding to arguments are the names and values of statistics corresponding to
certain columns in <link certain columns in <link
linkend="catalog-pg-class"><structname>pg_class</structname></link>. linkend="catalog-pg-class"><structname>pg_class</structname></link>.
@ -30408,7 +30409,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<indexterm> <indexterm>
<primary>pg_clear_relation_stats</primary> <primary>pg_clear_relation_stats</primary>
</indexterm> </indexterm>
<function>pg_clear_relation_stats</function> ( <parameter>relation</parameter> <type>regclass</type> ) <function>pg_clear_relation_stats</function> ( <parameter>schemaname</parameter> <type>text</type>, <parameter>relname</parameter> <type>text</type> )
<returnvalue>void</returnvalue> <returnvalue>void</returnvalue>
</para> </para>
<para> <para>
@ -30457,22 +30458,23 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<structname>mytable</structname>: <structname>mytable</structname>:
<programlisting> <programlisting>
SELECT pg_restore_attribute_stats( SELECT pg_restore_attribute_stats(
'relation', 'mytable'::regclass, 'schemaname', 'myschema',
'attname', 'col1'::name, 'relname', 'mytable',
'attname', 'col1',
'inherited', false, 'inherited', false,
'avg_width', 125::integer, 'avg_width', 125::integer,
'null_frac', 0.5::real); 'null_frac', 0.5::real);
</programlisting> </programlisting>
</para> </para>
<para> <para>
The required arguments are <literal>relation</literal> with a value The required arguments are <literal>schemaname</literal> and
of type <type>regclass</type>, which specifies the table; either <literal>relname</literal> with a value of type <type>text</type>
<literal>attname</literal> with a value of type <type>name</type> or which specify the table; either <literal>attname</literal> with a
<literal>attnum</literal> with a value of type <type>smallint</type>, value of type <type>text</type> or <literal>attnum</literal> with a
which specifies the column; and <literal>inherited</literal>, which value of type <type>smallint</type>, which specifies the column; and
specifies whether the statistics include values from child tables. <literal>inherited</literal>, which specifies whether the statistics
Other arguments are the names and values of statistics corresponding include values from child tables. Other arguments are the names and
to columns in <link values of statistics corresponding to columns in <link
linkend="view-pg-stats"><structname>pg_stats</structname></link>. linkend="view-pg-stats"><structname>pg_stats</structname></link>.
</para> </para>
<para> <para>
@ -30502,8 +30504,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<primary>pg_clear_attribute_stats</primary> <primary>pg_clear_attribute_stats</primary>
</indexterm> </indexterm>
<function>pg_clear_attribute_stats</function> ( <function>pg_clear_attribute_stats</function> (
<parameter>relation</parameter> <type>regclass</type>, <parameter>schemaname</parameter> <type>text</type>,
<parameter>attname</parameter> <type>name</type>, <parameter>relname</parameter> <type>text</type>,
<parameter>attname</parameter> <type>text</type>,
<parameter>inherited</parameter> <type>boolean</type> ) <parameter>inherited</parameter> <type>boolean</type> )
<returnvalue>void</returnvalue> <returnvalue>void</returnvalue>
</para> </para>

View File

@ -36,7 +36,8 @@
enum attribute_stats_argnum enum attribute_stats_argnum
{ {
ATTRELATION_ARG = 0, ATTRELSCHEMA_ARG = 0,
ATTRELNAME_ARG,
ATTNAME_ARG, ATTNAME_ARG,
ATTNUM_ARG, ATTNUM_ARG,
INHERITED_ARG, INHERITED_ARG,
@ -58,8 +59,9 @@ enum attribute_stats_argnum
static struct StatsArgInfo attarginfo[] = static struct StatsArgInfo attarginfo[] =
{ {
[ATTRELATION_ARG] = {"relation", REGCLASSOID}, [ATTRELSCHEMA_ARG] = {"schemaname", TEXTOID},
[ATTNAME_ARG] = {"attname", NAMEOID}, [ATTRELNAME_ARG] = {"relname", TEXTOID},
[ATTNAME_ARG] = {"attname", TEXTOID},
[ATTNUM_ARG] = {"attnum", INT2OID}, [ATTNUM_ARG] = {"attnum", INT2OID},
[INHERITED_ARG] = {"inherited", BOOLOID}, [INHERITED_ARG] = {"inherited", BOOLOID},
[NULL_FRAC_ARG] = {"null_frac", FLOAT4OID}, [NULL_FRAC_ARG] = {"null_frac", FLOAT4OID},
@ -80,7 +82,8 @@ static struct StatsArgInfo attarginfo[] =
enum clear_attribute_stats_argnum enum clear_attribute_stats_argnum
{ {
C_ATTRELATION_ARG = 0, C_ATTRELSCHEMA_ARG = 0,
C_ATTRELNAME_ARG,
C_ATTNAME_ARG, C_ATTNAME_ARG,
C_INHERITED_ARG, C_INHERITED_ARG,
C_NUM_ATTRIBUTE_STATS_ARGS C_NUM_ATTRIBUTE_STATS_ARGS
@ -88,8 +91,9 @@ enum clear_attribute_stats_argnum
static struct StatsArgInfo cleararginfo[] = static struct StatsArgInfo cleararginfo[] =
{ {
[C_ATTRELATION_ARG] = {"relation", REGCLASSOID}, [C_ATTRELSCHEMA_ARG] = {"relation", TEXTOID},
[C_ATTNAME_ARG] = {"attname", NAMEOID}, [C_ATTRELNAME_ARG] = {"relation", TEXTOID},
[C_ATTNAME_ARG] = {"attname", TEXTOID},
[C_INHERITED_ARG] = {"inherited", BOOLOID}, [C_INHERITED_ARG] = {"inherited", BOOLOID},
[C_NUM_ATTRIBUTE_STATS_ARGS] = {0} [C_NUM_ATTRIBUTE_STATS_ARGS] = {0}
}; };
@ -133,6 +137,8 @@ static void init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited,
static bool static bool
attribute_statistics_update(FunctionCallInfo fcinfo) attribute_statistics_update(FunctionCallInfo fcinfo)
{ {
char *nspname;
char *relname;
Oid reloid; Oid reloid;
char *attname; char *attname;
AttrNumber attnum; AttrNumber attnum;
@ -170,8 +176,13 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
bool result = true; bool result = true;
stats_check_required_arg(fcinfo, attarginfo, ATTRELATION_ARG); stats_check_required_arg(fcinfo, attarginfo, ATTRELSCHEMA_ARG);
reloid = PG_GETARG_OID(ATTRELATION_ARG); stats_check_required_arg(fcinfo, attarginfo, ATTRELNAME_ARG);
nspname = TextDatumGetCString(PG_GETARG_DATUM(ATTRELSCHEMA_ARG));
relname = TextDatumGetCString(PG_GETARG_DATUM(ATTRELNAME_ARG));
reloid = stats_lookup_relid(nspname, relname);
if (RecoveryInProgress()) if (RecoveryInProgress())
ereport(ERROR, ereport(ERROR,
@ -185,21 +196,18 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
/* user can specify either attname or attnum, but not both */ /* user can specify either attname or attnum, but not both */
if (!PG_ARGISNULL(ATTNAME_ARG)) if (!PG_ARGISNULL(ATTNAME_ARG))
{ {
Name attnamename;
if (!PG_ARGISNULL(ATTNUM_ARG)) if (!PG_ARGISNULL(ATTNUM_ARG))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot specify both attname and attnum"))); errmsg("cannot specify both attname and attnum")));
attnamename = PG_GETARG_NAME(ATTNAME_ARG); attname = TextDatumGetCString(PG_GETARG_DATUM(ATTNAME_ARG));
attname = NameStr(*attnamename);
attnum = get_attnum(reloid, attname); attnum = get_attnum(reloid, attname);
/* note that this test covers attisdropped cases too: */ /* note that this test covers attisdropped cases too: */
if (attnum == InvalidAttrNumber) if (attnum == InvalidAttrNumber)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN), (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist", errmsg("column \"%s\" of relation \"%s\" does not exist",
attname, get_rel_name(reloid)))); attname, relname)));
} }
else if (!PG_ARGISNULL(ATTNUM_ARG)) else if (!PG_ARGISNULL(ATTNUM_ARG))
{ {
@ -211,7 +219,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN), (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column %d of relation \"%s\" does not exist", errmsg("column %d of relation \"%s\" does not exist",
attnum, get_rel_name(reloid)))); attnum, relname)));
} }
else else
{ {
@ -900,13 +908,22 @@ init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited,
Datum Datum
pg_clear_attribute_stats(PG_FUNCTION_ARGS) pg_clear_attribute_stats(PG_FUNCTION_ARGS)
{ {
char *nspname;
char *relname;
Oid reloid; Oid reloid;
Name attname; char *attname;
AttrNumber attnum; AttrNumber attnum;
bool inherited; bool inherited;
stats_check_required_arg(fcinfo, cleararginfo, C_ATTRELATION_ARG); stats_check_required_arg(fcinfo, cleararginfo, C_ATTRELSCHEMA_ARG);
reloid = PG_GETARG_OID(C_ATTRELATION_ARG); stats_check_required_arg(fcinfo, cleararginfo, C_ATTRELNAME_ARG);
stats_check_required_arg(fcinfo, cleararginfo, C_ATTNAME_ARG);
stats_check_required_arg(fcinfo, cleararginfo, C_INHERITED_ARG);
nspname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTRELSCHEMA_ARG));
relname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTRELNAME_ARG));
reloid = stats_lookup_relid(nspname, relname);
if (RecoveryInProgress()) if (RecoveryInProgress())
ereport(ERROR, ereport(ERROR,
@ -916,23 +933,21 @@ pg_clear_attribute_stats(PG_FUNCTION_ARGS)
stats_lock_check_privileges(reloid); stats_lock_check_privileges(reloid);
stats_check_required_arg(fcinfo, cleararginfo, C_ATTNAME_ARG); attname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTNAME_ARG));
attname = PG_GETARG_NAME(C_ATTNAME_ARG); attnum = get_attnum(reloid, attname);
attnum = get_attnum(reloid, NameStr(*attname));
if (attnum < 0) if (attnum < 0)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot clear statistics on system column \"%s\"", errmsg("cannot clear statistics on system column \"%s\"",
NameStr(*attname)))); attname)));
if (attnum == InvalidAttrNumber) if (attnum == InvalidAttrNumber)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN), (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist", errmsg("column \"%s\" of relation \"%s\" does not exist",
NameStr(*attname), get_rel_name(reloid)))); attname, get_rel_name(reloid))));
stats_check_required_arg(fcinfo, cleararginfo, C_INHERITED_ARG);
inherited = PG_GETARG_BOOL(C_INHERITED_ARG); inherited = PG_GETARG_BOOL(C_INHERITED_ARG);
delete_pg_statistic(reloid, attnum, inherited); delete_pg_statistic(reloid, attnum, inherited);

View File

@ -19,9 +19,12 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "statistics/stat_utils.h" #include "statistics/stat_utils.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/fmgrprotos.h" #include "utils/fmgrprotos.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h" #include "utils/syscache.h"
@ -32,7 +35,8 @@
enum relation_stats_argnum enum relation_stats_argnum
{ {
RELATION_ARG = 0, RELSCHEMA_ARG = 0,
RELNAME_ARG,
RELPAGES_ARG, RELPAGES_ARG,
RELTUPLES_ARG, RELTUPLES_ARG,
RELALLVISIBLE_ARG, RELALLVISIBLE_ARG,
@ -42,7 +46,8 @@ enum relation_stats_argnum
static struct StatsArgInfo relarginfo[] = static struct StatsArgInfo relarginfo[] =
{ {
[RELATION_ARG] = {"relation", REGCLASSOID}, [RELSCHEMA_ARG] = {"schemaname", TEXTOID},
[RELNAME_ARG] = {"relname", TEXTOID},
[RELPAGES_ARG] = {"relpages", INT4OID}, [RELPAGES_ARG] = {"relpages", INT4OID},
[RELTUPLES_ARG] = {"reltuples", FLOAT4OID}, [RELTUPLES_ARG] = {"reltuples", FLOAT4OID},
[RELALLVISIBLE_ARG] = {"relallvisible", INT4OID}, [RELALLVISIBLE_ARG] = {"relallvisible", INT4OID},
@ -59,6 +64,8 @@ static bool
relation_statistics_update(FunctionCallInfo fcinfo) relation_statistics_update(FunctionCallInfo fcinfo)
{ {
bool result = true; bool result = true;
char *nspname;
char *relname;
Oid reloid; Oid reloid;
Relation crel; Relation crel;
BlockNumber relpages = 0; BlockNumber relpages = 0;
@ -76,6 +83,22 @@ relation_statistics_update(FunctionCallInfo fcinfo)
bool nulls[4] = {0}; bool nulls[4] = {0};
int nreplaces = 0; int nreplaces = 0;
stats_check_required_arg(fcinfo, relarginfo, RELSCHEMA_ARG);
stats_check_required_arg(fcinfo, relarginfo, RELNAME_ARG);
nspname = TextDatumGetCString(PG_GETARG_DATUM(RELSCHEMA_ARG));
relname = TextDatumGetCString(PG_GETARG_DATUM(RELNAME_ARG));
reloid = stats_lookup_relid(nspname, relname);
if (RecoveryInProgress())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("recovery is in progress"),
errhint("Statistics cannot be modified during recovery.")));
stats_lock_check_privileges(reloid);
if (!PG_ARGISNULL(RELPAGES_ARG)) if (!PG_ARGISNULL(RELPAGES_ARG))
{ {
relpages = PG_GETARG_UINT32(RELPAGES_ARG); relpages = PG_GETARG_UINT32(RELPAGES_ARG);
@ -108,17 +131,6 @@ relation_statistics_update(FunctionCallInfo fcinfo)
update_relallfrozen = true; update_relallfrozen = true;
} }
stats_check_required_arg(fcinfo, relarginfo, RELATION_ARG);
reloid = PG_GETARG_OID(RELATION_ARG);
if (RecoveryInProgress())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("recovery is in progress"),
errhint("Statistics cannot be modified during recovery.")));
stats_lock_check_privileges(reloid);
/* /*
* Take RowExclusiveLock on pg_class, consistent with * Take RowExclusiveLock on pg_class, consistent with
* vac_update_relstats(). * vac_update_relstats().
@ -187,20 +199,22 @@ relation_statistics_update(FunctionCallInfo fcinfo)
Datum Datum
pg_clear_relation_stats(PG_FUNCTION_ARGS) pg_clear_relation_stats(PG_FUNCTION_ARGS)
{ {
LOCAL_FCINFO(newfcinfo, 5); LOCAL_FCINFO(newfcinfo, 6);
InitFunctionCallInfoData(*newfcinfo, NULL, 5, InvalidOid, NULL, NULL); InitFunctionCallInfoData(*newfcinfo, NULL, 6, InvalidOid, NULL, NULL);
newfcinfo->args[0].value = PG_GETARG_OID(0); newfcinfo->args[0].value = PG_GETARG_DATUM(0);
newfcinfo->args[0].isnull = PG_ARGISNULL(0); newfcinfo->args[0].isnull = PG_ARGISNULL(0);
newfcinfo->args[1].value = UInt32GetDatum(0); newfcinfo->args[1].value = PG_GETARG_DATUM(1);
newfcinfo->args[1].isnull = false; newfcinfo->args[1].isnull = PG_ARGISNULL(1);
newfcinfo->args[2].value = Float4GetDatum(-1.0); newfcinfo->args[2].value = UInt32GetDatum(0);
newfcinfo->args[2].isnull = false; newfcinfo->args[2].isnull = false;
newfcinfo->args[3].value = UInt32GetDatum(0); newfcinfo->args[3].value = Float4GetDatum(-1.0);
newfcinfo->args[3].isnull = false; newfcinfo->args[3].isnull = false;
newfcinfo->args[4].value = UInt32GetDatum(0); newfcinfo->args[4].value = UInt32GetDatum(0);
newfcinfo->args[4].isnull = false; newfcinfo->args[4].isnull = false;
newfcinfo->args[5].value = UInt32GetDatum(0);
newfcinfo->args[5].isnull = false;
relation_statistics_update(newfcinfo); relation_statistics_update(newfcinfo);
PG_RETURN_VOID(); PG_RETURN_VOID();

View File

@ -18,6 +18,7 @@
#include "access/relation.h" #include "access/relation.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "funcapi.h" #include "funcapi.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -213,6 +214,27 @@ stats_lock_check_privileges(Oid reloid)
relation_close(table, NoLock); relation_close(table, NoLock);
} }
/*
* Lookup relation oid from schema and relation name.
*/
Oid
stats_lookup_relid(const char *nspname, const char *relname)
{
Oid nspoid;
Oid reloid;
nspoid = LookupExplicitNamespace(nspname, false);
reloid = get_relname_relid(relname, nspoid);
if (!OidIsValid(reloid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation \"%s.%s\" does not exist",
nspname, relname)));
return reloid;
}
/* /*
* Find the argument number for the given argument name, returning -1 if not * Find the argument number for the given argument name, returning -1 if not
* found. * found.

View File

@ -10498,7 +10498,6 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
PQExpBuffer out; PQExpBuffer out;
DumpId *deps = NULL; DumpId *deps = NULL;
int ndeps = 0; int ndeps = 0;
char *qualified_name;
int i_attname; int i_attname;
int i_inherited; int i_inherited;
int i_null_frac; int i_null_frac;
@ -10563,15 +10562,16 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
out = createPQExpBuffer(); out = createPQExpBuffer();
qualified_name = pg_strdup(fmtQualifiedDumpable(rsinfo));
/* restore relation stats */ /* restore relation stats */
appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n"); appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
appendPQExpBuffer(out, "\t'version', '%u'::integer,\n", appendPQExpBuffer(out, "\t'version', '%u'::integer,\n",
fout->remoteVersion); fout->remoteVersion);
appendPQExpBufferStr(out, "\t'relation', "); appendPQExpBufferStr(out, "\t'schemaname', ");
appendStringLiteralAH(out, qualified_name, fout); appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
appendPQExpBufferStr(out, "::regclass,\n"); appendPQExpBufferStr(out, ",\n");
appendPQExpBufferStr(out, "\t'relname', ");
appendStringLiteralAH(out, rsinfo->dobj.name, fout);
appendPQExpBufferStr(out, ",\n");
appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages); appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", rsinfo->reltuples); appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", rsinfo->reltuples);
appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer\n);\n", appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer\n);\n",
@ -10610,9 +10610,10 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_attribute_stats(\n"); appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_attribute_stats(\n");
appendPQExpBuffer(out, "\t'version', '%u'::integer,\n", appendPQExpBuffer(out, "\t'version', '%u'::integer,\n",
fout->remoteVersion); fout->remoteVersion);
appendPQExpBufferStr(out, "\t'relation', "); appendPQExpBufferStr(out, "\t'schemaname', ");
appendStringLiteralAH(out, qualified_name, fout); appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
appendPQExpBufferStr(out, "::regclass"); appendPQExpBufferStr(out, ",\n\t'relname', ");
appendStringLiteralAH(out, rsinfo->dobj.name, fout);
if (PQgetisnull(res, rownum, i_attname)) if (PQgetisnull(res, rownum, i_attname))
pg_fatal("attname cannot be NULL"); pg_fatal("attname cannot be NULL");
@ -10624,7 +10625,10 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
* their attnames are not necessarily stable across dump/reload. * their attnames are not necessarily stable across dump/reload.
*/ */
if (rsinfo->nindAttNames == 0) if (rsinfo->nindAttNames == 0)
appendNamedArgument(out, fout, "attname", "name", attname); {
appendPQExpBuffer(out, ",\n\t'attname', ");
appendStringLiteralAH(out, attname, fout);
}
else else
{ {
bool found = false; bool found = false;
@ -10704,7 +10708,6 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
.deps = deps, .deps = deps,
.nDeps = ndeps)); .nDeps = ndeps));
free(qualified_name);
destroyPQExpBuffer(out); destroyPQExpBuffer(out);
destroyPQExpBuffer(query); destroyPQExpBuffer(query);
} }

View File

@ -4741,14 +4741,16 @@ my %tests = (
regexp => qr/^ regexp => qr/^
\QSELECT * FROM pg_catalog.pg_restore_relation_stats(\E\s+ \QSELECT * FROM pg_catalog.pg_restore_relation_stats(\E\s+
'version',\s'\d+'::integer,\s+ 'version',\s'\d+'::integer,\s+
'relation',\s'dump_test.dup_test_post_data_ix'::regclass,\s+ 'schemaname',\s'dump_test',\s+
'relname',\s'dup_test_post_data_ix',\s+
'relpages',\s'\d+'::integer,\s+ 'relpages',\s'\d+'::integer,\s+
'reltuples',\s'\d+'::real,\s+ 'reltuples',\s'\d+'::real,\s+
'relallvisible',\s'\d+'::integer\s+ 'relallvisible',\s'\d+'::integer\s+
\);\s+ \);\s+
\QSELECT * FROM pg_catalog.pg_restore_attribute_stats(\E\s+ \QSELECT * FROM pg_catalog.pg_restore_attribute_stats(\E\s+
'version',\s'\d+'::integer,\s+ 'version',\s'\d+'::integer,\s+
'relation',\s'dump_test.dup_test_post_data_ix'::regclass,\s+ 'schemaname',\s'dump_test',\s+
'relname',\s'dup_test_post_data_ix',\s+
'attnum',\s'2'::smallint,\s+ 'attnum',\s'2'::smallint,\s+
'inherited',\s'f'::boolean,\s+ 'inherited',\s'f'::boolean,\s+
'null_frac',\s'0'::real,\s+ 'null_frac',\s'0'::real,\s+

View File

@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202503241 #define CATALOG_VERSION_NO 202503251
#endif #endif

View File

@ -12453,8 +12453,8 @@
descr => 'clear statistics on relation', descr => 'clear statistics on relation',
proname => 'pg_clear_relation_stats', provolatile => 'v', proisstrict => 'f', proname => 'pg_clear_relation_stats', provolatile => 'v', proisstrict => 'f',
proparallel => 'u', prorettype => 'void', proparallel => 'u', prorettype => 'void',
proargtypes => 'regclass', proargtypes => 'text text',
proargnames => '{relation}', proargnames => '{schemaname,relname}',
prosrc => 'pg_clear_relation_stats' }, prosrc => 'pg_clear_relation_stats' },
{ oid => '8461', { oid => '8461',
descr => 'restore statistics on attribute', descr => 'restore statistics on attribute',
@ -12469,8 +12469,8 @@
descr => 'clear statistics on attribute', descr => 'clear statistics on attribute',
proname => 'pg_clear_attribute_stats', provolatile => 'v', proisstrict => 'f', proname => 'pg_clear_attribute_stats', provolatile => 'v', proisstrict => 'f',
proparallel => 'u', prorettype => 'void', proparallel => 'u', prorettype => 'void',
proargtypes => 'regclass name bool', proargtypes => 'text text text bool',
proargnames => '{relation,attname,inherited}', proargnames => '{schemaname,relname,attname,inherited}',
prosrc => 'pg_clear_attribute_stats' }, prosrc => 'pg_clear_attribute_stats' },
# GiST stratnum implementations # GiST stratnum implementations

View File

@ -32,6 +32,8 @@ extern bool stats_check_arg_pair(FunctionCallInfo fcinfo,
extern void stats_lock_check_privileges(Oid reloid); extern void stats_lock_check_privileges(Oid reloid);
extern Oid stats_lookup_relid(const char *nspname, const char *relname);
extern bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo, extern bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
FunctionCallInfo positional_fcinfo, FunctionCallInfo positional_fcinfo,
struct StatsArgInfo *arginfo); struct StatsArgInfo *arginfo);

View File

@ -14,7 +14,8 @@ CREATE TABLE stats_import.test(
) WITH (autovacuum_enabled = false); ) WITH (autovacuum_enabled = false);
SELECT SELECT
pg_catalog.pg_restore_relation_stats( pg_catalog.pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relpages', 18::integer, 'relpages', 18::integer,
'reltuples', 21::real, 'reltuples', 21::real,
'relallvisible', 24::integer, 'relallvisible', 24::integer,
@ -36,7 +37,7 @@ ORDER BY relname;
test | 18 | 21 | 24 | 27 test | 18 | 21 | 24 | 27
(1 row) (1 row)
SELECT pg_clear_relation_stats('stats_import.test'::regclass); SELECT pg_clear_relation_stats('stats_import', 'test');
pg_clear_relation_stats pg_clear_relation_stats
------------------------- -------------------------
@ -45,33 +46,49 @@ SELECT pg_clear_relation_stats('stats_import.test'::regclass);
-- --
-- relstats tests -- relstats tests
-- --
--- error: relation is wrong type -- error: schemaname missing
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 0::oid, 'relname', 'test',
'relpages', 17::integer); 'relpages', 17::integer);
WARNING: argument "relation" has type "oid", expected type "regclass" ERROR: "schemaname" cannot be NULL
ERROR: "relation" cannot be NULL -- error: relname missing
SELECT pg_catalog.pg_restore_relation_stats(
'schemaname', 'stats_import',
'relpages', 17::integer);
ERROR: "relname" cannot be NULL
--- error: schemaname is wrong type
SELECT pg_catalog.pg_restore_relation_stats(
'schemaname', 3.6::float,
'relname', 'test',
'relpages', 17::integer);
WARNING: argument "schemaname" has type "double precision", expected type "text"
ERROR: "schemaname" cannot be NULL
--- error: relname is wrong type
SELECT pg_catalog.pg_restore_relation_stats(
'schemaname', 'stats_import',
'relname', 0::oid,
'relpages', 17::integer);
WARNING: argument "relname" has type "oid", expected type "text"
ERROR: "relname" cannot be NULL
-- error: relation not found -- error: relation not found
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 0::oid::regclass, 'schemaname', 'stats_import',
'relname', 'nope',
'relpages', 17::integer); 'relpages', 17::integer);
ERROR: could not open relation with OID 0 ERROR: relation "stats_import.nope" does not exist
-- error: odd number of variadic arguments cannot be pairs -- error: odd number of variadic arguments cannot be pairs
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relallvisible'); 'relallvisible');
ERROR: variadic arguments must be name/value pairs ERROR: variadic arguments must be name/value pairs
HINT: Provide an even number of variadic arguments that can be divided into pairs. HINT: Provide an even number of variadic arguments that can be divided into pairs.
-- error: argument name is NULL -- error: argument name is NULL
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
NULL, '17'::integer); NULL, '17'::integer);
ERROR: name at variadic position 3 is NULL ERROR: name at variadic position 5 is NULL
-- error: argument name is not a text type
SELECT pg_restore_relation_stats(
'relation', '0'::oid::regclass,
17, '17'::integer);
ERROR: name at variadic position 3 has type "integer", expected type "text"
-- starting stats -- starting stats
SELECT relpages, reltuples, relallvisible, relallfrozen SELECT relpages, reltuples, relallvisible, relallfrozen
FROM pg_class FROM pg_class
@ -84,7 +101,8 @@ WHERE oid = 'stats_import.test_i'::regclass;
-- regular indexes have special case locking rules -- regular indexes have special case locking rules
BEGIN; BEGIN;
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 'stats_import.test_i'::regclass, 'schemaname', 'stats_import',
'relname', 'test_i',
'relpages', 18::integer); 'relpages', 18::integer);
pg_restore_relation_stats pg_restore_relation_stats
--------------------------- ---------------------------
@ -132,7 +150,8 @@ WHERE oid = 'stats_import.part_parent'::regclass;
-- --
BEGIN; BEGIN;
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 'stats_import.part_parent_i'::regclass, 'schemaname', 'stats_import',
'relname', 'part_parent_i',
'relpages', 2::integer); 'relpages', 2::integer);
pg_restore_relation_stats pg_restore_relation_stats
--------------------------- ---------------------------
@ -166,7 +185,8 @@ WHERE oid = 'stats_import.part_parent_i'::regclass;
-- ok: set all relstats, with version, no bounds checking -- ok: set all relstats, with version, no bounds checking
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'version', 150000::integer, 'version', 150000::integer,
'relpages', '-17'::integer, 'relpages', '-17'::integer,
'reltuples', 400::real, 'reltuples', 400::real,
@ -187,7 +207,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- ok: set just relpages, rest stay same -- ok: set just relpages, rest stay same
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relpages', '16'::integer); 'relpages', '16'::integer);
pg_restore_relation_stats pg_restore_relation_stats
--------------------------- ---------------------------
@ -204,7 +225,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- ok: set just reltuples, rest stay same -- ok: set just reltuples, rest stay same
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'reltuples', '500'::real); 'reltuples', '500'::real);
pg_restore_relation_stats pg_restore_relation_stats
--------------------------- ---------------------------
@ -221,7 +243,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- ok: set just relallvisible, rest stay same -- ok: set just relallvisible, rest stay same
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relallvisible', 5::integer); 'relallvisible', 5::integer);
pg_restore_relation_stats pg_restore_relation_stats
--------------------------- ---------------------------
@ -238,7 +261,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- ok: just relallfrozen -- ok: just relallfrozen
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'version', 150000::integer, 'version', 150000::integer,
'relallfrozen', 3::integer); 'relallfrozen', 3::integer);
pg_restore_relation_stats pg_restore_relation_stats
@ -256,7 +280,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- warn: bad relpages type, rest updated -- warn: bad relpages type, rest updated
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relpages', 'nope'::text, 'relpages', 'nope'::text,
'reltuples', 400.0::real, 'reltuples', 400.0::real,
'relallvisible', 4::integer, 'relallvisible', 4::integer,
@ -277,7 +302,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- unrecognized argument name, rest ok -- unrecognized argument name, rest ok
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relpages', '171'::integer, 'relpages', '171'::integer,
'nope', 10::integer); 'nope', 10::integer);
WARNING: unrecognized argument name: "nope" WARNING: unrecognized argument name: "nope"
@ -295,8 +321,7 @@ WHERE oid = 'stats_import.test'::regclass;
(1 row) (1 row)
-- ok: clear stats -- ok: clear stats
SELECT pg_catalog.pg_clear_relation_stats( SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'test');
relation => 'stats_import.test'::regclass);
pg_clear_relation_stats pg_clear_relation_stats
------------------------- -------------------------
@ -313,50 +338,71 @@ WHERE oid = 'stats_import.test'::regclass;
-- invalid relkinds for statistics -- invalid relkinds for statistics
CREATE SEQUENCE stats_import.testseq; CREATE SEQUENCE stats_import.testseq;
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 'stats_import.testseq'::regclass); 'schemaname', 'stats_import',
'relname', 'testseq');
ERROR: cannot modify statistics for relation "testseq" ERROR: cannot modify statistics for relation "testseq"
DETAIL: This operation is not supported for sequences. DETAIL: This operation is not supported for sequences.
SELECT pg_catalog.pg_clear_relation_stats( SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testseq');
'stats_import.testseq'::regclass);
ERROR: cannot modify statistics for relation "testseq" ERROR: cannot modify statistics for relation "testseq"
DETAIL: This operation is not supported for sequences. DETAIL: This operation is not supported for sequences.
CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testview');
'relation', 'stats_import.testview'::regclass);
ERROR: cannot modify statistics for relation "testview"
DETAIL: This operation is not supported for views.
SELECT pg_catalog.pg_clear_relation_stats(
'stats_import.testview'::regclass);
ERROR: cannot modify statistics for relation "testview" ERROR: cannot modify statistics for relation "testview"
DETAIL: This operation is not supported for views. DETAIL: This operation is not supported for views.
-- --
-- attribute stats -- attribute stats
-- --
-- error: object does not exist -- error: schemaname missing
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', '0'::oid::regclass, 'relname', 'test',
'attname', 'id'::name, 'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
ERROR: could not open relation with OID 0 ERROR: "schemaname" cannot be NULL
-- error: relation null -- error: schema does not exist
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', NULL::oid::regclass, 'schemaname', 'nope',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
ERROR: "relation" cannot be NULL ERROR: schema "nope" does not exist
-- error: relname missing
SELECT pg_catalog.pg_restore_attribute_stats(
'schemaname', 'stats_import',
'attname', 'id',
'inherited', false::boolean,
'null_frac', 0.1::real);
ERROR: "relname" cannot be NULL
-- error: relname does not exist
SELECT pg_catalog.pg_restore_attribute_stats(
'schemaname', 'stats_import',
'relname', 'nope',
'attname', 'id',
'inherited', false::boolean,
'null_frac', 0.1::real);
ERROR: relation "stats_import.nope" does not exist
-- error: relname null
SELECT pg_catalog.pg_restore_attribute_stats(
'schemaname', 'stats_import',
'relname', NULL,
'attname', 'id',
'inherited', false::boolean,
'null_frac', 0.1::real);
ERROR: "relname" cannot be NULL
-- error: NULL attname -- error: NULL attname
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', NULL::name, 'relname', 'test',
'attname', NULL,
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
ERROR: must specify either attname or attnum ERROR: must specify either attname or attnum
-- error: attname doesn't exist -- error: attname doesn't exist
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'nope'::name, 'relname', 'test',
'attname', 'nope',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real, 'null_frac', 0.1::real,
'avg_width', 2::integer, 'avg_width', 2::integer,
@ -364,36 +410,41 @@ SELECT pg_catalog.pg_restore_attribute_stats(
ERROR: column "nope" of relation "test" does not exist ERROR: column "nope" of relation "test" does not exist
-- error: both attname and attnum -- error: both attname and attnum
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'attnum', 1::smallint, 'attnum', 1::smallint,
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
ERROR: cannot specify both attname and attnum ERROR: cannot specify both attname and attnum
-- error: neither attname nor attnum -- error: neither attname nor attnum
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
ERROR: must specify either attname or attnum ERROR: must specify either attname or attnum
-- error: attribute is system column -- error: attribute is system column
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'xmin'::name, 'relname', 'test',
'attname', 'xmin',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
ERROR: cannot modify statistics on system column "xmin" ERROR: cannot modify statistics on system column "xmin"
-- error: inherited null -- error: inherited null
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', NULL::boolean, 'inherited', NULL::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
ERROR: "inherited" cannot be NULL ERROR: "inherited" cannot be NULL
-- ok: just the fixed values, with version, no stakinds -- ok: just the fixed values, with version, no stakinds
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'version', 150000::integer, 'version', 150000::integer,
'null_frac', 0.2::real, 'null_frac', 0.2::real,
@ -421,7 +472,8 @@ AND attname = 'id';
-- for any stat-having relation. -- for any stat-having relation.
-- --
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'attnum', 1::smallint, 'attnum', 1::smallint,
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.4::real); 'null_frac', 0.4::real);
@ -443,8 +495,9 @@ AND attname = 'id';
-- warn: unrecognized argument name, rest get set -- warn: unrecognized argument name, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.2::real, 'null_frac', 0.2::real,
'nope', 0.5::real); 'nope', 0.5::real);
@ -467,8 +520,9 @@ AND attname = 'id';
-- warn: mcv / mcf null mismatch part 1, rest get set -- warn: mcv / mcf null mismatch part 1, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.21::real, 'null_frac', 0.21::real,
'most_common_freqs', '{0.1,0.2,0.3}'::real[] 'most_common_freqs', '{0.1,0.2,0.3}'::real[]
@ -492,8 +546,9 @@ AND attname = 'id';
-- warn: mcv / mcf null mismatch part 2, rest get set -- warn: mcv / mcf null mismatch part 2, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.21::real, 'null_frac', 0.21::real,
'most_common_vals', '{1,2,3}'::text 'most_common_vals', '{1,2,3}'::text
@ -517,8 +572,9 @@ AND attname = 'id';
-- warn: mcf type mismatch, mcv-pair fails, rest get set -- warn: mcf type mismatch, mcv-pair fails, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.22::real, 'null_frac', 0.22::real,
'most_common_vals', '{2,1,3}'::text, 'most_common_vals', '{2,1,3}'::text,
@ -544,8 +600,9 @@ AND attname = 'id';
-- warn: mcv cast failure, mcv-pair fails, rest get set -- warn: mcv cast failure, mcv-pair fails, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.23::real, 'null_frac', 0.23::real,
'most_common_vals', '{2,four,3}'::text, 'most_common_vals', '{2,four,3}'::text,
@ -570,8 +627,9 @@ AND attname = 'id';
-- ok: mcv+mcf -- ok: mcv+mcf
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'most_common_vals', '{2,1,3}'::text, 'most_common_vals', '{2,1,3}'::text,
'most_common_freqs', '{0.3,0.25,0.05}'::real[] 'most_common_freqs', '{0.3,0.25,0.05}'::real[]
@ -594,8 +652,9 @@ AND attname = 'id';
-- warn: NULL in histogram array, rest get set -- warn: NULL in histogram array, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.24::real, 'null_frac', 0.24::real,
'histogram_bounds', '{1,NULL,3,4}'::text 'histogram_bounds', '{1,NULL,3,4}'::text
@ -619,8 +678,9 @@ AND attname = 'id';
-- ok: histogram_bounds -- ok: histogram_bounds
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'histogram_bounds', '{1,2,3,4}'::text 'histogram_bounds', '{1,2,3,4}'::text
); );
@ -642,8 +702,9 @@ AND attname = 'id';
-- warn: elem_count_histogram null element, rest get set -- warn: elem_count_histogram null element, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.25::real, 'null_frac', 0.25::real,
'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[] 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[]
@ -667,8 +728,9 @@ AND attname = 'tags';
-- ok: elem_count_histogram -- ok: elem_count_histogram
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.26::real, 'null_frac', 0.26::real,
'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
@ -691,8 +753,9 @@ AND attname = 'tags';
-- warn: range stats on a scalar type, rest ok -- warn: range stats on a scalar type, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.27::real, 'null_frac', 0.27::real,
'range_empty_frac', 0.5::real, 'range_empty_frac', 0.5::real,
@ -718,8 +781,9 @@ AND attname = 'id';
-- warn: range_empty_frac range_length_hist null mismatch, rest ok -- warn: range_empty_frac range_length_hist null mismatch, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.28::real, 'null_frac', 0.28::real,
'range_length_histogram', '{399,499,Infinity}'::text 'range_length_histogram', '{399,499,Infinity}'::text
@ -743,8 +807,9 @@ AND attname = 'arange';
-- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.29::real, 'null_frac', 0.29::real,
'range_empty_frac', 0.5::real 'range_empty_frac', 0.5::real
@ -768,8 +833,9 @@ AND attname = 'arange';
-- ok: range_empty_frac + range_length_hist -- ok: range_empty_frac + range_length_hist
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'range_empty_frac', 0.5::real, 'range_empty_frac', 0.5::real,
'range_length_histogram', '{399,499,Infinity}'::text 'range_length_histogram', '{399,499,Infinity}'::text
@ -792,8 +858,9 @@ AND attname = 'arange';
-- warn: range bounds histogram on scalar, rest ok -- warn: range bounds histogram on scalar, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.31::real, 'null_frac', 0.31::real,
'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
@ -818,8 +885,9 @@ AND attname = 'id';
-- ok: range_bounds_histogram -- ok: range_bounds_histogram
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
); );
@ -841,8 +909,9 @@ AND attname = 'arange';
-- warn: cannot set most_common_elems for range type, rest ok -- warn: cannot set most_common_elems for range type, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.32::real, 'null_frac', 0.32::real,
'most_common_elems', '{3,1}'::text, 'most_common_elems', '{3,1}'::text,
@ -868,8 +937,9 @@ AND attname = 'arange';
-- warn: scalars can't have mcelem, rest ok -- warn: scalars can't have mcelem, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.33::real, 'null_frac', 0.33::real,
'most_common_elems', '{1,3}'::text, 'most_common_elems', '{1,3}'::text,
@ -895,8 +965,9 @@ AND attname = 'id';
-- warn: mcelem / mcelem mismatch, rest ok -- warn: mcelem / mcelem mismatch, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.34::real, 'null_frac', 0.34::real,
'most_common_elems', '{one,two}'::text 'most_common_elems', '{one,two}'::text
@ -920,8 +991,9 @@ AND attname = 'tags';
-- warn: mcelem / mcelem null mismatch part 2, rest ok -- warn: mcelem / mcelem null mismatch part 2, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.35::real, 'null_frac', 0.35::real,
'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[] 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
@ -945,8 +1017,9 @@ AND attname = 'tags';
-- ok: mcelem -- ok: mcelem
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'most_common_elems', '{one,three}'::text, 'most_common_elems', '{one,three}'::text,
'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
@ -969,8 +1042,9 @@ AND attname = 'tags';
-- warn: scalars can't have elem_count_histogram, rest ok -- warn: scalars can't have elem_count_histogram, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.36::real, 'null_frac', 0.36::real,
'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[] 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[]
@ -1022,8 +1096,9 @@ SELECT s.schemaname, s.tablename, s.attname, s.inherited, r.*
FROM pg_catalog.pg_stats AS s FROM pg_catalog.pg_stats AS s
CROSS JOIN LATERAL CROSS JOIN LATERAL
pg_catalog.pg_restore_attribute_stats( pg_catalog.pg_restore_attribute_stats(
'relation', ('stats_import.' || s.tablename || '_clone')::regclass, 'schemaname', 'stats_import',
'attname', s.attname, 'relname', s.tablename::text || '_clone',
'attname', s.attname::text,
'inherited', s.inherited, 'inherited', s.inherited,
'version', 150000, 'version', 150000,
'null_frac', s.null_frac, 'null_frac', s.null_frac,
@ -1200,9 +1275,10 @@ AND attname = 'arange';
(1 row) (1 row)
SELECT pg_catalog.pg_clear_attribute_stats( SELECT pg_catalog.pg_clear_attribute_stats(
relation => 'stats_import.test'::regclass, schemaname => 'stats_import',
attname => 'arange'::name, relname => 'test',
inherited => false::boolean); attname => 'arange',
inherited => false);
pg_clear_attribute_stats pg_clear_attribute_stats
-------------------------- --------------------------
@ -1219,6 +1295,53 @@ AND attname = 'arange';
0 0
(1 row) (1 row)
-- temp tables
CREATE TEMP TABLE stats_temp(i int);
SELECT pg_restore_relation_stats(
'schemaname', 'pg_temp',
'relname', 'stats_temp',
'relpages', '-19'::integer,
'reltuples', 401::real,
'relallvisible', 5::integer,
'relallfrozen', 3::integer);
pg_restore_relation_stats
---------------------------
t
(1 row)
SELECT relname, relpages, reltuples, relallvisible, relallfrozen
FROM pg_class
WHERE oid = 'pg_temp.stats_temp'::regclass
ORDER BY relname;
relname | relpages | reltuples | relallvisible | relallfrozen
------------+----------+-----------+---------------+--------------
stats_temp | -19 | 401 | 5 | 3
(1 row)
SELECT pg_catalog.pg_restore_attribute_stats(
'schemaname', 'pg_temp',
'relname', 'stats_temp',
'attname', 'i',
'inherited', false::boolean,
'null_frac', 0.0123::real
);
pg_restore_attribute_stats
----------------------------
t
(1 row)
SELECT tablename, null_frac
FROM pg_stats
WHERE schemaname like 'pg_temp%'
AND tablename = 'stats_temp'
AND inherited = false
AND attname = 'i';
tablename | null_frac
------------+-----------
stats_temp | 0.0123
(1 row)
DROP TABLE stats_temp;
DROP SCHEMA stats_import CASCADE; DROP SCHEMA stats_import CASCADE;
NOTICE: drop cascades to 6 other objects NOTICE: drop cascades to 6 other objects
DETAIL: drop cascades to type stats_import.complex_type DETAIL: drop cascades to type stats_import.complex_type

View File

@ -17,7 +17,8 @@ CREATE TABLE stats_import.test(
SELECT SELECT
pg_catalog.pg_restore_relation_stats( pg_catalog.pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relpages', 18::integer, 'relpages', 18::integer,
'reltuples', 21::real, 'reltuples', 21::real,
'relallvisible', 24::integer, 'relallvisible', 24::integer,
@ -32,37 +33,52 @@ FROM pg_class
WHERE oid = 'stats_import.test'::regclass WHERE oid = 'stats_import.test'::regclass
ORDER BY relname; ORDER BY relname;
SELECT pg_clear_relation_stats('stats_import.test'::regclass); SELECT pg_clear_relation_stats('stats_import', 'test');
-- --
-- relstats tests -- relstats tests
-- --
--- error: relation is wrong type -- error: schemaname missing
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 0::oid, 'relname', 'test',
'relpages', 17::integer);
-- error: relname missing
SELECT pg_catalog.pg_restore_relation_stats(
'schemaname', 'stats_import',
'relpages', 17::integer);
--- error: schemaname is wrong type
SELECT pg_catalog.pg_restore_relation_stats(
'schemaname', 3.6::float,
'relname', 'test',
'relpages', 17::integer);
--- error: relname is wrong type
SELECT pg_catalog.pg_restore_relation_stats(
'schemaname', 'stats_import',
'relname', 0::oid,
'relpages', 17::integer); 'relpages', 17::integer);
-- error: relation not found -- error: relation not found
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 0::oid::regclass, 'schemaname', 'stats_import',
'relname', 'nope',
'relpages', 17::integer); 'relpages', 17::integer);
-- error: odd number of variadic arguments cannot be pairs -- error: odd number of variadic arguments cannot be pairs
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relallvisible'); 'relallvisible');
-- error: argument name is NULL -- error: argument name is NULL
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
NULL, '17'::integer); NULL, '17'::integer);
-- error: argument name is not a text type
SELECT pg_restore_relation_stats(
'relation', '0'::oid::regclass,
17, '17'::integer);
-- starting stats -- starting stats
SELECT relpages, reltuples, relallvisible, relallfrozen SELECT relpages, reltuples, relallvisible, relallfrozen
FROM pg_class FROM pg_class
@ -71,7 +87,8 @@ WHERE oid = 'stats_import.test_i'::regclass;
-- regular indexes have special case locking rules -- regular indexes have special case locking rules
BEGIN; BEGIN;
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 'stats_import.test_i'::regclass, 'schemaname', 'stats_import',
'relname', 'test_i',
'relpages', 18::integer); 'relpages', 18::integer);
SELECT mode FROM pg_locks SELECT mode FROM pg_locks
@ -108,7 +125,8 @@ WHERE oid = 'stats_import.part_parent'::regclass;
BEGIN; BEGIN;
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 'stats_import.part_parent_i'::regclass, 'schemaname', 'stats_import',
'relname', 'part_parent_i',
'relpages', 2::integer); 'relpages', 2::integer);
SELECT mode FROM pg_locks SELECT mode FROM pg_locks
@ -127,7 +145,8 @@ WHERE oid = 'stats_import.part_parent_i'::regclass;
-- ok: set all relstats, with version, no bounds checking -- ok: set all relstats, with version, no bounds checking
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'version', 150000::integer, 'version', 150000::integer,
'relpages', '-17'::integer, 'relpages', '-17'::integer,
'reltuples', 400::real, 'reltuples', 400::real,
@ -140,7 +159,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- ok: set just relpages, rest stay same -- ok: set just relpages, rest stay same
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relpages', '16'::integer); 'relpages', '16'::integer);
SELECT relpages, reltuples, relallvisible, relallfrozen SELECT relpages, reltuples, relallvisible, relallfrozen
@ -149,7 +169,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- ok: set just reltuples, rest stay same -- ok: set just reltuples, rest stay same
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'reltuples', '500'::real); 'reltuples', '500'::real);
SELECT relpages, reltuples, relallvisible, relallfrozen SELECT relpages, reltuples, relallvisible, relallfrozen
@ -158,7 +179,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- ok: set just relallvisible, rest stay same -- ok: set just relallvisible, rest stay same
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relallvisible', 5::integer); 'relallvisible', 5::integer);
SELECT relpages, reltuples, relallvisible, relallfrozen SELECT relpages, reltuples, relallvisible, relallfrozen
@ -167,7 +189,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- ok: just relallfrozen -- ok: just relallfrozen
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'version', 150000::integer, 'version', 150000::integer,
'relallfrozen', 3::integer); 'relallfrozen', 3::integer);
@ -177,7 +200,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- warn: bad relpages type, rest updated -- warn: bad relpages type, rest updated
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relpages', 'nope'::text, 'relpages', 'nope'::text,
'reltuples', 400.0::real, 'reltuples', 400.0::real,
'relallvisible', 4::integer, 'relallvisible', 4::integer,
@ -189,7 +213,8 @@ WHERE oid = 'stats_import.test'::regclass;
-- unrecognized argument name, rest ok -- unrecognized argument name, rest ok
SELECT pg_restore_relation_stats( SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'relpages', '171'::integer, 'relpages', '171'::integer,
'nope', 10::integer); 'nope', 10::integer);
@ -198,8 +223,7 @@ FROM pg_class
WHERE oid = 'stats_import.test'::regclass; WHERE oid = 'stats_import.test'::regclass;
-- ok: clear stats -- ok: clear stats
SELECT pg_catalog.pg_clear_relation_stats( SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'test');
relation => 'stats_import.test'::regclass);
SELECT relpages, reltuples, relallvisible SELECT relpages, reltuples, relallvisible
FROM pg_class FROM pg_class
@ -209,48 +233,70 @@ WHERE oid = 'stats_import.test'::regclass;
CREATE SEQUENCE stats_import.testseq; CREATE SEQUENCE stats_import.testseq;
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_restore_relation_stats(
'relation', 'stats_import.testseq'::regclass); 'schemaname', 'stats_import',
'relname', 'testseq');
SELECT pg_catalog.pg_clear_relation_stats( SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testseq');
'stats_import.testseq'::regclass);
CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
SELECT pg_catalog.pg_restore_relation_stats( SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testview');
'relation', 'stats_import.testview'::regclass);
SELECT pg_catalog.pg_clear_relation_stats(
'stats_import.testview'::regclass);
-- --
-- attribute stats -- attribute stats
-- --
-- error: object does not exist -- error: schemaname missing
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', '0'::oid::regclass, 'relname', 'test',
'attname', 'id'::name, 'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
-- error: relation null -- error: schema does not exist
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', NULL::oid::regclass, 'schemaname', 'nope',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean,
'null_frac', 0.1::real);
-- error: relname missing
SELECT pg_catalog.pg_restore_attribute_stats(
'schemaname', 'stats_import',
'attname', 'id',
'inherited', false::boolean,
'null_frac', 0.1::real);
-- error: relname does not exist
SELECT pg_catalog.pg_restore_attribute_stats(
'schemaname', 'stats_import',
'relname', 'nope',
'attname', 'id',
'inherited', false::boolean,
'null_frac', 0.1::real);
-- error: relname null
SELECT pg_catalog.pg_restore_attribute_stats(
'schemaname', 'stats_import',
'relname', NULL,
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
-- error: NULL attname -- error: NULL attname
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', NULL::name, 'relname', 'test',
'attname', NULL,
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
-- error: attname doesn't exist -- error: attname doesn't exist
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'nope'::name, 'relname', 'test',
'attname', 'nope',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real, 'null_frac', 0.1::real,
'avg_width', 2::integer, 'avg_width', 2::integer,
@ -258,36 +304,41 @@ SELECT pg_catalog.pg_restore_attribute_stats(
-- error: both attname and attnum -- error: both attname and attnum
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'attnum', 1::smallint, 'attnum', 1::smallint,
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
-- error: neither attname nor attnum -- error: neither attname nor attnum
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
-- error: attribute is system column -- error: attribute is system column
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'xmin'::name, 'relname', 'test',
'attname', 'xmin',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
-- error: inherited null -- error: inherited null
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', NULL::boolean, 'inherited', NULL::boolean,
'null_frac', 0.1::real); 'null_frac', 0.1::real);
-- ok: just the fixed values, with version, no stakinds -- ok: just the fixed values, with version, no stakinds
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'version', 150000::integer, 'version', 150000::integer,
'null_frac', 0.2::real, 'null_frac', 0.2::real,
@ -307,7 +358,8 @@ AND attname = 'id';
-- for any stat-having relation. -- for any stat-having relation.
-- --
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'relname', 'test',
'attnum', 1::smallint, 'attnum', 1::smallint,
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.4::real); 'null_frac', 0.4::real);
@ -321,8 +373,9 @@ AND attname = 'id';
-- warn: unrecognized argument name, rest get set -- warn: unrecognized argument name, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.2::real, 'null_frac', 0.2::real,
'nope', 0.5::real); 'nope', 0.5::real);
@ -336,8 +389,9 @@ AND attname = 'id';
-- warn: mcv / mcf null mismatch part 1, rest get set -- warn: mcv / mcf null mismatch part 1, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.21::real, 'null_frac', 0.21::real,
'most_common_freqs', '{0.1,0.2,0.3}'::real[] 'most_common_freqs', '{0.1,0.2,0.3}'::real[]
@ -352,8 +406,9 @@ AND attname = 'id';
-- warn: mcv / mcf null mismatch part 2, rest get set -- warn: mcv / mcf null mismatch part 2, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.21::real, 'null_frac', 0.21::real,
'most_common_vals', '{1,2,3}'::text 'most_common_vals', '{1,2,3}'::text
@ -368,8 +423,9 @@ AND attname = 'id';
-- warn: mcf type mismatch, mcv-pair fails, rest get set -- warn: mcf type mismatch, mcv-pair fails, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.22::real, 'null_frac', 0.22::real,
'most_common_vals', '{2,1,3}'::text, 'most_common_vals', '{2,1,3}'::text,
@ -385,8 +441,9 @@ AND attname = 'id';
-- warn: mcv cast failure, mcv-pair fails, rest get set -- warn: mcv cast failure, mcv-pair fails, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.23::real, 'null_frac', 0.23::real,
'most_common_vals', '{2,four,3}'::text, 'most_common_vals', '{2,four,3}'::text,
@ -402,8 +459,9 @@ AND attname = 'id';
-- ok: mcv+mcf -- ok: mcv+mcf
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'most_common_vals', '{2,1,3}'::text, 'most_common_vals', '{2,1,3}'::text,
'most_common_freqs', '{0.3,0.25,0.05}'::real[] 'most_common_freqs', '{0.3,0.25,0.05}'::real[]
@ -418,8 +476,9 @@ AND attname = 'id';
-- warn: NULL in histogram array, rest get set -- warn: NULL in histogram array, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.24::real, 'null_frac', 0.24::real,
'histogram_bounds', '{1,NULL,3,4}'::text 'histogram_bounds', '{1,NULL,3,4}'::text
@ -434,8 +493,9 @@ AND attname = 'id';
-- ok: histogram_bounds -- ok: histogram_bounds
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'histogram_bounds', '{1,2,3,4}'::text 'histogram_bounds', '{1,2,3,4}'::text
); );
@ -449,8 +509,9 @@ AND attname = 'id';
-- warn: elem_count_histogram null element, rest get set -- warn: elem_count_histogram null element, rest get set
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.25::real, 'null_frac', 0.25::real,
'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[] 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[]
@ -465,8 +526,9 @@ AND attname = 'tags';
-- ok: elem_count_histogram -- ok: elem_count_histogram
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.26::real, 'null_frac', 0.26::real,
'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
@ -481,8 +543,9 @@ AND attname = 'tags';
-- warn: range stats on a scalar type, rest ok -- warn: range stats on a scalar type, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.27::real, 'null_frac', 0.27::real,
'range_empty_frac', 0.5::real, 'range_empty_frac', 0.5::real,
@ -498,8 +561,9 @@ AND attname = 'id';
-- warn: range_empty_frac range_length_hist null mismatch, rest ok -- warn: range_empty_frac range_length_hist null mismatch, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.28::real, 'null_frac', 0.28::real,
'range_length_histogram', '{399,499,Infinity}'::text 'range_length_histogram', '{399,499,Infinity}'::text
@ -514,8 +578,9 @@ AND attname = 'arange';
-- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.29::real, 'null_frac', 0.29::real,
'range_empty_frac', 0.5::real 'range_empty_frac', 0.5::real
@ -530,8 +595,9 @@ AND attname = 'arange';
-- ok: range_empty_frac + range_length_hist -- ok: range_empty_frac + range_length_hist
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'range_empty_frac', 0.5::real, 'range_empty_frac', 0.5::real,
'range_length_histogram', '{399,499,Infinity}'::text 'range_length_histogram', '{399,499,Infinity}'::text
@ -546,8 +612,9 @@ AND attname = 'arange';
-- warn: range bounds histogram on scalar, rest ok -- warn: range bounds histogram on scalar, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.31::real, 'null_frac', 0.31::real,
'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
@ -562,8 +629,9 @@ AND attname = 'id';
-- ok: range_bounds_histogram -- ok: range_bounds_histogram
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
); );
@ -577,8 +645,9 @@ AND attname = 'arange';
-- warn: cannot set most_common_elems for range type, rest ok -- warn: cannot set most_common_elems for range type, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'arange'::name, 'relname', 'test',
'attname', 'arange',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.32::real, 'null_frac', 0.32::real,
'most_common_elems', '{3,1}'::text, 'most_common_elems', '{3,1}'::text,
@ -594,8 +663,9 @@ AND attname = 'arange';
-- warn: scalars can't have mcelem, rest ok -- warn: scalars can't have mcelem, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.33::real, 'null_frac', 0.33::real,
'most_common_elems', '{1,3}'::text, 'most_common_elems', '{1,3}'::text,
@ -611,8 +681,9 @@ AND attname = 'id';
-- warn: mcelem / mcelem mismatch, rest ok -- warn: mcelem / mcelem mismatch, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.34::real, 'null_frac', 0.34::real,
'most_common_elems', '{one,two}'::text 'most_common_elems', '{one,two}'::text
@ -627,8 +698,9 @@ AND attname = 'tags';
-- warn: mcelem / mcelem null mismatch part 2, rest ok -- warn: mcelem / mcelem null mismatch part 2, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.35::real, 'null_frac', 0.35::real,
'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[] 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
@ -643,8 +715,9 @@ AND attname = 'tags';
-- ok: mcelem -- ok: mcelem
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'tags'::name, 'relname', 'test',
'attname', 'tags',
'inherited', false::boolean, 'inherited', false::boolean,
'most_common_elems', '{one,three}'::text, 'most_common_elems', '{one,three}'::text,
'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
@ -659,8 +732,9 @@ AND attname = 'tags';
-- warn: scalars can't have elem_count_histogram, rest ok -- warn: scalars can't have elem_count_histogram, rest ok
SELECT pg_catalog.pg_restore_attribute_stats( SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass, 'schemaname', 'stats_import',
'attname', 'id'::name, 'relname', 'test',
'attname', 'id',
'inherited', false::boolean, 'inherited', false::boolean,
'null_frac', 0.36::real, 'null_frac', 0.36::real,
'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[] 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[]
@ -707,8 +781,9 @@ SELECT s.schemaname, s.tablename, s.attname, s.inherited, r.*
FROM pg_catalog.pg_stats AS s FROM pg_catalog.pg_stats AS s
CROSS JOIN LATERAL CROSS JOIN LATERAL
pg_catalog.pg_restore_attribute_stats( pg_catalog.pg_restore_attribute_stats(
'relation', ('stats_import.' || s.tablename || '_clone')::regclass, 'schemaname', 'stats_import',
'attname', s.attname, 'relname', s.tablename::text || '_clone',
'attname', s.attname::text,
'inherited', s.inherited, 'inherited', s.inherited,
'version', 150000, 'version', 150000,
'null_frac', s.null_frac, 'null_frac', s.null_frac,
@ -853,9 +928,10 @@ AND inherited = false
AND attname = 'arange'; AND attname = 'arange';
SELECT pg_catalog.pg_clear_attribute_stats( SELECT pg_catalog.pg_clear_attribute_stats(
relation => 'stats_import.test'::regclass, schemaname => 'stats_import',
attname => 'arange'::name, relname => 'test',
inherited => false::boolean); attname => 'arange',
inherited => false);
SELECT COUNT(*) SELECT COUNT(*)
FROM pg_stats FROM pg_stats
@ -864,4 +940,34 @@ AND tablename = 'test'
AND inherited = false AND inherited = false
AND attname = 'arange'; AND attname = 'arange';
-- temp tables
CREATE TEMP TABLE stats_temp(i int);
SELECT pg_restore_relation_stats(
'schemaname', 'pg_temp',
'relname', 'stats_temp',
'relpages', '-19'::integer,
'reltuples', 401::real,
'relallvisible', 5::integer,
'relallfrozen', 3::integer);
SELECT relname, relpages, reltuples, relallvisible, relallfrozen
FROM pg_class
WHERE oid = 'pg_temp.stats_temp'::regclass
ORDER BY relname;
SELECT pg_catalog.pg_restore_attribute_stats(
'schemaname', 'pg_temp',
'relname', 'stats_temp',
'attname', 'i',
'inherited', false::boolean,
'null_frac', 0.0123::real
);
SELECT tablename, null_frac
FROM pg_stats
WHERE schemaname like 'pg_temp%'
AND tablename = 'stats_temp'
AND inherited = false
AND attname = 'i';
DROP TABLE stats_temp;
DROP SCHEMA stats_import CASCADE; DROP SCHEMA stats_import CASCADE;