mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -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_set_relation_stats</primary> |          <primary>pg_restore_relation_stats</primary> | ||||||
|         </indexterm> |         </indexterm> | ||||||
|          <function>pg_set_relation_stats</function> ( |         <function>pg_restore_relation_stats</function> ( | ||||||
|          <parameter>relation</parameter> <type>regclass</type> |         <literal>VARIADIC</literal> <parameter>kwargs</parameter> <type>"any"</type> ) | ||||||
|          <optional>, <parameter>relpages</parameter> <type>integer</type></optional> |         <returnvalue>boolean</returnvalue> | ||||||
|          <optional>, <parameter>reltuples</parameter> <type>real</type></optional> |  | ||||||
|          <optional>, <parameter>relallvisible</parameter> <type>integer</type></optional> ) |  | ||||||
|          <returnvalue>void</returnvalue> |  | ||||||
|        </para> |        </para> | ||||||
|         <para> |         <para> | ||||||
|          Updates relation-level statistics for the given relation to the |          Updates table-level statistics.  Ordinarily, these statistics are | ||||||
|          specified values. The parameters correspond to columns in <link |          collected automatically or updated as a part of <xref | ||||||
|          linkend="catalog-pg-class"><structname>pg_class</structname></link>. Unspecified |          linkend="sql-vacuum"/> or <xref linkend="sql-analyze"/>, so it's not | ||||||
|          or <literal>NULL</literal> values leave the setting unchanged. |          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> | ||||||
|          Ordinarily, these statistics are collected automatically or updated |          The tracked statistics may change from version to version, so | ||||||
|          as a part of <xref linkend="sql-vacuum"/> or <xref |          arguments are passed as pairs of <replaceable>argname</replaceable> | ||||||
|          linkend="sql-analyze"/>, so it's not necessary to call this |          and <replaceable>argvalue</replaceable> in the form: | ||||||
|          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( | ||||||
|  |     '<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> | ||||||
|          The caller must have the <literal>MAINTAIN</literal> privilege on |          For example, to set the <structname>relpages</structname> and | ||||||
|          the table or be the owner of the database. |          <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> | ||||||
|         <para> |         <para> | ||||||
|          The value of <structfield>relpages</structfield> must be greater than |          The argument <literal>relation</literal> with a value of type | ||||||
|          or equal to <literal>-1</literal>, |          <type>regclass</type> is required, and specifies the table. Other | ||||||
|          <structfield>reltuples</structfield> must be greater than or equal to |          arguments are the names of statistics corresponding to certain | ||||||
|          <literal>-1.0</literal>, and <structfield>relallvisible</structfield> |          columns in <link | ||||||
|          must be greater than or equal to <literal>0</literal>. |          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> | ||||||
|  |          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> |         </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> | ||||||
|         <para> |         <para> | ||||||
|          Similar to <function>pg_set_relation_stats()</function>, but intended |          Create or update column-level statistics.  Ordinarily, these | ||||||
|          for bulk restore of relation statistics. The tracked statistics may |          statistics are collected automatically or updated as a part of <xref | ||||||
|          change from version to version, so the primary purpose of this |          linkend="sql-vacuum"/> or <xref linkend="sql-analyze"/>, so it's not | ||||||
|          function is to maintain a consistent function signature to avoid |          necessary to call this function.  However, it is useful after a | ||||||
|          errors when restoring statistics from previous versions. |          restore to enable the optimizer to choose better plans if | ||||||
|  |          <command>ANALYZE</command> has not been run yet. | ||||||
|         </para> |         </para> | ||||||
|         <para> |         <para> | ||||||
|          Arguments are passed as pairs of <replaceable>argname</replaceable> |          The tracked statistics may change from version to version, so | ||||||
|          and <replaceable>argvalue</replaceable>, where |          arguments are passed as pairs of <replaceable>argname</replaceable> | ||||||
|          <replaceable>argname</replaceable> corresponds to a named argument in |          and <replaceable>argvalue</replaceable> in the form: | ||||||
|          <function>pg_set_relation_stats()</function> and | <programlisting> | ||||||
|          <replaceable>argvalue</replaceable> is of the corresponding type. |  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> | ||||||
|  |          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> | ||||||
|         <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