Remove redundant pg_set_*_stats() variants.

After commit f3dae2ae58, the primary purpose of separating the
pg_set_*_stats() from the pg_restore_*_stats() variants was
eliminated.

Leave pg_restore_relation_stats() and pg_restore_attribute_stats(),
which satisfy both purposes, and remove pg_set_relation_stats() and
pg_set_attribute_stats().

Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://postgr.es/m/1457469.1740419458@sss.pgh.pa.us
This commit is contained in:
Jeff Davis 2025-02-25 16:15:47 -08:00
parent ecbff4378b
commit a5cbdeb98a
10 changed files with 823 additions and 1973 deletions

View File

@ -30181,41 +30181,72 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<tbody>
<row>
<entry role="func_table_entry">
<para role="func_signature">
<indexterm>
<primary>pg_set_relation_stats</primary>
</indexterm>
<function>pg_set_relation_stats</function> (
<parameter>relation</parameter> <type>regclass</type>
<optional>, <parameter>relpages</parameter> <type>integer</type></optional>
<optional>, <parameter>reltuples</parameter> <type>real</type></optional>
<optional>, <parameter>relallvisible</parameter> <type>integer</type></optional> )
<returnvalue>void</returnvalue>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>pg_restore_relation_stats</primary>
</indexterm>
<function>pg_restore_relation_stats</function> (
<literal>VARIADIC</literal> <parameter>kwargs</parameter> <type>"any"</type> )
<returnvalue>boolean</returnvalue>
</para>
<para>
Updates table-level statistics. Ordinarily, these statistics are
collected automatically or updated as a part of <xref
linkend="sql-vacuum"/> or <xref linkend="sql-analyze"/>, so it's not
necessary to call this function. However, it is useful after a
restore to enable the optimizer to choose better plans if
<command>ANALYZE</command> has not been run yet.
</para>
<para>
Updates relation-level statistics for the given relation to the
specified values. The parameters correspond to columns in <link
linkend="catalog-pg-class"><structname>pg_class</structname></link>. Unspecified
or <literal>NULL</literal> values leave the setting unchanged.
The tracked statistics may change from version to version, so
arguments are passed as pairs of <replaceable>argname</replaceable>
and <replaceable>argvalue</replaceable> in the form:
<programlisting>
SELECT pg_restore_relation_stats(
'<replaceable>arg1name</replaceable>', '<replaceable>arg1value</replaceable>'::<replaceable>arg1type</replaceable>,
'<replaceable>arg2name</replaceable>', '<replaceable>arg2value</replaceable>'::<replaceable>arg2type</replaceable>,
'<replaceable>arg3name</replaceable>', '<replaceable>arg3value</replaceable>'::<replaceable>arg3type</replaceable>);
</programlisting>
</para>
<para>
Ordinarily, these statistics are collected automatically or updated
as a part of <xref linkend="sql-vacuum"/> or <xref
linkend="sql-analyze"/>, so it's not necessary to call this
function. However, it may be useful when testing the effects of
statistics on the planner to understand or anticipate plan changes.
For example, to set the <structname>relpages</structname> and
<structname>reltuples</structname> of the table
<structname>mytable</structname>:
<programlisting>
SELECT pg_restore_relation_stats(
'relation', 'mytable'::regclass,
'relpages', 173::integer,
'reltuples', 10000::real);
</programlisting>
</para>
<para>
The caller must have the <literal>MAINTAIN</literal> privilege on
the table or be the owner of the database.
The argument <literal>relation</literal> with a value of type
<type>regclass</type> is required, and specifies the table. Other
arguments are the names of statistics corresponding to certain
columns in <link
linkend="catalog-pg-class"><structname>pg_class</structname></link>.
The currently-supported relation statistics are
<literal>relpages</literal> with a value of type
<type>integer</type>, <literal>reltuples</literal> with a value of
type <type>real</type>, and <literal>relallvisible</literal> with a
value of type <type>integer</type>.
</para>
<para>
The value of <structfield>relpages</structfield> must be greater than
or equal to <literal>-1</literal>,
<structfield>reltuples</structfield> must be greater than or equal to
<literal>-1.0</literal>, and <structfield>relallvisible</structfield>
must be greater than or equal to <literal>0</literal>.
Additionally, this function supports argument name
<literal>version</literal> of type <type>integer</type>, which
specifies the version from which the statistics originated, improving
interpretation of statistics from older versions of
<productname>PostgreSQL</productname>.
</para>
<para>
Minor errors are reported as a <literal>WARNING</literal> and
ignored, and remaining statistics will still be restored. If all
specified statistics are successfully restored, return
<literal>true</literal>, otherwise <literal>false</literal>.
</para>
<para>
The caller must have the <literal>MAINTAIN</literal> privilege on the
table or be the owner of the database.
</para>
</entry>
</row>
@ -30234,8 +30265,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
table was newly created.
</para>
<para>
The caller must have the <literal>MAINTAIN</literal> privilege on
the table or be the owner of the database.
The caller must have the <literal>MAINTAIN</literal> privilege on the
table or be the owner of the database.
</para>
</entry>
</row>
@ -30243,42 +30274,61 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>pg_restore_relation_stats</primary>
<primary>pg_restore_attribute_stats</primary>
</indexterm>
<function>pg_restore_relation_stats</function> (
<function>pg_restore_attribute_stats</function> (
<literal>VARIADIC</literal> <parameter>kwargs</parameter> <type>"any"</type> )
<returnvalue>boolean</returnvalue>
</para>
<para>
Create or update column-level statistics. Ordinarily, these
statistics are collected automatically or updated as a part of <xref
linkend="sql-vacuum"/> or <xref linkend="sql-analyze"/>, so it's not
necessary to call this function. However, it is useful after a
restore to enable the optimizer to choose better plans if
<command>ANALYZE</command> has not been run yet.
</para>
<para>
Similar to <function>pg_set_relation_stats()</function>, but intended
for bulk restore of relation statistics. The tracked statistics may
change from version to version, so the primary purpose of this
function is to maintain a consistent function signature to avoid
errors when restoring statistics from previous versions.
The tracked statistics may change from version to version, so
arguments are passed as pairs of <replaceable>argname</replaceable>
and <replaceable>argvalue</replaceable> in the form:
<programlisting>
SELECT pg_restore_attribute_stats(
'<replaceable>arg1name</replaceable>', '<replaceable>arg1value</replaceable>'::<replaceable>arg1type</replaceable>,
'<replaceable>arg2name</replaceable>', '<replaceable>arg2value</replaceable>'::<replaceable>arg2type</replaceable>,
'<replaceable>arg3name</replaceable>', '<replaceable>arg3value</replaceable>'::<replaceable>arg3type</replaceable>);
</programlisting>
</para>
<para>
Arguments are passed as pairs of <replaceable>argname</replaceable>
and <replaceable>argvalue</replaceable>, where
<replaceable>argname</replaceable> corresponds to a named argument in
<function>pg_set_relation_stats()</function> and
<replaceable>argvalue</replaceable> is of the corresponding type.
For example, to set the <structname>avg_width</structname> and
<structname>null_frac</structname> for the attribute
<structname>col1</structname> of the table
<structname>mytable</structname>:
<programlisting>
SELECT pg_restore_attribute_stats(
'relation', 'mytable'::regclass,
'attname', 'col1'::name,
'inherited', false,
'avg_width', 125::integer,
'null_frac', 0.5::real);
</programlisting>
</para>
<para>
The required arguments are <literal>relation</literal> with a value
of type <type>regclass</type>, which specifies the table;
<literal>attname</literal> with a value of type <type>name</type>,
which specifies the column; and <literal>inherited</literal>, which
specifies whether the statistics includes values from child tables.
Other arguments are the names of statistics corresponding to columns
in <link
linkend="view-pg-stats"><structname>pg_stats</structname></link>.
</para>
<para>
Additionally, this function supports argument name
<literal>version</literal> of type <type>integer</type>, which
specifies the version from which the statistics originated, improving
interpretation of older statistics.
</para>
<para>
For example, to set the <structname>relpages</structname> and
<structname>reltuples</structname> of the table
<structname>mytable</structname>:
<programlisting>
SELECT pg_restore_relation_stats(
'relation', 'mytable'::regclass,
'relpages', 173::integer,
'reltuples', 10000::float4);
</programlisting>
interpretation of statistics from older versions of
<productname>PostgreSQL</productname>.
</para>
<para>
Minor errors are reported as a <literal>WARNING</literal> and
@ -30286,53 +30336,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
specified statistics are successfully restored, return
<literal>true</literal>, otherwise <literal>false</literal>.
</para>
</entry>
</row>
<row>
<entry role="func_table_entry">
<para role="func_signature">
<indexterm>
<primary>pg_set_attribute_stats</primary>
</indexterm>
<function>pg_set_attribute_stats</function> (
<parameter>relation</parameter> <type>regclass</type>,
<parameter>attname</parameter> <type>name</type>,
<parameter>inherited</parameter> <type>boolean</type>
<optional>, <parameter>null_frac</parameter> <type>real</type></optional>
<optional>, <parameter>avg_width</parameter> <type>integer</type></optional>
<optional>, <parameter>n_distinct</parameter> <type>real</type></optional>
<optional>, <parameter>most_common_vals</parameter> <type>text</type>, <parameter>most_common_freqs</parameter> <type>real[]</type> </optional>
<optional>, <parameter>histogram_bounds</parameter> <type>text</type> </optional>
<optional>, <parameter>correlation</parameter> <type>real</type> </optional>
<optional>, <parameter>most_common_elems</parameter> <type>text</type>, <parameter>most_common_elem_freqs</parameter> <type>real[]</type> </optional>
<optional>, <parameter>elem_count_histogram</parameter> <type>real[]</type> </optional>
<optional>, <parameter>range_length_histogram</parameter> <type>text</type> </optional>
<optional>, <parameter>range_empty_frac</parameter> <type>real</type> </optional>
<optional>, <parameter>range_bounds_histogram</parameter> <type>text</type> </optional> )
<returnvalue>void</returnvalue>
</para>
<para>
Creates or updates attribute-level statistics for the given relation
and attribute name to the specified values. The parameters correspond
to attributes of the same name found in the <link
linkend="view-pg-stats"><structname>pg_stats</structname></link>
view.
</para>
<para>
Optional parameters default to <literal>NULL</literal>, which leave
the corresponding statistic unchanged.
</para>
<para>
Ordinarily, these statistics are collected automatically or updated
as a part of <xref linkend="sql-vacuum"/> or <xref
linkend="sql-analyze"/>, so it's not necessary to call this
function. However, it may be useful when testing the effects of
statistics on the planner to understand or anticipate plan changes.
</para>
<para>
The caller must have the <literal>MAINTAIN</literal> privilege on
the table or be the owner of the database.
The caller must have the <literal>MAINTAIN</literal> privilege on the
table or be the owner of the database.
</para>
</entry>
</row>
@ -30350,8 +30356,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<returnvalue>void</returnvalue>
</para>
<para>
Clears table-level statistics for the given relation attribute, as
though the table was newly created.
Clears column-level statistics for the given relation and
attribute, as though the table was newly created.
</para>
<para>
The caller must have the <literal>MAINTAIN</literal> privilege on
@ -30359,58 +30365,6 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
</para>
</entry>
</row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>pg_restore_attribute_stats</primary>
</indexterm>
<function>pg_restore_attribute_stats</function> (
<literal>VARIADIC</literal> <parameter>kwargs</parameter> <type>"any"</type> )
<returnvalue>boolean</returnvalue>
</para>
<para>
Similar to <function>pg_set_attribute_stats()</function>, but
intended for bulk restore of attribute statistics. The tracked
statistics may change from version to version, so the primary purpose
of this function is to maintain a consistent function signature to
avoid errors when restoring statistics from previous versions.
</para>
<para>
Arguments are passed as pairs of <replaceable>argname</replaceable>
and <replaceable>argvalue</replaceable>, where
<replaceable>argname</replaceable> corresponds to a named argument in
<function>pg_set_attribute_stats()</function> and
<replaceable>argvalue</replaceable> is of the corresponding type.
</para>
<para>
Additionally, this function supports argument name
<literal>version</literal> of type <type>integer</type>, which
specifies the version from which the statistics originated, improving
interpretation of older statistics.
</para>
<para>
For example, to set the <structname>avg_width</structname> and
<structname>null_frac</structname> for the attribute
<structname>col1</structname> of the table
<structname>mytable</structname>:
<programlisting>
SELECT pg_restore_attribute_stats(
'relation', 'mytable'::regclass,
'attname', 'col1'::name,
'inherited', false,
'avg_width', 125::integer,
'null_frac', 0.5::real);
</programlisting>
</para>
<para>
Minor errors are reported as a <literal>WARNING</literal> and
ignored, and remaining statistics will still be restored. If all
specified statistics are successfully restored, return
<literal>true</literal>, otherwise <literal>false</literal>.
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -636,38 +636,6 @@ LANGUAGE INTERNAL
CALLED ON NULL INPUT VOLATILE PARALLEL SAFE
AS 'pg_stat_reset_slru';
CREATE OR REPLACE FUNCTION
pg_set_relation_stats(relation regclass,
relpages integer DEFAULT NULL,
reltuples real DEFAULT NULL,
relallvisible integer DEFAULT NULL)
RETURNS void
LANGUAGE INTERNAL
CALLED ON NULL INPUT VOLATILE
AS 'pg_set_relation_stats';
CREATE OR REPLACE FUNCTION
pg_set_attribute_stats(relation regclass,
attname name,
inherited bool,
null_frac real DEFAULT NULL,
avg_width integer DEFAULT NULL,
n_distinct real DEFAULT NULL,
most_common_vals text DEFAULT NULL,
most_common_freqs real[] DEFAULT NULL,
histogram_bounds text DEFAULT NULL,
correlation real DEFAULT NULL,
most_common_elems text DEFAULT NULL,
most_common_elem_freqs real[] DEFAULT NULL,
elem_count_histogram real[] DEFAULT NULL,
range_length_histogram text DEFAULT NULL,
range_empty_frac real DEFAULT NULL,
range_bounds_histogram text DEFAULT NULL)
RETURNS void
LANGUAGE INTERNAL
CALLED ON NULL INPUT VOLATILE
AS 'pg_set_attribute_stats';
--
-- The default permissions for functions mean that anyone can execute them.
-- A number of functions shouldn't be executable by just anyone, but rather

View File

@ -76,16 +76,16 @@ static struct StatsArgInfo attarginfo[] =
[NUM_ATTRIBUTE_STATS_ARGS] = {0}
};
static bool attribute_statistics_update(FunctionCallInfo fcinfo, int elevel);
static bool attribute_statistics_update(FunctionCallInfo fcinfo);
static Node *get_attr_expr(Relation rel, int attnum);
static void get_attr_stat_type(Oid reloid, AttrNumber attnum, int elevel,
static void get_attr_stat_type(Oid reloid, AttrNumber attnum,
Oid *atttypid, int32 *atttypmod,
char *atttyptype, Oid *atttypcoll,
Oid *eq_opr, Oid *lt_opr);
static bool get_elem_stat_type(Oid atttypid, char atttyptype, int elevel,
static bool get_elem_stat_type(Oid atttypid, char atttyptype,
Oid *elemtypid, Oid *elem_eq_opr);
static Datum text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d,
Oid typid, int32 typmod, int elevel, bool *ok);
Oid typid, int32 typmod, bool *ok);
static void set_stats_slot(Datum *values, bool *nulls, bool *replaces,
int16 stakind, Oid staop, Oid stacoll,
Datum stanumbers, bool stanumbers_isnull,
@ -109,11 +109,11 @@ static void init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited,
*
* Major errors, such as the table not existing, the attribute not existing,
* or a permissions failure are always reported at ERROR. Other errors, such
* as a conversion failure on one statistic kind, are reported at 'elevel',
* as a conversion failure on one statistic kind, are reported as a WARNING
* and other statistic kinds may still be updated.
*/
static bool
attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
attribute_statistics_update(FunctionCallInfo fcinfo)
{
Oid reloid;
Name attname;
@ -184,33 +184,29 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
inherited = PG_GETARG_BOOL(INHERITED_ARG);
/*
* Check argument sanity. If some arguments are unusable, emit at elevel
* Check argument sanity. If some arguments are unusable, emit a WARNING
* and set the corresponding argument to NULL in fcinfo.
*/
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_FREQS_ARG,
elevel))
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_FREQS_ARG))
{
do_mcv = false;
result = false;
}
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_ELEM_FREQS_ARG,
elevel))
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_ELEM_FREQS_ARG))
{
do_mcelem = false;
result = false;
}
if (!stats_check_arg_array(fcinfo, attarginfo, ELEM_COUNT_HISTOGRAM_ARG,
elevel))
if (!stats_check_arg_array(fcinfo, attarginfo, ELEM_COUNT_HISTOGRAM_ARG))
{
do_dechist = false;
result = false;
}
if (!stats_check_arg_pair(fcinfo, attarginfo,
MOST_COMMON_VALS_ARG, MOST_COMMON_FREQS_ARG,
elevel))
MOST_COMMON_VALS_ARG, MOST_COMMON_FREQS_ARG))
{
do_mcv = false;
result = false;
@ -218,7 +214,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
if (!stats_check_arg_pair(fcinfo, attarginfo,
MOST_COMMON_ELEMS_ARG,
MOST_COMMON_ELEM_FREQS_ARG, elevel))
MOST_COMMON_ELEM_FREQS_ARG))
{
do_mcelem = false;
result = false;
@ -226,14 +222,14 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
if (!stats_check_arg_pair(fcinfo, attarginfo,
RANGE_LENGTH_HISTOGRAM_ARG,
RANGE_EMPTY_FRAC_ARG, elevel))
RANGE_EMPTY_FRAC_ARG))
{
do_range_length_histogram = false;
result = false;
}
/* derive information from attribute */
get_attr_stat_type(reloid, attnum, elevel,
get_attr_stat_type(reloid, attnum,
&atttypid, &atttypmod,
&atttyptype, &atttypcoll,
&eq_opr, &lt_opr);
@ -241,10 +237,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
/* if needed, derive element type */
if (do_mcelem || do_dechist)
{
if (!get_elem_stat_type(atttypid, atttyptype, elevel,
if (!get_elem_stat_type(atttypid, atttyptype,
&elemtypid, &elem_eq_opr))
{
ereport(elevel,
ereport(WARNING,
(errmsg("unable to determine element type of attribute \"%s\"", NameStr(*attname)),
errdetail("Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.")));
elemtypid = InvalidOid;
@ -259,7 +255,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
/* histogram and correlation require less-than operator */
if ((do_histogram || do_correlation) && !OidIsValid(lt_opr))
{
ereport(elevel,
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("could not determine less-than operator for attribute \"%s\"", NameStr(*attname)),
errdetail("Cannot set STATISTIC_KIND_HISTOGRAM or STATISTIC_KIND_CORRELATION.")));
@ -273,7 +269,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
if ((do_range_length_histogram || do_bounds_histogram) &&
!(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
{
ereport(elevel,
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("attribute \"%s\" is not a range type", NameStr(*attname)),
errdetail("Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.")));
@ -322,7 +318,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
&array_in_fn,
PG_GETARG_DATUM(MOST_COMMON_VALS_ARG),
atttypid, atttypmod,
elevel, &converted);
&converted);
if (converted)
{
@ -344,7 +340,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
stavalues = text_to_stavalues("histogram_bounds",
&array_in_fn,
PG_GETARG_DATUM(HISTOGRAM_BOUNDS_ARG),
atttypid, atttypmod, elevel,
atttypid, atttypmod,
&converted);
if (converted)
@ -382,7 +378,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
&array_in_fn,
PG_GETARG_DATUM(MOST_COMMON_ELEMS_ARG),
elemtypid, atttypmod,
elevel, &converted);
&converted);
if (converted)
{
@ -422,7 +418,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
&array_in_fn,
PG_GETARG_DATUM(RANGE_BOUNDS_HISTOGRAM_ARG),
atttypid, atttypmod,
elevel, &converted);
&converted);
if (converted)
{
@ -449,7 +445,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
stavalues = text_to_stavalues("range_length_histogram",
&array_in_fn,
PG_GETARG_DATUM(RANGE_LENGTH_HISTOGRAM_ARG),
FLOAT8OID, 0, elevel, &converted);
FLOAT8OID, 0, &converted);
if (converted)
{
@ -517,7 +513,7 @@ get_attr_expr(Relation rel, int attnum)
* Derive type information from the attribute.
*/
static void
get_attr_stat_type(Oid reloid, AttrNumber attnum, int elevel,
get_attr_stat_type(Oid reloid, AttrNumber attnum,
Oid *atttypid, int32 *atttypmod,
char *atttyptype, Oid *atttypcoll,
Oid *eq_opr, Oid *lt_opr)
@ -599,7 +595,7 @@ get_attr_stat_type(Oid reloid, AttrNumber attnum, int elevel,
* Derive element type information from the attribute type.
*/
static bool
get_elem_stat_type(Oid atttypid, char atttyptype, int elevel,
get_elem_stat_type(Oid atttypid, char atttyptype,
Oid *elemtypid, Oid *elem_eq_opr)
{
TypeCacheEntry *elemtypcache;
@ -634,13 +630,13 @@ get_elem_stat_type(Oid atttypid, char atttyptype, int elevel,
/*
* Cast a text datum into an array with element type elemtypid.
*
* If an error is encountered, capture it and re-throw at elevel, and set ok
* to false. If the resulting array contains NULLs, raise an error at elevel
* and set ok to false. Otherwise, set ok to true.
* If an error is encountered, capture it and re-throw a WARNING, and set ok
* to false. If the resulting array contains NULLs, raise a WARNING and set ok
* to false. Otherwise, set ok to true.
*/
static Datum
text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid,
int32 typmod, int elevel, bool *ok)
int32 typmod, bool *ok)
{
LOCAL_FCINFO(fcinfo, 8);
char *s;
@ -667,8 +663,7 @@ text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid,
if (escontext.error_occurred)
{
if (elevel != ERROR)
escontext.error_data->elevel = elevel;
escontext.error_data->elevel = WARNING;
ThrowErrorData(escontext.error_data);
*ok = false;
return (Datum) 0;
@ -676,7 +671,7 @@ text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid,
if (array_contains_nulls(DatumGetArrayTypeP(result)))
{
ereport(elevel,
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" array cannot contain NULL values", staname)));
*ok = false;
@ -851,33 +846,6 @@ init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited,
}
}
/*
* Import statistics for a given relation attribute.
*
* Inserts or replaces a row in pg_statistic for the given relation and
* attribute name. It takes input parameters that correspond to columns in the
* view pg_stats.
*
* Parameters null_frac, avg_width, and n_distinct all correspond to NOT NULL
* columns in pg_statistic. The remaining parameters all belong to a specific
* stakind. Some stakinds require multiple parameters, which must be specified
* together (or neither specified).
*
* Parameters are only superficially validated. Omitting a parameter or
* passing NULL leaves the statistic unchanged.
*
* Parameters corresponding to ANYARRAY columns are instead passed in as text
* values, which is a valid input string for an array of the type or element
* type of the attribute. Any error generated by the array_in() function will
* in turn fail the function.
*/
Datum
pg_set_attribute_stats(PG_FUNCTION_ARGS)
{
attribute_statistics_update(fcinfo, ERROR);
PG_RETURN_VOID();
}
/*
* Delete statistics for the given attribute.
*/
@ -933,10 +901,10 @@ pg_restore_attribute_stats(PG_FUNCTION_ARGS)
InvalidOid, NULL, NULL);
if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
attarginfo, WARNING))
attarginfo))
result = false;
if (!attribute_statistics_update(positional_fcinfo, WARNING))
if (!attribute_statistics_update(positional_fcinfo))
result = false;
PG_RETURN_BOOL(result);

View File

@ -48,13 +48,13 @@ static struct StatsArgInfo relarginfo[] =
[NUM_RELATION_STATS_ARGS] = {0}
};
static bool relation_statistics_update(FunctionCallInfo fcinfo, int elevel);
static bool relation_statistics_update(FunctionCallInfo fcinfo);
/*
* Internal function for modifying statistics for a relation.
*/
static bool
relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
relation_statistics_update(FunctionCallInfo fcinfo)
{
bool result = true;
Oid reloid;
@ -83,7 +83,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
if (reltuples < -1.0)
{
ereport(elevel,
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("reltuples cannot be < -1.0")));
result = false;
@ -118,7 +118,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
ctup = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid));
if (!HeapTupleIsValid(ctup))
{
ereport(elevel,
ereport(WARNING,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("pg_class entry for relid %u not found", reloid)));
table_close(crel, RowExclusiveLock);
@ -169,16 +169,6 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
return result;
}
/*
* Set statistics for a given pg_class entry.
*/
Datum
pg_set_relation_stats(PG_FUNCTION_ARGS)
{
relation_statistics_update(fcinfo, ERROR);
PG_RETURN_VOID();
}
/*
* Clear statistics for a given pg_class entry; that is, set back to initial
* stats for a newly-created table.
@ -199,7 +189,7 @@ pg_clear_relation_stats(PG_FUNCTION_ARGS)
newfcinfo->args[3].value = UInt32GetDatum(0);
newfcinfo->args[3].isnull = false;
relation_statistics_update(newfcinfo, ERROR);
relation_statistics_update(newfcinfo);
PG_RETURN_VOID();
}
@ -214,10 +204,10 @@ pg_restore_relation_stats(PG_FUNCTION_ARGS)
InvalidOid, NULL, NULL);
if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
relarginfo, WARNING))
relarginfo))
result = false;
if (!relation_statistics_update(positional_fcinfo, WARNING))
if (!relation_statistics_update(positional_fcinfo))
result = false;
PG_RETURN_BOOL(result);

View File

@ -48,13 +48,13 @@ stats_check_required_arg(FunctionCallInfo fcinfo,
* Check that argument is either NULL or a one dimensional array with no
* NULLs.
*
* If a problem is found, emit at elevel, and return false. Otherwise return
* If a problem is found, emit a WARNING, and return false. Otherwise return
* true.
*/
bool
stats_check_arg_array(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo,
int argnum, int elevel)
int argnum)
{
ArrayType *arr;
@ -65,7 +65,7 @@ stats_check_arg_array(FunctionCallInfo fcinfo,
if (ARR_NDIM(arr) != 1)
{
ereport(elevel,
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" cannot be a multidimensional array",
arginfo[argnum].argname)));
@ -74,7 +74,7 @@ stats_check_arg_array(FunctionCallInfo fcinfo,
if (array_contains_nulls(arr))
{
ereport(elevel,
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" array cannot contain NULL values",
arginfo[argnum].argname)));
@ -89,13 +89,13 @@ stats_check_arg_array(FunctionCallInfo fcinfo,
* a particular stakind, such as most_common_vals and most_common_freqs for
* STATISTIC_KIND_MCV.
*
* If a problem is found, emit at elevel, and return false. Otherwise return
* If a problem is found, emit a WARNING, and return false. Otherwise return
* true.
*/
bool
stats_check_arg_pair(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo,
int argnum1, int argnum2, int elevel)
int argnum1, int argnum2)
{
if (PG_ARGISNULL(argnum1) && PG_ARGISNULL(argnum2))
return true;
@ -105,7 +105,7 @@ stats_check_arg_pair(FunctionCallInfo fcinfo,
int nullarg = PG_ARGISNULL(argnum1) ? argnum1 : argnum2;
int otherarg = PG_ARGISNULL(argnum1) ? argnum2 : argnum1;
ereport(elevel,
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" must be specified when \"%s\" is specified",
arginfo[nullarg].argname,
@ -216,7 +216,7 @@ stats_lock_check_privileges(Oid reloid)
* found.
*/
static int
get_arg_by_name(const char *argname, struct StatsArgInfo *arginfo, int elevel)
get_arg_by_name(const char *argname, struct StatsArgInfo *arginfo)
{
int argnum;
@ -224,7 +224,7 @@ get_arg_by_name(const char *argname, struct StatsArgInfo *arginfo, int elevel)
if (pg_strcasecmp(argname, arginfo[argnum].argname) == 0)
return argnum;
ereport(elevel,
ereport(WARNING,
(errmsg("unrecognized argument name: \"%s\"", argname)));
return -1;
@ -234,11 +234,11 @@ get_arg_by_name(const char *argname, struct StatsArgInfo *arginfo, int elevel)
* Ensure that a given argument matched the expected type.
*/
static bool
stats_check_arg_type(const char *argname, Oid argtype, Oid expectedtype, int elevel)
stats_check_arg_type(const char *argname, Oid argtype, Oid expectedtype)
{
if (argtype != expectedtype)
{
ereport(elevel,
ereport(WARNING,
(errmsg("argument \"%s\" has type \"%s\", expected type \"%s\"",
argname, format_type_be(argtype),
format_type_be(expectedtype))));
@ -260,8 +260,7 @@ stats_check_arg_type(const char *argname, Oid argtype, Oid expectedtype, int ele
bool
stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
FunctionCallInfo positional_fcinfo,
struct StatsArgInfo *arginfo,
int elevel)
struct StatsArgInfo *arginfo)
{
Datum *args;
bool *argnulls;
@ -319,11 +318,10 @@ stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
if (pg_strcasecmp(argname, "version") == 0)
continue;
argnum = get_arg_by_name(argname, arginfo, elevel);
argnum = get_arg_by_name(argname, arginfo);
if (argnum < 0 || !stats_check_arg_type(argname, types[i + 1],
arginfo[argnum].argtype,
elevel))
arginfo[argnum].argtype))
{
result = false;
continue;

View File

@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202502241
#define CATALOG_VERSION_NO 202502242
#endif

View File

@ -1,4 +1,4 @@
#----------------------------------------------------------------------
\#----------------------------------------------------------------------
#
# pg_proc.dat
# Initial contents of the pg_proc system catalog.
@ -12420,7 +12420,14 @@
proargnames => '{kwargs}',
proargmodes => '{v}',
prosrc => 'pg_restore_relation_stats' },
{ oid => '8460',
{ oid => '9160',
descr => 'clear statistics on relation',
proname => 'pg_clear_relation_stats', provolatile => 'v', proisstrict => 'f',
proparallel => 'u', prorettype => 'void',
proargtypes => 'regclass',
proargnames => '{relation}',
prosrc => 'pg_clear_relation_stats' },
{ oid => '8461',
descr => 'restore statistics on attribute',
proname => 'pg_restore_attribute_stats', provolatile => 'v', proisstrict => 'f',
provariadic => 'any',
@ -12430,33 +12437,12 @@
proargmodes => '{v}',
prosrc => 'pg_restore_attribute_stats' },
{ oid => '9162',
descr => 'set statistics on attribute',
proname => 'pg_set_attribute_stats', provolatile => 'v', proisstrict => 'f',
proparallel => 'u', prorettype => 'void',
proargtypes => 'regclass name bool float4 int4 float4 text _float4 text float4 text _float4 _float4 text float4 text',
proargnames => '{relation,attname,inherited,null_frac,avg_width,n_distinct,most_common_vals,most_common_freqs,histogram_bounds,correlation,most_common_elems,most_common_elem_freqs,elem_count_histogram,range_length_histogram,range_empty_frac,range_bounds_histogram}',
prosrc => 'pg_set_attribute_stats' },
{ oid => '9163',
descr => 'clear statistics on attribute',
proname => 'pg_clear_attribute_stats', provolatile => 'v', proisstrict => 'f',
proparallel => 'u', prorettype => 'void',
proargtypes => 'regclass name bool',
proargnames => '{relation,attname,inherited}',
prosrc => 'pg_clear_attribute_stats' },
{ oid => '9944',
descr => 'set statistics on relation',
proname => 'pg_set_relation_stats', provolatile => 'v', proisstrict => 'f',
proparallel => 'u', prorettype => 'void',
proargtypes => 'regclass int4 float4 int4',
proargnames => '{relation,relpages,reltuples,relallvisible}',
prosrc => 'pg_set_relation_stats' },
{ oid => '9945',
descr => 'clear statistics on relation',
proname => 'pg_clear_relation_stats', provolatile => 'v', proisstrict => 'f',
proparallel => 'u', prorettype => 'void',
proargtypes => 'regclass',
proargnames => '{relation}',
prosrc => 'pg_clear_relation_stats' },
# GiST stratnum implementations
{ oid => '8047', descr => 'GiST support',

View File

@ -25,17 +25,15 @@ extern void stats_check_required_arg(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo,
int argnum);
extern bool stats_check_arg_array(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo, int argnum,
int elevel);
struct StatsArgInfo *arginfo, int argnum);
extern bool stats_check_arg_pair(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo,
int argnum1, int argnum2, int elevel);
int argnum1, int argnum2);
extern void stats_lock_check_privileges(Oid reloid);
extern bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
FunctionCallInfo positional_fcinfo,
struct StatsArgInfo *arginfo,
int elevel);
struct StatsArgInfo *arginfo);
#endif /* STATS_UTILS_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff