mirror of
https://github.com/postgres/postgres.git
synced 2025-05-14 00:03:46 -04:00
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:
parent
ecbff4378b
commit
a5cbdeb98a
@ -30181,41 +30181,72 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
|
|||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry role="func_table_entry">
|
<entry role="func_table_entry"><para role="func_signature">
|
||||||
<para role="func_signature">
|
<indexterm>
|
||||||
<indexterm>
|
<primary>pg_restore_relation_stats</primary>
|
||||||
<primary>pg_set_relation_stats</primary>
|
</indexterm>
|
||||||
</indexterm>
|
<function>pg_restore_relation_stats</function> (
|
||||||
<function>pg_set_relation_stats</function> (
|
<literal>VARIADIC</literal> <parameter>kwargs</parameter> <type>"any"</type> )
|
||||||
<parameter>relation</parameter> <type>regclass</type>
|
<returnvalue>boolean</returnvalue>
|
||||||
<optional>, <parameter>relpages</parameter> <type>integer</type></optional>
|
</para>
|
||||||
<optional>, <parameter>reltuples</parameter> <type>real</type></optional>
|
<para>
|
||||||
<optional>, <parameter>relallvisible</parameter> <type>integer</type></optional> )
|
Updates table-level statistics. Ordinarily, these statistics are
|
||||||
<returnvalue>void</returnvalue>
|
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>
|
||||||
<para>
|
<para>
|
||||||
Updates relation-level statistics for the given relation to the
|
The tracked statistics may change from version to version, so
|
||||||
specified values. The parameters correspond to columns in <link
|
arguments are passed as pairs of <replaceable>argname</replaceable>
|
||||||
linkend="catalog-pg-class"><structname>pg_class</structname></link>. Unspecified
|
and <replaceable>argvalue</replaceable> in the form:
|
||||||
or <literal>NULL</literal> values leave the setting unchanged.
|
<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>
|
||||||
<para>
|
<para>
|
||||||
Ordinarily, these statistics are collected automatically or updated
|
For example, to set the <structname>relpages</structname> and
|
||||||
as a part of <xref linkend="sql-vacuum"/> or <xref
|
<structname>reltuples</structname> of the table
|
||||||
linkend="sql-analyze"/>, so it's not necessary to call this
|
<structname>mytable</structname>:
|
||||||
function. However, it may be useful when testing the effects of
|
<programlisting>
|
||||||
statistics on the planner to understand or anticipate plan changes.
|
SELECT pg_restore_relation_stats(
|
||||||
|
'relation', 'mytable'::regclass,
|
||||||
|
'relpages', 173::integer,
|
||||||
|
'reltuples', 10000::real);
|
||||||
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The caller must have the <literal>MAINTAIN</literal> privilege on
|
The argument <literal>relation</literal> with a value of type
|
||||||
the table or be the owner of the database.
|
<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>
|
||||||
<para>
|
<para>
|
||||||
The value of <structfield>relpages</structfield> must be greater than
|
Additionally, this function supports argument name
|
||||||
or equal to <literal>-1</literal>,
|
<literal>version</literal> of type <type>integer</type>, which
|
||||||
<structfield>reltuples</structfield> must be greater than or equal to
|
specifies the version from which the statistics originated, improving
|
||||||
<literal>-1.0</literal>, and <structfield>relallvisible</structfield>
|
interpretation of statistics from older versions of
|
||||||
must be greater than or equal to <literal>0</literal>.
|
<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>
|
</para>
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
@ -30234,8 +30265,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
|
|||||||
table was newly created.
|
table was newly created.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The caller must have the <literal>MAINTAIN</literal> privilege on
|
The caller must have the <literal>MAINTAIN</literal> privilege on the
|
||||||
the table or be the owner of the database.
|
table or be the owner of the database.
|
||||||
</para>
|
</para>
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
@ -30243,42 +30274,61 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
|
|||||||
<row>
|
<row>
|
||||||
<entry role="func_table_entry"><para role="func_signature">
|
<entry role="func_table_entry"><para role="func_signature">
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>pg_restore_relation_stats</primary>
|
<primary>pg_restore_attribute_stats</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
<function>pg_restore_relation_stats</function> (
|
<function>pg_restore_attribute_stats</function> (
|
||||||
<literal>VARIADIC</literal> <parameter>kwargs</parameter> <type>"any"</type> )
|
<literal>VARIADIC</literal> <parameter>kwargs</parameter> <type>"any"</type> )
|
||||||
<returnvalue>boolean</returnvalue>
|
<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>
|
||||||
<para>
|
<para>
|
||||||
Similar to <function>pg_set_relation_stats()</function>, but intended
|
The tracked statistics may change from version to version, so
|
||||||
for bulk restore of relation statistics. The tracked statistics may
|
arguments are passed as pairs of <replaceable>argname</replaceable>
|
||||||
change from version to version, so the primary purpose of this
|
and <replaceable>argvalue</replaceable> in the form:
|
||||||
function is to maintain a consistent function signature to avoid
|
<programlisting>
|
||||||
errors when restoring statistics from previous versions.
|
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>
|
||||||
<para>
|
<para>
|
||||||
Arguments are passed as pairs of <replaceable>argname</replaceable>
|
For example, to set the <structname>avg_width</structname> and
|
||||||
and <replaceable>argvalue</replaceable>, where
|
<structname>null_frac</structname> for the attribute
|
||||||
<replaceable>argname</replaceable> corresponds to a named argument in
|
<structname>col1</structname> of the table
|
||||||
<function>pg_set_relation_stats()</function> and
|
<structname>mytable</structname>:
|
||||||
<replaceable>argvalue</replaceable> is of the corresponding type.
|
<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>
|
||||||
<para>
|
<para>
|
||||||
Additionally, this function supports argument name
|
Additionally, this function supports argument name
|
||||||
<literal>version</literal> of type <type>integer</type>, which
|
<literal>version</literal> of type <type>integer</type>, which
|
||||||
specifies the version from which the statistics originated, improving
|
specifies the version from which the statistics originated, improving
|
||||||
interpretation of older statistics.
|
interpretation of statistics from older versions of
|
||||||
</para>
|
<productname>PostgreSQL</productname>.
|
||||||
<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>
|
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Minor errors are reported as a <literal>WARNING</literal> and
|
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
|
specified statistics are successfully restored, return
|
||||||
<literal>true</literal>, otherwise <literal>false</literal>.
|
<literal>true</literal>, otherwise <literal>false</literal>.
|
||||||
</para>
|
</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>
|
<para>
|
||||||
Creates or updates attribute-level statistics for the given relation
|
The caller must have the <literal>MAINTAIN</literal> privilege on the
|
||||||
and attribute name to the specified values. The parameters correspond
|
table or be the owner of the database.
|
||||||
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.
|
|
||||||
</para>
|
</para>
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
@ -30350,8 +30356,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
|
|||||||
<returnvalue>void</returnvalue>
|
<returnvalue>void</returnvalue>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Clears table-level statistics for the given relation attribute, as
|
Clears column-level statistics for the given relation and
|
||||||
though the table was newly created.
|
attribute, as though the table was newly created.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The caller must have the <literal>MAINTAIN</literal> privilege on
|
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>
|
</para>
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</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>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
@ -636,38 +636,6 @@ LANGUAGE INTERNAL
|
|||||||
CALLED ON NULL INPUT VOLATILE PARALLEL SAFE
|
CALLED ON NULL INPUT VOLATILE PARALLEL SAFE
|
||||||
AS 'pg_stat_reset_slru';
|
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.
|
-- The default permissions for functions mean that anyone can execute them.
|
||||||
-- A number of functions shouldn't be executable by just anyone, but rather
|
-- A number of functions shouldn't be executable by just anyone, but rather
|
||||||
|
@ -76,16 +76,16 @@ static struct StatsArgInfo attarginfo[] =
|
|||||||
[NUM_ATTRIBUTE_STATS_ARGS] = {0}
|
[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 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,
|
Oid *atttypid, int32 *atttypmod,
|
||||||
char *atttyptype, Oid *atttypcoll,
|
char *atttyptype, Oid *atttypcoll,
|
||||||
Oid *eq_opr, Oid *lt_opr);
|
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);
|
Oid *elemtypid, Oid *elem_eq_opr);
|
||||||
static Datum text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d,
|
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,
|
static void set_stats_slot(Datum *values, bool *nulls, bool *replaces,
|
||||||
int16 stakind, Oid staop, Oid stacoll,
|
int16 stakind, Oid staop, Oid stacoll,
|
||||||
Datum stanumbers, bool stanumbers_isnull,
|
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,
|
* Major errors, such as the table not existing, the attribute not existing,
|
||||||
* or a permissions failure are always reported at ERROR. Other errors, such
|
* 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.
|
* and other statistic kinds may still be updated.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
attribute_statistics_update(FunctionCallInfo fcinfo)
|
||||||
{
|
{
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
Name attname;
|
Name attname;
|
||||||
@ -184,33 +184,29 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
inherited = PG_GETARG_BOOL(INHERITED_ARG);
|
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.
|
* and set the corresponding argument to NULL in fcinfo.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_FREQS_ARG,
|
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_FREQS_ARG))
|
||||||
elevel))
|
|
||||||
{
|
{
|
||||||
do_mcv = false;
|
do_mcv = false;
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_ELEM_FREQS_ARG,
|
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_ELEM_FREQS_ARG))
|
||||||
elevel))
|
|
||||||
{
|
{
|
||||||
do_mcelem = false;
|
do_mcelem = false;
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
if (!stats_check_arg_array(fcinfo, attarginfo, ELEM_COUNT_HISTOGRAM_ARG,
|
if (!stats_check_arg_array(fcinfo, attarginfo, ELEM_COUNT_HISTOGRAM_ARG))
|
||||||
elevel))
|
|
||||||
{
|
{
|
||||||
do_dechist = false;
|
do_dechist = false;
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stats_check_arg_pair(fcinfo, attarginfo,
|
if (!stats_check_arg_pair(fcinfo, attarginfo,
|
||||||
MOST_COMMON_VALS_ARG, MOST_COMMON_FREQS_ARG,
|
MOST_COMMON_VALS_ARG, MOST_COMMON_FREQS_ARG))
|
||||||
elevel))
|
|
||||||
{
|
{
|
||||||
do_mcv = false;
|
do_mcv = false;
|
||||||
result = false;
|
result = false;
|
||||||
@ -218,7 +214,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
|
|
||||||
if (!stats_check_arg_pair(fcinfo, attarginfo,
|
if (!stats_check_arg_pair(fcinfo, attarginfo,
|
||||||
MOST_COMMON_ELEMS_ARG,
|
MOST_COMMON_ELEMS_ARG,
|
||||||
MOST_COMMON_ELEM_FREQS_ARG, elevel))
|
MOST_COMMON_ELEM_FREQS_ARG))
|
||||||
{
|
{
|
||||||
do_mcelem = false;
|
do_mcelem = false;
|
||||||
result = false;
|
result = false;
|
||||||
@ -226,14 +222,14 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
|
|
||||||
if (!stats_check_arg_pair(fcinfo, attarginfo,
|
if (!stats_check_arg_pair(fcinfo, attarginfo,
|
||||||
RANGE_LENGTH_HISTOGRAM_ARG,
|
RANGE_LENGTH_HISTOGRAM_ARG,
|
||||||
RANGE_EMPTY_FRAC_ARG, elevel))
|
RANGE_EMPTY_FRAC_ARG))
|
||||||
{
|
{
|
||||||
do_range_length_histogram = false;
|
do_range_length_histogram = false;
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* derive information from attribute */
|
/* derive information from attribute */
|
||||||
get_attr_stat_type(reloid, attnum, elevel,
|
get_attr_stat_type(reloid, attnum,
|
||||||
&atttypid, &atttypmod,
|
&atttypid, &atttypmod,
|
||||||
&atttyptype, &atttypcoll,
|
&atttyptype, &atttypcoll,
|
||||||
&eq_opr, <_opr);
|
&eq_opr, <_opr);
|
||||||
@ -241,10 +237,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
/* if needed, derive element type */
|
/* if needed, derive element type */
|
||||||
if (do_mcelem || do_dechist)
|
if (do_mcelem || do_dechist)
|
||||||
{
|
{
|
||||||
if (!get_elem_stat_type(atttypid, atttyptype, elevel,
|
if (!get_elem_stat_type(atttypid, atttyptype,
|
||||||
&elemtypid, &elem_eq_opr))
|
&elemtypid, &elem_eq_opr))
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errmsg("unable to determine element type of attribute \"%s\"", NameStr(*attname)),
|
(errmsg("unable to determine element type of attribute \"%s\"", NameStr(*attname)),
|
||||||
errdetail("Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.")));
|
errdetail("Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.")));
|
||||||
elemtypid = InvalidOid;
|
elemtypid = InvalidOid;
|
||||||
@ -259,7 +255,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
/* histogram and correlation require less-than operator */
|
/* histogram and correlation require less-than operator */
|
||||||
if ((do_histogram || do_correlation) && !OidIsValid(lt_opr))
|
if ((do_histogram || do_correlation) && !OidIsValid(lt_opr))
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("could not determine less-than operator for attribute \"%s\"", NameStr(*attname)),
|
errmsg("could not determine less-than operator for attribute \"%s\"", NameStr(*attname)),
|
||||||
errdetail("Cannot set STATISTIC_KIND_HISTOGRAM or STATISTIC_KIND_CORRELATION.")));
|
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) &&
|
if ((do_range_length_histogram || do_bounds_histogram) &&
|
||||||
!(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
|
!(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("attribute \"%s\" is not a range type", NameStr(*attname)),
|
errmsg("attribute \"%s\" is not a range type", NameStr(*attname)),
|
||||||
errdetail("Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.")));
|
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,
|
&array_in_fn,
|
||||||
PG_GETARG_DATUM(MOST_COMMON_VALS_ARG),
|
PG_GETARG_DATUM(MOST_COMMON_VALS_ARG),
|
||||||
atttypid, atttypmod,
|
atttypid, atttypmod,
|
||||||
elevel, &converted);
|
&converted);
|
||||||
|
|
||||||
if (converted)
|
if (converted)
|
||||||
{
|
{
|
||||||
@ -344,7 +340,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
stavalues = text_to_stavalues("histogram_bounds",
|
stavalues = text_to_stavalues("histogram_bounds",
|
||||||
&array_in_fn,
|
&array_in_fn,
|
||||||
PG_GETARG_DATUM(HISTOGRAM_BOUNDS_ARG),
|
PG_GETARG_DATUM(HISTOGRAM_BOUNDS_ARG),
|
||||||
atttypid, atttypmod, elevel,
|
atttypid, atttypmod,
|
||||||
&converted);
|
&converted);
|
||||||
|
|
||||||
if (converted)
|
if (converted)
|
||||||
@ -382,7 +378,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
&array_in_fn,
|
&array_in_fn,
|
||||||
PG_GETARG_DATUM(MOST_COMMON_ELEMS_ARG),
|
PG_GETARG_DATUM(MOST_COMMON_ELEMS_ARG),
|
||||||
elemtypid, atttypmod,
|
elemtypid, atttypmod,
|
||||||
elevel, &converted);
|
&converted);
|
||||||
|
|
||||||
if (converted)
|
if (converted)
|
||||||
{
|
{
|
||||||
@ -422,7 +418,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
&array_in_fn,
|
&array_in_fn,
|
||||||
PG_GETARG_DATUM(RANGE_BOUNDS_HISTOGRAM_ARG),
|
PG_GETARG_DATUM(RANGE_BOUNDS_HISTOGRAM_ARG),
|
||||||
atttypid, atttypmod,
|
atttypid, atttypmod,
|
||||||
elevel, &converted);
|
&converted);
|
||||||
|
|
||||||
if (converted)
|
if (converted)
|
||||||
{
|
{
|
||||||
@ -449,7 +445,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
stavalues = text_to_stavalues("range_length_histogram",
|
stavalues = text_to_stavalues("range_length_histogram",
|
||||||
&array_in_fn,
|
&array_in_fn,
|
||||||
PG_GETARG_DATUM(RANGE_LENGTH_HISTOGRAM_ARG),
|
PG_GETARG_DATUM(RANGE_LENGTH_HISTOGRAM_ARG),
|
||||||
FLOAT8OID, 0, elevel, &converted);
|
FLOAT8OID, 0, &converted);
|
||||||
|
|
||||||
if (converted)
|
if (converted)
|
||||||
{
|
{
|
||||||
@ -517,7 +513,7 @@ get_attr_expr(Relation rel, int attnum)
|
|||||||
* Derive type information from the attribute.
|
* Derive type information from the attribute.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
get_attr_stat_type(Oid reloid, AttrNumber attnum, int elevel,
|
get_attr_stat_type(Oid reloid, AttrNumber attnum,
|
||||||
Oid *atttypid, int32 *atttypmod,
|
Oid *atttypid, int32 *atttypmod,
|
||||||
char *atttyptype, Oid *atttypcoll,
|
char *atttyptype, Oid *atttypcoll,
|
||||||
Oid *eq_opr, Oid *lt_opr)
|
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.
|
* Derive element type information from the attribute type.
|
||||||
*/
|
*/
|
||||||
static bool
|
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)
|
Oid *elemtypid, Oid *elem_eq_opr)
|
||||||
{
|
{
|
||||||
TypeCacheEntry *elemtypcache;
|
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.
|
* 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
|
* If an error is encountered, capture it and re-throw a WARNING, and set ok
|
||||||
* to false. If the resulting array contains NULLs, raise an error at elevel
|
* to false. If the resulting array contains NULLs, raise a WARNING and set ok
|
||||||
* and set ok to false. Otherwise, set ok to true.
|
* to false. Otherwise, set ok to true.
|
||||||
*/
|
*/
|
||||||
static Datum
|
static Datum
|
||||||
text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid,
|
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);
|
LOCAL_FCINFO(fcinfo, 8);
|
||||||
char *s;
|
char *s;
|
||||||
@ -667,8 +663,7 @@ text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid,
|
|||||||
|
|
||||||
if (escontext.error_occurred)
|
if (escontext.error_occurred)
|
||||||
{
|
{
|
||||||
if (elevel != ERROR)
|
escontext.error_data->elevel = WARNING;
|
||||||
escontext.error_data->elevel = elevel;
|
|
||||||
ThrowErrorData(escontext.error_data);
|
ThrowErrorData(escontext.error_data);
|
||||||
*ok = false;
|
*ok = false;
|
||||||
return (Datum) 0;
|
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)))
|
if (array_contains_nulls(DatumGetArrayTypeP(result)))
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("\"%s\" array cannot contain NULL values", staname)));
|
errmsg("\"%s\" array cannot contain NULL values", staname)));
|
||||||
*ok = false;
|
*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.
|
* Delete statistics for the given attribute.
|
||||||
*/
|
*/
|
||||||
@ -933,10 +901,10 @@ pg_restore_attribute_stats(PG_FUNCTION_ARGS)
|
|||||||
InvalidOid, NULL, NULL);
|
InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
|
if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
|
||||||
attarginfo, WARNING))
|
attarginfo))
|
||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
if (!attribute_statistics_update(positional_fcinfo, WARNING))
|
if (!attribute_statistics_update(positional_fcinfo))
|
||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
|
@ -48,13 +48,13 @@ static struct StatsArgInfo relarginfo[] =
|
|||||||
[NUM_RELATION_STATS_ARGS] = {0}
|
[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.
|
* Internal function for modifying statistics for a relation.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
relation_statistics_update(FunctionCallInfo fcinfo)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
@ -83,7 +83,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
|
reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
|
||||||
if (reltuples < -1.0)
|
if (reltuples < -1.0)
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("reltuples cannot be < -1.0")));
|
errmsg("reltuples cannot be < -1.0")));
|
||||||
result = false;
|
result = false;
|
||||||
@ -118,7 +118,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
ctup = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid));
|
ctup = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid));
|
||||||
if (!HeapTupleIsValid(ctup))
|
if (!HeapTupleIsValid(ctup))
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_OBJECT_IN_USE),
|
(errcode(ERRCODE_OBJECT_IN_USE),
|
||||||
errmsg("pg_class entry for relid %u not found", reloid)));
|
errmsg("pg_class entry for relid %u not found", reloid)));
|
||||||
table_close(crel, RowExclusiveLock);
|
table_close(crel, RowExclusiveLock);
|
||||||
@ -169,16 +169,6 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
|||||||
return result;
|
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
|
* Clear statistics for a given pg_class entry; that is, set back to initial
|
||||||
* stats for a newly-created table.
|
* 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].value = UInt32GetDatum(0);
|
||||||
newfcinfo->args[3].isnull = false;
|
newfcinfo->args[3].isnull = false;
|
||||||
|
|
||||||
relation_statistics_update(newfcinfo, ERROR);
|
relation_statistics_update(newfcinfo);
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,10 +204,10 @@ pg_restore_relation_stats(PG_FUNCTION_ARGS)
|
|||||||
InvalidOid, NULL, NULL);
|
InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
|
if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
|
||||||
relarginfo, WARNING))
|
relarginfo))
|
||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
if (!relation_statistics_update(positional_fcinfo, WARNING))
|
if (!relation_statistics_update(positional_fcinfo))
|
||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
|
@ -48,13 +48,13 @@ stats_check_required_arg(FunctionCallInfo fcinfo,
|
|||||||
* Check that argument is either NULL or a one dimensional array with no
|
* Check that argument is either NULL or a one dimensional array with no
|
||||||
* NULLs.
|
* 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.
|
* true.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
stats_check_arg_array(FunctionCallInfo fcinfo,
|
stats_check_arg_array(FunctionCallInfo fcinfo,
|
||||||
struct StatsArgInfo *arginfo,
|
struct StatsArgInfo *arginfo,
|
||||||
int argnum, int elevel)
|
int argnum)
|
||||||
{
|
{
|
||||||
ArrayType *arr;
|
ArrayType *arr;
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ stats_check_arg_array(FunctionCallInfo fcinfo,
|
|||||||
|
|
||||||
if (ARR_NDIM(arr) != 1)
|
if (ARR_NDIM(arr) != 1)
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("\"%s\" cannot be a multidimensional array",
|
errmsg("\"%s\" cannot be a multidimensional array",
|
||||||
arginfo[argnum].argname)));
|
arginfo[argnum].argname)));
|
||||||
@ -74,7 +74,7 @@ stats_check_arg_array(FunctionCallInfo fcinfo,
|
|||||||
|
|
||||||
if (array_contains_nulls(arr))
|
if (array_contains_nulls(arr))
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("\"%s\" array cannot contain NULL values",
|
errmsg("\"%s\" array cannot contain NULL values",
|
||||||
arginfo[argnum].argname)));
|
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
|
* a particular stakind, such as most_common_vals and most_common_freqs for
|
||||||
* STATISTIC_KIND_MCV.
|
* 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.
|
* true.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
stats_check_arg_pair(FunctionCallInfo fcinfo,
|
stats_check_arg_pair(FunctionCallInfo fcinfo,
|
||||||
struct StatsArgInfo *arginfo,
|
struct StatsArgInfo *arginfo,
|
||||||
int argnum1, int argnum2, int elevel)
|
int argnum1, int argnum2)
|
||||||
{
|
{
|
||||||
if (PG_ARGISNULL(argnum1) && PG_ARGISNULL(argnum2))
|
if (PG_ARGISNULL(argnum1) && PG_ARGISNULL(argnum2))
|
||||||
return true;
|
return true;
|
||||||
@ -105,7 +105,7 @@ stats_check_arg_pair(FunctionCallInfo fcinfo,
|
|||||||
int nullarg = PG_ARGISNULL(argnum1) ? argnum1 : argnum2;
|
int nullarg = PG_ARGISNULL(argnum1) ? argnum1 : argnum2;
|
||||||
int otherarg = PG_ARGISNULL(argnum1) ? argnum2 : argnum1;
|
int otherarg = PG_ARGISNULL(argnum1) ? argnum2 : argnum1;
|
||||||
|
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("\"%s\" must be specified when \"%s\" is specified",
|
errmsg("\"%s\" must be specified when \"%s\" is specified",
|
||||||
arginfo[nullarg].argname,
|
arginfo[nullarg].argname,
|
||||||
@ -216,7 +216,7 @@ stats_lock_check_privileges(Oid reloid)
|
|||||||
* found.
|
* found.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
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)
|
if (pg_strcasecmp(argname, arginfo[argnum].argname) == 0)
|
||||||
return argnum;
|
return argnum;
|
||||||
|
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errmsg("unrecognized argument name: \"%s\"", argname)));
|
(errmsg("unrecognized argument name: \"%s\"", argname)));
|
||||||
|
|
||||||
return -1;
|
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.
|
* Ensure that a given argument matched the expected type.
|
||||||
*/
|
*/
|
||||||
static bool
|
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)
|
if (argtype != expectedtype)
|
||||||
{
|
{
|
||||||
ereport(elevel,
|
ereport(WARNING,
|
||||||
(errmsg("argument \"%s\" has type \"%s\", expected type \"%s\"",
|
(errmsg("argument \"%s\" has type \"%s\", expected type \"%s\"",
|
||||||
argname, format_type_be(argtype),
|
argname, format_type_be(argtype),
|
||||||
format_type_be(expectedtype))));
|
format_type_be(expectedtype))));
|
||||||
@ -260,8 +260,7 @@ stats_check_arg_type(const char *argname, Oid argtype, Oid expectedtype, int ele
|
|||||||
bool
|
bool
|
||||||
stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
|
stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
|
||||||
FunctionCallInfo positional_fcinfo,
|
FunctionCallInfo positional_fcinfo,
|
||||||
struct StatsArgInfo *arginfo,
|
struct StatsArgInfo *arginfo)
|
||||||
int elevel)
|
|
||||||
{
|
{
|
||||||
Datum *args;
|
Datum *args;
|
||||||
bool *argnulls;
|
bool *argnulls;
|
||||||
@ -319,11 +318,10 @@ stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
|
|||||||
if (pg_strcasecmp(argname, "version") == 0)
|
if (pg_strcasecmp(argname, "version") == 0)
|
||||||
continue;
|
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],
|
if (argnum < 0 || !stats_check_arg_type(argname, types[i + 1],
|
||||||
arginfo[argnum].argtype,
|
arginfo[argnum].argtype))
|
||||||
elevel))
|
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
continue;
|
continue;
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202502241
|
#define CATALOG_VERSION_NO 202502242
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#----------------------------------------------------------------------
|
\#----------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# pg_proc.dat
|
# pg_proc.dat
|
||||||
# Initial contents of the pg_proc system catalog.
|
# Initial contents of the pg_proc system catalog.
|
||||||
@ -12420,7 +12420,14 @@
|
|||||||
proargnames => '{kwargs}',
|
proargnames => '{kwargs}',
|
||||||
proargmodes => '{v}',
|
proargmodes => '{v}',
|
||||||
prosrc => 'pg_restore_relation_stats' },
|
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',
|
descr => 'restore statistics on attribute',
|
||||||
proname => 'pg_restore_attribute_stats', provolatile => 'v', proisstrict => 'f',
|
proname => 'pg_restore_attribute_stats', provolatile => 'v', proisstrict => 'f',
|
||||||
provariadic => 'any',
|
provariadic => 'any',
|
||||||
@ -12430,33 +12437,12 @@
|
|||||||
proargmodes => '{v}',
|
proargmodes => '{v}',
|
||||||
prosrc => 'pg_restore_attribute_stats' },
|
prosrc => 'pg_restore_attribute_stats' },
|
||||||
{ oid => '9162',
|
{ 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',
|
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 => 'regclass name bool',
|
||||||
proargnames => '{relation,attname,inherited}',
|
proargnames => '{relation,attname,inherited}',
|
||||||
prosrc => 'pg_clear_attribute_stats' },
|
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
|
# GiST stratnum implementations
|
||||||
{ oid => '8047', descr => 'GiST support',
|
{ oid => '8047', descr => 'GiST support',
|
||||||
|
@ -25,17 +25,15 @@ extern void stats_check_required_arg(FunctionCallInfo fcinfo,
|
|||||||
struct StatsArgInfo *arginfo,
|
struct StatsArgInfo *arginfo,
|
||||||
int argnum);
|
int argnum);
|
||||||
extern bool stats_check_arg_array(FunctionCallInfo fcinfo,
|
extern bool stats_check_arg_array(FunctionCallInfo fcinfo,
|
||||||
struct StatsArgInfo *arginfo, int argnum,
|
struct StatsArgInfo *arginfo, int argnum);
|
||||||
int elevel);
|
|
||||||
extern bool stats_check_arg_pair(FunctionCallInfo fcinfo,
|
extern bool stats_check_arg_pair(FunctionCallInfo fcinfo,
|
||||||
struct StatsArgInfo *arginfo,
|
struct StatsArgInfo *arginfo,
|
||||||
int argnum1, int argnum2, int elevel);
|
int argnum1, int argnum2);
|
||||||
|
|
||||||
extern void stats_lock_check_privileges(Oid reloid);
|
extern void stats_lock_check_privileges(Oid reloid);
|
||||||
|
|
||||||
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);
|
||||||
int elevel);
|
|
||||||
|
|
||||||
#endif /* STATS_UTILS_H */
|
#endif /* STATS_UTILS_H */
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user