diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index f0ccb751106..12206e0cfc6 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -30181,41 +30181,72 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
-
-
-
- pg_set_relation_stats
-
- pg_set_relation_stats (
- relation regclass
- , relpages integer
- , reltuples real
- , relallvisible integer )
- void
+
+
+ pg_restore_relation_stats
+
+ pg_restore_relation_stats (
+ VARIADIC kwargs "any" )
+ boolean
+
+
+ Updates table-level statistics. Ordinarily, these statistics are
+ collected automatically or updated as a part of or , 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
+ ANALYZE has not been run yet.
- Updates relation-level statistics for the given relation to the
- specified values. The parameters correspond to columns in pg_class. Unspecified
- or NULL values leave the setting unchanged.
+ The tracked statistics may change from version to version, so
+ arguments are passed as pairs of argname
+ and argvalue in the form:
+
+ SELECT pg_restore_relation_stats(
+ 'arg1name', 'arg1value'::arg1type,
+ 'arg2name', 'arg2value'::arg2type,
+ 'arg3name', 'arg3value'::arg3type);
+
- Ordinarily, these statistics are collected automatically or updated
- as a part of or , so it's not necessary to call this
- function. However, it may be useful when testing the effects of
- statistics on the planner to understand or anticipate plan changes.
+ For example, to set the relpages and
+ reltuples of the table
+ mytable:
+
+ SELECT pg_restore_relation_stats(
+ 'relation', 'mytable'::regclass,
+ 'relpages', 173::integer,
+ 'reltuples', 10000::real);
+
- The caller must have the MAINTAIN privilege on
- the table or be the owner of the database.
+ The argument relation with a value of type
+ regclass is required, and specifies the table. Other
+ arguments are the names of statistics corresponding to certain
+ columns in pg_class.
+ The currently-supported relation statistics are
+ relpages with a value of type
+ integer, reltuples with a value of
+ type real, and relallvisible with a
+ value of type integer.
- The value of relpages must be greater than
- or equal to -1,
- reltuples must be greater than or equal to
- -1.0, and relallvisible
- must be greater than or equal to 0.
+ Additionally, this function supports argument name
+ version of type integer, which
+ specifies the version from which the statistics originated, improving
+ interpretation of statistics from older versions of
+ PostgreSQL.
+
+
+ Minor errors are reported as a WARNING and
+ ignored, and remaining statistics will still be restored. If all
+ specified statistics are successfully restored, return
+ true, otherwise false.
+
+
+ The caller must have the MAINTAIN privilege on the
+ table or be the owner of the database.
@@ -30234,8 +30265,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
table was newly created.
- The caller must have the MAINTAIN privilege on
- the table or be the owner of the database.
+ The caller must have the MAINTAIN privilege on the
+ table or be the owner of the database.
@@ -30243,42 +30274,61 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
- pg_restore_relation_stats
+ pg_restore_attribute_stats
- pg_restore_relation_stats (
+ pg_restore_attribute_stats (
VARIADIC kwargs "any" )
boolean
+
+
+ Create or update column-level statistics. Ordinarily, these
+ statistics are collected automatically or updated as a part of or , 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
+ ANALYZE has not been run yet.
- Similar to pg_set_relation_stats(), but intended
- for bulk restore of relation statistics. The tracked statistics may
- change from version to version, so the primary purpose of this
- function is to maintain a consistent function signature to avoid
- errors when restoring statistics from previous versions.
+ The tracked statistics may change from version to version, so
+ arguments are passed as pairs of argname
+ and argvalue in the form:
+
+ SELECT pg_restore_attribute_stats(
+ 'arg1name', 'arg1value'::arg1type,
+ 'arg2name', 'arg2value'::arg2type,
+ 'arg3name', 'arg3value'::arg3type);
+
- Arguments are passed as pairs of argname
- and argvalue, where
- argname corresponds to a named argument in
- pg_set_relation_stats() and
- argvalue is of the corresponding type.
+ For example, to set the avg_width and
+ null_frac for the attribute
+ col1 of the table
+ mytable:
+
+ SELECT pg_restore_attribute_stats(
+ 'relation', 'mytable'::regclass,
+ 'attname', 'col1'::name,
+ 'inherited', false,
+ 'avg_width', 125::integer,
+ 'null_frac', 0.5::real);
+
+
+
+ The required arguments are relation with a value
+ of type regclass, which specifies the table;
+ attname with a value of type name,
+ which specifies the column; and inherited, which
+ specifies whether the statistics includes values from child tables.
+ Other arguments are the names of statistics corresponding to columns
+ in pg_stats.
Additionally, this function supports argument name
version of type integer, which
specifies the version from which the statistics originated, improving
- interpretation of older statistics.
-
-
- For example, to set the relpages and
- reltuples of the table
- mytable:
-
- SELECT pg_restore_relation_stats(
- 'relation', 'mytable'::regclass,
- 'relpages', 173::integer,
- 'reltuples', 10000::float4);
-
+ interpretation of statistics from older versions of
+ PostgreSQL.
Minor errors are reported as a WARNING and
@@ -30286,53 +30336,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
specified statistics are successfully restored, return
true, otherwise false.
-
-
-
-
-
-
-
- pg_set_attribute_stats
-
- pg_set_attribute_stats (
- relation regclass,
- attname name,
- inherited boolean
- , null_frac real
- , avg_width integer
- , n_distinct real
- , most_common_vals text, most_common_freqs real[]
- , histogram_bounds text
- , correlation real
- , most_common_elems text, most_common_elem_freqs real[]
- , elem_count_histogram real[]
- , range_length_histogram text
- , range_empty_frac real
- , range_bounds_histogram text )
- void
-
- Creates or updates attribute-level statistics for the given relation
- and attribute name to the specified values. The parameters correspond
- to attributes of the same name found in the pg_stats
- view.
-
-
- Optional parameters default to NULL, which leave
- the corresponding statistic unchanged.
-
-
- Ordinarily, these statistics are collected automatically or updated
- as a part of or , 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.
-
-
- The caller must have the MAINTAIN privilege on
- the table or be the owner of the database.
+ The caller must have the MAINTAIN privilege on the
+ table or be the owner of the database.
@@ -30350,8 +30356,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
void
- Clears table-level statistics for the given relation attribute, as
- though the table was newly created.
+ Clears column-level statistics for the given relation and
+ attribute, as though the table was newly created.
The caller must have the MAINTAIN privilege on
@@ -30359,58 +30365,6 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
-
-
-
-
- pg_restore_attribute_stats
-
- pg_restore_attribute_stats (
- VARIADIC kwargs "any" )
- boolean
-
-
- Similar to pg_set_attribute_stats(), 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.
-
-
- Arguments are passed as pairs of argname
- and argvalue, where
- argname corresponds to a named argument in
- pg_set_attribute_stats() and
- argvalue is of the corresponding type.
-
-
- Additionally, this function supports argument name
- version of type integer, which
- specifies the version from which the statistics originated, improving
- interpretation of older statistics.
-
-
- For example, to set the avg_width and
- null_frac for the attribute
- col1 of the table
- mytable:
-
- SELECT pg_restore_attribute_stats(
- 'relation', 'mytable'::regclass,
- 'attname', 'col1'::name,
- 'inherited', false,
- 'avg_width', 125::integer,
- 'null_frac', 0.5::real);
-
-
-
- Minor errors are reported as a WARNING and
- ignored, and remaining statistics will still be restored. If all
- specified statistics are successfully restored, return
- true, otherwise false.
-
-
-
diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql
index 591157b1d1b..86888cd3201 100644
--- a/src/backend/catalog/system_functions.sql
+++ b/src/backend/catalog/system_functions.sql
@@ -636,38 +636,6 @@ LANGUAGE INTERNAL
CALLED ON NULL INPUT VOLATILE PARALLEL SAFE
AS 'pg_stat_reset_slru';
-CREATE OR REPLACE FUNCTION
- pg_set_relation_stats(relation regclass,
- relpages integer DEFAULT NULL,
- reltuples real DEFAULT NULL,
- relallvisible integer DEFAULT NULL)
-RETURNS void
-LANGUAGE INTERNAL
-CALLED ON NULL INPUT VOLATILE
-AS 'pg_set_relation_stats';
-
-CREATE OR REPLACE FUNCTION
- pg_set_attribute_stats(relation regclass,
- attname name,
- inherited bool,
- null_frac real DEFAULT NULL,
- avg_width integer DEFAULT NULL,
- n_distinct real DEFAULT NULL,
- most_common_vals text DEFAULT NULL,
- most_common_freqs real[] DEFAULT NULL,
- histogram_bounds text DEFAULT NULL,
- correlation real DEFAULT NULL,
- most_common_elems text DEFAULT NULL,
- most_common_elem_freqs real[] DEFAULT NULL,
- elem_count_histogram real[] DEFAULT NULL,
- range_length_histogram text DEFAULT NULL,
- range_empty_frac real DEFAULT NULL,
- range_bounds_histogram text DEFAULT NULL)
-RETURNS void
-LANGUAGE INTERNAL
-CALLED ON NULL INPUT VOLATILE
-AS 'pg_set_attribute_stats';
-
--
-- The default permissions for functions mean that anyone can execute them.
-- A number of functions shouldn't be executable by just anyone, but rather
diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c
index c0c398a4bb2..66a5676c810 100644
--- a/src/backend/statistics/attribute_stats.c
+++ b/src/backend/statistics/attribute_stats.c
@@ -76,16 +76,16 @@ static struct StatsArgInfo attarginfo[] =
[NUM_ATTRIBUTE_STATS_ARGS] = {0}
};
-static bool attribute_statistics_update(FunctionCallInfo fcinfo, int elevel);
+static bool attribute_statistics_update(FunctionCallInfo fcinfo);
static Node *get_attr_expr(Relation rel, int attnum);
-static void get_attr_stat_type(Oid reloid, AttrNumber attnum, int elevel,
+static void get_attr_stat_type(Oid reloid, AttrNumber attnum,
Oid *atttypid, int32 *atttypmod,
char *atttyptype, Oid *atttypcoll,
Oid *eq_opr, Oid *lt_opr);
-static bool get_elem_stat_type(Oid atttypid, char atttyptype, int elevel,
+static bool get_elem_stat_type(Oid atttypid, char atttyptype,
Oid *elemtypid, Oid *elem_eq_opr);
static Datum text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d,
- Oid typid, int32 typmod, int elevel, bool *ok);
+ Oid typid, int32 typmod, bool *ok);
static void set_stats_slot(Datum *values, bool *nulls, bool *replaces,
int16 stakind, Oid staop, Oid stacoll,
Datum stanumbers, bool stanumbers_isnull,
@@ -109,11 +109,11 @@ static void init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited,
*
* Major errors, such as the table not existing, the attribute not existing,
* or a permissions failure are always reported at ERROR. Other errors, such
- * as a conversion failure on one statistic kind, are reported at 'elevel',
+ * as a conversion failure on one statistic kind, are reported as a WARNING
* and other statistic kinds may still be updated.
*/
static bool
-attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
+attribute_statistics_update(FunctionCallInfo fcinfo)
{
Oid reloid;
Name attname;
@@ -184,33 +184,29 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
inherited = PG_GETARG_BOOL(INHERITED_ARG);
/*
- * Check argument sanity. If some arguments are unusable, emit at elevel
+ * Check argument sanity. If some arguments are unusable, emit a WARNING
* and set the corresponding argument to NULL in fcinfo.
*/
- if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_FREQS_ARG,
- elevel))
+ if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_FREQS_ARG))
{
do_mcv = false;
result = false;
}
- if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_ELEM_FREQS_ARG,
- elevel))
+ if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_ELEM_FREQS_ARG))
{
do_mcelem = false;
result = false;
}
- if (!stats_check_arg_array(fcinfo, attarginfo, ELEM_COUNT_HISTOGRAM_ARG,
- elevel))
+ if (!stats_check_arg_array(fcinfo, attarginfo, ELEM_COUNT_HISTOGRAM_ARG))
{
do_dechist = false;
result = false;
}
if (!stats_check_arg_pair(fcinfo, attarginfo,
- MOST_COMMON_VALS_ARG, MOST_COMMON_FREQS_ARG,
- elevel))
+ MOST_COMMON_VALS_ARG, MOST_COMMON_FREQS_ARG))
{
do_mcv = false;
result = false;
@@ -218,7 +214,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
if (!stats_check_arg_pair(fcinfo, attarginfo,
MOST_COMMON_ELEMS_ARG,
- MOST_COMMON_ELEM_FREQS_ARG, elevel))
+ MOST_COMMON_ELEM_FREQS_ARG))
{
do_mcelem = false;
result = false;
@@ -226,14 +222,14 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
if (!stats_check_arg_pair(fcinfo, attarginfo,
RANGE_LENGTH_HISTOGRAM_ARG,
- RANGE_EMPTY_FRAC_ARG, elevel))
+ RANGE_EMPTY_FRAC_ARG))
{
do_range_length_histogram = false;
result = false;
}
/* derive information from attribute */
- get_attr_stat_type(reloid, attnum, elevel,
+ get_attr_stat_type(reloid, attnum,
&atttypid, &atttypmod,
&atttyptype, &atttypcoll,
&eq_opr, <_opr);
@@ -241,10 +237,10 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
/* if needed, derive element type */
if (do_mcelem || do_dechist)
{
- if (!get_elem_stat_type(atttypid, atttyptype, elevel,
+ if (!get_elem_stat_type(atttypid, atttyptype,
&elemtypid, &elem_eq_opr))
{
- ereport(elevel,
+ ereport(WARNING,
(errmsg("unable to determine element type of attribute \"%s\"", NameStr(*attname)),
errdetail("Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.")));
elemtypid = InvalidOid;
@@ -259,7 +255,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
/* histogram and correlation require less-than operator */
if ((do_histogram || do_correlation) && !OidIsValid(lt_opr))
{
- ereport(elevel,
+ ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("could not determine less-than operator for attribute \"%s\"", NameStr(*attname)),
errdetail("Cannot set STATISTIC_KIND_HISTOGRAM or STATISTIC_KIND_CORRELATION.")));
@@ -273,7 +269,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
if ((do_range_length_histogram || do_bounds_histogram) &&
!(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
{
- ereport(elevel,
+ ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("attribute \"%s\" is not a range type", NameStr(*attname)),
errdetail("Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.")));
@@ -322,7 +318,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
&array_in_fn,
PG_GETARG_DATUM(MOST_COMMON_VALS_ARG),
atttypid, atttypmod,
- elevel, &converted);
+ &converted);
if (converted)
{
@@ -344,7 +340,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
stavalues = text_to_stavalues("histogram_bounds",
&array_in_fn,
PG_GETARG_DATUM(HISTOGRAM_BOUNDS_ARG),
- atttypid, atttypmod, elevel,
+ atttypid, atttypmod,
&converted);
if (converted)
@@ -382,7 +378,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
&array_in_fn,
PG_GETARG_DATUM(MOST_COMMON_ELEMS_ARG),
elemtypid, atttypmod,
- elevel, &converted);
+ &converted);
if (converted)
{
@@ -422,7 +418,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
&array_in_fn,
PG_GETARG_DATUM(RANGE_BOUNDS_HISTOGRAM_ARG),
atttypid, atttypmod,
- elevel, &converted);
+ &converted);
if (converted)
{
@@ -449,7 +445,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
stavalues = text_to_stavalues("range_length_histogram",
&array_in_fn,
PG_GETARG_DATUM(RANGE_LENGTH_HISTOGRAM_ARG),
- FLOAT8OID, 0, elevel, &converted);
+ FLOAT8OID, 0, &converted);
if (converted)
{
@@ -517,7 +513,7 @@ get_attr_expr(Relation rel, int attnum)
* Derive type information from the attribute.
*/
static void
-get_attr_stat_type(Oid reloid, AttrNumber attnum, int elevel,
+get_attr_stat_type(Oid reloid, AttrNumber attnum,
Oid *atttypid, int32 *atttypmod,
char *atttyptype, Oid *atttypcoll,
Oid *eq_opr, Oid *lt_opr)
@@ -599,7 +595,7 @@ get_attr_stat_type(Oid reloid, AttrNumber attnum, int elevel,
* Derive element type information from the attribute type.
*/
static bool
-get_elem_stat_type(Oid atttypid, char atttyptype, int elevel,
+get_elem_stat_type(Oid atttypid, char atttyptype,
Oid *elemtypid, Oid *elem_eq_opr)
{
TypeCacheEntry *elemtypcache;
@@ -634,13 +630,13 @@ get_elem_stat_type(Oid atttypid, char atttyptype, int elevel,
/*
* Cast a text datum into an array with element type elemtypid.
*
- * If an error is encountered, capture it and re-throw at elevel, and set ok
- * to false. If the resulting array contains NULLs, raise an error at elevel
- * and set ok to false. Otherwise, set ok to true.
+ * If an error is encountered, capture it and re-throw a WARNING, and set ok
+ * to false. If the resulting array contains NULLs, raise a WARNING and set ok
+ * to false. Otherwise, set ok to true.
*/
static Datum
text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid,
- int32 typmod, int elevel, bool *ok)
+ int32 typmod, bool *ok)
{
LOCAL_FCINFO(fcinfo, 8);
char *s;
@@ -667,8 +663,7 @@ text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid,
if (escontext.error_occurred)
{
- if (elevel != ERROR)
- escontext.error_data->elevel = elevel;
+ escontext.error_data->elevel = WARNING;
ThrowErrorData(escontext.error_data);
*ok = false;
return (Datum) 0;
@@ -676,7 +671,7 @@ text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid,
if (array_contains_nulls(DatumGetArrayTypeP(result)))
{
- ereport(elevel,
+ ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" array cannot contain NULL values", staname)));
*ok = false;
@@ -851,33 +846,6 @@ init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited,
}
}
-/*
- * Import statistics for a given relation attribute.
- *
- * Inserts or replaces a row in pg_statistic for the given relation and
- * attribute name. It takes input parameters that correspond to columns in the
- * view pg_stats.
- *
- * Parameters null_frac, avg_width, and n_distinct all correspond to NOT NULL
- * columns in pg_statistic. The remaining parameters all belong to a specific
- * stakind. Some stakinds require multiple parameters, which must be specified
- * together (or neither specified).
- *
- * Parameters are only superficially validated. Omitting a parameter or
- * passing NULL leaves the statistic unchanged.
- *
- * Parameters corresponding to ANYARRAY columns are instead passed in as text
- * values, which is a valid input string for an array of the type or element
- * type of the attribute. Any error generated by the array_in() function will
- * in turn fail the function.
- */
-Datum
-pg_set_attribute_stats(PG_FUNCTION_ARGS)
-{
- attribute_statistics_update(fcinfo, ERROR);
- PG_RETURN_VOID();
-}
-
/*
* Delete statistics for the given attribute.
*/
@@ -933,10 +901,10 @@ pg_restore_attribute_stats(PG_FUNCTION_ARGS)
InvalidOid, NULL, NULL);
if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
- attarginfo, WARNING))
+ attarginfo))
result = false;
- if (!attribute_statistics_update(positional_fcinfo, WARNING))
+ if (!attribute_statistics_update(positional_fcinfo))
result = false;
PG_RETURN_BOOL(result);
diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c
index 66731290a3e..11b1ef2dbc2 100644
--- a/src/backend/statistics/relation_stats.c
+++ b/src/backend/statistics/relation_stats.c
@@ -48,13 +48,13 @@ static struct StatsArgInfo relarginfo[] =
[NUM_RELATION_STATS_ARGS] = {0}
};
-static bool relation_statistics_update(FunctionCallInfo fcinfo, int elevel);
+static bool relation_statistics_update(FunctionCallInfo fcinfo);
/*
* Internal function for modifying statistics for a relation.
*/
static bool
-relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
+relation_statistics_update(FunctionCallInfo fcinfo)
{
bool result = true;
Oid reloid;
@@ -83,7 +83,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
if (reltuples < -1.0)
{
- ereport(elevel,
+ ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("reltuples cannot be < -1.0")));
result = false;
@@ -118,7 +118,7 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
ctup = SearchSysCache1(RELOID, ObjectIdGetDatum(reloid));
if (!HeapTupleIsValid(ctup))
{
- ereport(elevel,
+ ereport(WARNING,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("pg_class entry for relid %u not found", reloid)));
table_close(crel, RowExclusiveLock);
@@ -169,16 +169,6 @@ relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
return result;
}
-/*
- * Set statistics for a given pg_class entry.
- */
-Datum
-pg_set_relation_stats(PG_FUNCTION_ARGS)
-{
- relation_statistics_update(fcinfo, ERROR);
- PG_RETURN_VOID();
-}
-
/*
* Clear statistics for a given pg_class entry; that is, set back to initial
* stats for a newly-created table.
@@ -199,7 +189,7 @@ pg_clear_relation_stats(PG_FUNCTION_ARGS)
newfcinfo->args[3].value = UInt32GetDatum(0);
newfcinfo->args[3].isnull = false;
- relation_statistics_update(newfcinfo, ERROR);
+ relation_statistics_update(newfcinfo);
PG_RETURN_VOID();
}
@@ -214,10 +204,10 @@ pg_restore_relation_stats(PG_FUNCTION_ARGS)
InvalidOid, NULL, NULL);
if (!stats_fill_fcinfo_from_arg_pairs(fcinfo, positional_fcinfo,
- relarginfo, WARNING))
+ relarginfo))
result = false;
- if (!relation_statistics_update(positional_fcinfo, WARNING))
+ if (!relation_statistics_update(positional_fcinfo))
result = false;
PG_RETURN_BOOL(result);
diff --git a/src/backend/statistics/stat_utils.c b/src/backend/statistics/stat_utils.c
index e70ea1ce738..54ead90b5bb 100644
--- a/src/backend/statistics/stat_utils.c
+++ b/src/backend/statistics/stat_utils.c
@@ -48,13 +48,13 @@ stats_check_required_arg(FunctionCallInfo fcinfo,
* Check that argument is either NULL or a one dimensional array with no
* NULLs.
*
- * If a problem is found, emit at elevel, and return false. Otherwise return
+ * If a problem is found, emit a WARNING, and return false. Otherwise return
* true.
*/
bool
stats_check_arg_array(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo,
- int argnum, int elevel)
+ int argnum)
{
ArrayType *arr;
@@ -65,7 +65,7 @@ stats_check_arg_array(FunctionCallInfo fcinfo,
if (ARR_NDIM(arr) != 1)
{
- ereport(elevel,
+ ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" cannot be a multidimensional array",
arginfo[argnum].argname)));
@@ -74,7 +74,7 @@ stats_check_arg_array(FunctionCallInfo fcinfo,
if (array_contains_nulls(arr))
{
- ereport(elevel,
+ ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" array cannot contain NULL values",
arginfo[argnum].argname)));
@@ -89,13 +89,13 @@ stats_check_arg_array(FunctionCallInfo fcinfo,
* a particular stakind, such as most_common_vals and most_common_freqs for
* STATISTIC_KIND_MCV.
*
- * If a problem is found, emit at elevel, and return false. Otherwise return
+ * If a problem is found, emit a WARNING, and return false. Otherwise return
* true.
*/
bool
stats_check_arg_pair(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo,
- int argnum1, int argnum2, int elevel)
+ int argnum1, int argnum2)
{
if (PG_ARGISNULL(argnum1) && PG_ARGISNULL(argnum2))
return true;
@@ -105,7 +105,7 @@ stats_check_arg_pair(FunctionCallInfo fcinfo,
int nullarg = PG_ARGISNULL(argnum1) ? argnum1 : argnum2;
int otherarg = PG_ARGISNULL(argnum1) ? argnum2 : argnum1;
- ereport(elevel,
+ ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" must be specified when \"%s\" is specified",
arginfo[nullarg].argname,
@@ -216,7 +216,7 @@ stats_lock_check_privileges(Oid reloid)
* found.
*/
static int
-get_arg_by_name(const char *argname, struct StatsArgInfo *arginfo, int elevel)
+get_arg_by_name(const char *argname, struct StatsArgInfo *arginfo)
{
int argnum;
@@ -224,7 +224,7 @@ get_arg_by_name(const char *argname, struct StatsArgInfo *arginfo, int elevel)
if (pg_strcasecmp(argname, arginfo[argnum].argname) == 0)
return argnum;
- ereport(elevel,
+ ereport(WARNING,
(errmsg("unrecognized argument name: \"%s\"", argname)));
return -1;
@@ -234,11 +234,11 @@ get_arg_by_name(const char *argname, struct StatsArgInfo *arginfo, int elevel)
* Ensure that a given argument matched the expected type.
*/
static bool
-stats_check_arg_type(const char *argname, Oid argtype, Oid expectedtype, int elevel)
+stats_check_arg_type(const char *argname, Oid argtype, Oid expectedtype)
{
if (argtype != expectedtype)
{
- ereport(elevel,
+ ereport(WARNING,
(errmsg("argument \"%s\" has type \"%s\", expected type \"%s\"",
argname, format_type_be(argtype),
format_type_be(expectedtype))));
@@ -260,8 +260,7 @@ stats_check_arg_type(const char *argname, Oid argtype, Oid expectedtype, int ele
bool
stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
FunctionCallInfo positional_fcinfo,
- struct StatsArgInfo *arginfo,
- int elevel)
+ struct StatsArgInfo *arginfo)
{
Datum *args;
bool *argnulls;
@@ -319,11 +318,10 @@ stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
if (pg_strcasecmp(argname, "version") == 0)
continue;
- argnum = get_arg_by_name(argname, arginfo, elevel);
+ argnum = get_arg_by_name(argname, arginfo);
if (argnum < 0 || !stats_check_arg_type(argname, types[i + 1],
- arginfo[argnum].argtype,
- elevel))
+ arginfo[argnum].argtype))
{
result = false;
continue;
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index f6a99472e76..12163ae94be 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202502241
+#define CATALOG_VERSION_NO 202502242
#endif
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index af9546de23d..1c1d96e0c7e 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -1,4 +1,4 @@
-#----------------------------------------------------------------------
+\#----------------------------------------------------------------------
#
# pg_proc.dat
# Initial contents of the pg_proc system catalog.
@@ -12420,7 +12420,14 @@
proargnames => '{kwargs}',
proargmodes => '{v}',
prosrc => 'pg_restore_relation_stats' },
-{ oid => '8460',
+{ oid => '9160',
+ descr => 'clear statistics on relation',
+ proname => 'pg_clear_relation_stats', provolatile => 'v', proisstrict => 'f',
+ proparallel => 'u', prorettype => 'void',
+ proargtypes => 'regclass',
+ proargnames => '{relation}',
+ prosrc => 'pg_clear_relation_stats' },
+{ oid => '8461',
descr => 'restore statistics on attribute',
proname => 'pg_restore_attribute_stats', provolatile => 'v', proisstrict => 'f',
provariadic => 'any',
@@ -12430,33 +12437,12 @@
proargmodes => '{v}',
prosrc => 'pg_restore_attribute_stats' },
{ oid => '9162',
- descr => 'set statistics on attribute',
- proname => 'pg_set_attribute_stats', provolatile => 'v', proisstrict => 'f',
- proparallel => 'u', prorettype => 'void',
- proargtypes => 'regclass name bool float4 int4 float4 text _float4 text float4 text _float4 _float4 text float4 text',
- proargnames => '{relation,attname,inherited,null_frac,avg_width,n_distinct,most_common_vals,most_common_freqs,histogram_bounds,correlation,most_common_elems,most_common_elem_freqs,elem_count_histogram,range_length_histogram,range_empty_frac,range_bounds_histogram}',
- prosrc => 'pg_set_attribute_stats' },
-{ oid => '9163',
descr => 'clear statistics on attribute',
proname => 'pg_clear_attribute_stats', provolatile => 'v', proisstrict => 'f',
proparallel => 'u', prorettype => 'void',
proargtypes => 'regclass name bool',
proargnames => '{relation,attname,inherited}',
prosrc => 'pg_clear_attribute_stats' },
-{ oid => '9944',
- descr => 'set statistics on relation',
- proname => 'pg_set_relation_stats', provolatile => 'v', proisstrict => 'f',
- proparallel => 'u', prorettype => 'void',
- proargtypes => 'regclass int4 float4 int4',
- proargnames => '{relation,relpages,reltuples,relallvisible}',
- prosrc => 'pg_set_relation_stats' },
-{ oid => '9945',
- descr => 'clear statistics on relation',
- proname => 'pg_clear_relation_stats', provolatile => 'v', proisstrict => 'f',
- proparallel => 'u', prorettype => 'void',
- proargtypes => 'regclass',
- proargnames => '{relation}',
- prosrc => 'pg_clear_relation_stats' },
# GiST stratnum implementations
{ oid => '8047', descr => 'GiST support',
diff --git a/src/include/statistics/stat_utils.h b/src/include/statistics/stat_utils.h
index 6edb5ea0321..0eb4decfcac 100644
--- a/src/include/statistics/stat_utils.h
+++ b/src/include/statistics/stat_utils.h
@@ -25,17 +25,15 @@ extern void stats_check_required_arg(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo,
int argnum);
extern bool stats_check_arg_array(FunctionCallInfo fcinfo,
- struct StatsArgInfo *arginfo, int argnum,
- int elevel);
+ struct StatsArgInfo *arginfo, int argnum);
extern bool stats_check_arg_pair(FunctionCallInfo fcinfo,
struct StatsArgInfo *arginfo,
- int argnum1, int argnum2, int elevel);
+ int argnum1, int argnum2);
extern void stats_lock_check_privileges(Oid reloid);
extern bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo,
FunctionCallInfo positional_fcinfo,
- struct StatsArgInfo *arginfo,
- int elevel);
+ struct StatsArgInfo *arginfo);
#endif /* STATS_UTILS_H */
diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out
index d6713eacc2c..7e8b7f429c9 100644
--- a/src/test/regress/expected/stats_import.out
+++ b/src/test/regress/expected/stats_import.out
@@ -12,6 +12,7 @@ CREATE TABLE stats_import.test(
arange int4range,
tags text[]
) WITH (autovacuum_enabled = false);
+CREATE INDEX test_i ON stats_import.test(id);
-- starting stats
SELECT relpages, reltuples, relallvisible
FROM pg_class
@@ -21,80 +22,15 @@ WHERE oid = 'stats_import.test'::regclass;
0 | -1 | 0
(1 row)
--- error: regclass not found
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 0::Oid,
- relpages => 17::integer,
- reltuples => 400.0::real,
- relallvisible => 4::integer);
-ERROR: could not open relation with OID 0
--- relpages default
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => NULL::integer,
- reltuples => 400.0::real,
- relallvisible => 4::integer);
- pg_set_relation_stats
------------------------
-
-(1 row)
-
--- reltuples default
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => 17::integer,
- reltuples => NULL::real,
- relallvisible => 4::integer);
- pg_set_relation_stats
------------------------
-
-(1 row)
-
--- relallvisible default
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => 17::integer,
- reltuples => 400.0::real,
- relallvisible => NULL::integer);
- pg_set_relation_stats
------------------------
-
-(1 row)
-
--- named arguments
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => 17::integer,
- reltuples => 400.0::real,
- relallvisible => 4::integer);
- pg_set_relation_stats
------------------------
-
-(1 row)
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible
-----------+-----------+---------------
- 17 | 400 | 4
-(1 row)
-
-CREATE INDEX test_i ON stats_import.test(id);
BEGIN;
-- regular indexes have special case locking rules
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test_i'::regclass,
- relpages => 18::integer);
- pg_set_relation_stats
------------------------
-
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.test_i'::regclass,
+ 'relpages', 18::integer);
+ pg_restore_relation_stats
+---------------------------
+ t
(1 row)
SELECT mode FROM pg_locks
@@ -123,34 +59,6 @@ SELECT
t
(1 row)
--- positional arguments
-SELECT
- pg_catalog.pg_set_relation_stats(
- 'stats_import.test'::regclass,
- 18::integer,
- 401.0::real,
- 5::integer);
- pg_set_relation_stats
------------------------
-
-(1 row)
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible
-----------+-----------+---------------
- 18 | 401 | 5
-(1 row)
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible
-----------+-----------+---------------
- 18 | 401 | 5
-(1 row)
-
-- clear
SELECT
pg_catalog.pg_clear_relation_stats(
@@ -168,19 +76,6 @@ WHERE oid = 'stats_import.test'::regclass;
0 | -1 | 0
(1 row)
--- invalid relkinds for statistics
-CREATE SEQUENCE stats_import.testseq;
-CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
-SELECT
- pg_catalog.pg_clear_relation_stats(
- 'stats_import.testseq'::regclass);
-ERROR: cannot modify statistics for relation "testseq"
-DETAIL: This operation is not supported for sequences.
-SELECT
- pg_catalog.pg_clear_relation_stats(
- 'stats_import.testview'::regclass);
-ERROR: cannot modify statistics for relation "testview"
-DETAIL: This operation is not supported for views.
-- relpages may be -1 for partitioned tables
CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i);
CREATE TABLE stats_import.part_child_1
@@ -200,21 +95,21 @@ WHERE oid = 'stats_import.part_parent'::regclass;
-- although partitioned tables have no storage, setting relpages to a
-- positive value is still allowed
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.part_parent_i'::regclass,
- relpages => 2::integer);
- pg_set_relation_stats
------------------------
-
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.part_parent_i'::regclass,
+ 'relpages', 2::integer);
+ pg_restore_relation_stats
+---------------------------
+ t
(1 row)
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.part_parent'::regclass,
- relpages => 2::integer);
- pg_set_relation_stats
------------------------
-
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.part_parent'::regclass,
+ 'relpages', 2::integer);
+ pg_restore_relation_stats
+---------------------------
+ t
(1 row)
--
@@ -225,12 +120,12 @@ SELECT
--
BEGIN;
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.part_parent_i'::regclass,
- relpages => 2::integer);
- pg_set_relation_stats
------------------------
-
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.part_parent_i'::regclass,
+ 'relpages', 2::integer);
+ pg_restore_relation_stats
+---------------------------
+ t
(1 row)
SELECT mode FROM pg_locks
@@ -261,527 +156,14 @@ SELECT
-- nothing stops us from setting it to -1
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.part_parent'::regclass,
- relpages => -1::integer);
- pg_set_relation_stats
------------------------
-
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.part_parent'::regclass,
+ 'relpages', -1::integer);
+ pg_restore_relation_stats
+---------------------------
+ t
(1 row)
--- error: object doesn't exist
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => '0'::oid,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-ERROR: could not open relation with OID 0
--- error: object doesn't exist
-SELECT pg_catalog.pg_clear_attribute_stats(
- relation => '0'::oid,
- attname => 'id'::name,
- inherited => false::boolean);
-ERROR: could not open relation with OID 0
--- error: relation null
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => NULL::oid,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-ERROR: "relation" cannot be NULL
--- error: attribute is system column
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'xmin'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-ERROR: cannot modify statistics on system column "xmin"
--- error: attname doesn't exist
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'nope'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-ERROR: column "nope" of relation "test" does not exist
--- error: attribute is system column
-SELECT pg_catalog.pg_clear_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'ctid'::name,
- inherited => false::boolean);
-ERROR: cannot clear statistics on system column "ctid"
--- error: attname doesn't exist
-SELECT pg_catalog.pg_clear_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'nope'::name,
- inherited => false::boolean);
-ERROR: column "nope" of relation "test" does not exist
--- error: attname null
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => NULL::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-ERROR: "attname" cannot be NULL
--- error: inherited null
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => NULL::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-ERROR: "inherited" cannot be NULL
--- ok: no stakinds
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
- pg_set_attribute_stats
-------------------------
-
-(1 row)
-
-SELECT stanullfrac, stawidth, stadistinct
-FROM pg_statistic
-WHERE starelid = 'stats_import.test'::regclass;
- stanullfrac | stawidth | stadistinct
--------------+----------+-------------
- 0.1 | 2 | 0.3
-(1 row)
-
--- error: mcv / mcf null mismatch
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_freqs => '{0.1,0.2,0.3}'::real[]
- );
-ERROR: "most_common_vals" must be specified when "most_common_freqs" is specified
--- error: mcv / mcf null mismatch part 2
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{1,2,3}'::text
- );
-ERROR: "most_common_freqs" must be specified when "most_common_vals" is specified
--- error: mcv / mcf type mismatch
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{2023-09-30,2024-10-31,3}'::text,
- most_common_freqs => '{0.2,0.1}'::real[]
- );
-ERROR: invalid input syntax for type integer: "2023-09-30"
--- error: mcv cast failure
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{2,four,3}'::text,
- most_common_freqs => '{0.3,0.25,0.05}'::real[]
- );
-ERROR: invalid input syntax for type integer: "four"
--- ok: mcv+mcf
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{2,1,3}'::text,
- most_common_freqs => '{0.3,0.25,0.05}'::real[]
- );
- pg_set_attribute_stats
-------------------------
-
-(1 row)
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'id';
- schemaname | tablename | 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
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test | id | f | 0.5 | 2 | -0.1 | {2,1,3} | {0.3,0.25,0.05} | | | | | | | |
-(1 row)
-
--- error: histogram elements null value
--- this generates no warnings, but perhaps it should
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- histogram_bounds => '{1,NULL,3,4}'::text
- );
-ERROR: "histogram_bounds" array cannot contain NULL values
--- ok: histogram_bounds
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- histogram_bounds => '{1,2,3,4}'::text
- );
- pg_set_attribute_stats
-------------------------
-
-(1 row)
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'id';
- schemaname | tablename | 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
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test | id | f | 0.5 | 2 | -0.1 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | |
-(1 row)
-
--- ok: correlation
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- correlation => 0.5::real);
- pg_set_attribute_stats
-------------------------
-
-(1 row)
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'id';
- schemaname | tablename | 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
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test | id | f | 0.5 | 2 | -0.1 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | 0.5 | | | | | |
-(1 row)
-
--- error: scalars can't have mcelem
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_elems => '{1,3}'::text,
- most_common_elem_freqs => '{0.3,0.2,0.2,0.3,0.0}'::real[]
- );
-ERROR: unable to determine element type of attribute "id"
-DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
--- error: mcelem / mcelem mismatch
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_elems => '{one,two}'::text
- );
-ERROR: "most_common_elem_freqs" must be specified when "most_common_elems" is specified
--- error: mcelem / mcelem null mismatch part 2
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_elem_freqs => '{0.3,0.2,0.2,0.3}'::real[]
- );
-ERROR: "most_common_elems" must be specified when "most_common_elem_freqs" is specified
--- ok: mcelem
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_elems => '{one,three}'::text,
- most_common_elem_freqs => '{0.3,0.2,0.2,0.3,0.0}'::real[]
- );
- pg_set_attribute_stats
-------------------------
-
-(1 row)
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'tags';
- schemaname | tablename | 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
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test | tags | f | 0.5 | 2 | -0.1 | | | | | {one,three} | {0.3,0.2,0.2,0.3,0} | | | |
-(1 row)
-
--- error: scalars can't have elem_count_histogram
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- elem_count_histogram => '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
- );
-ERROR: unable to determine element type of attribute "id"
-DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
--- error: elem_count_histogram null element
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- elem_count_histogram => '{1,1,NULL,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
- );
-ERROR: "elem_count_histogram" array cannot contain NULL values
--- ok: elem_count_histogram
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- elem_count_histogram => '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
- );
- pg_set_attribute_stats
-------------------------
-
-(1 row)
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'tags';
- schemaname | tablename | 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
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
- stats_import | test | tags | f | 0.5 | 2 | -0.1 | | | | | {one,three} | {0.3,0.2,0.2,0.3,0} | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | |
-(1 row)
-
--- error: scalars can't have range stats
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_empty_frac => 0.5::real,
- range_length_histogram => '{399,499,Infinity}'::text
- );
-ERROR: attribute "id" is not a range type
-DETAIL: Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.
--- error: range_empty_frac range_length_hist null mismatch
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_length_histogram => '{399,499,Infinity}'::text
- );
-ERROR: "range_empty_frac" must be specified when "range_length_histogram" is specified
--- error: range_empty_frac range_length_hist null mismatch part 2
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_empty_frac => 0.5::real
- );
-ERROR: "range_length_histogram" must be specified when "range_empty_frac" is specified
--- ok: range_empty_frac + range_length_hist
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_empty_frac => 0.5::real,
- range_length_histogram => '{399,499,Infinity}'::text
- );
- pg_set_attribute_stats
-------------------------
-
-(1 row)
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'arange';
- schemaname | tablename | 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
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
- stats_import | test | arange | f | 0.5 | 2 | -0.1 | | | | | | | | {399,499,Infinity} | 0.5 |
-(1 row)
-
--- error: scalars can't have range stats
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_bounds_histogram => '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
- );
-ERROR: attribute "id" is not a range type
-DETAIL: Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.
--- ok: range_bounds_histogram
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_bounds_histogram => '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
- );
- pg_set_attribute_stats
-------------------------
-
-(1 row)
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'arange';
- schemaname | tablename | 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
---------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
- stats_import | test | arange | f | 0.5 | 2 | -0.1 | | | | | | | | {399,499,Infinity} | 0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
-(1 row)
-
--- error: cannot set most_common_elems for range type
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{"[2,3)","[1,2)","[3,4)"}'::text,
- most_common_freqs => '{0.3,0.25,0.05}'::real[],
- histogram_bounds => '{"[1,2)","[2,3)","[3,4)","[4,5)"}'::text,
- correlation => 1.1::real,
- most_common_elems => '{3,1}'::text,
- most_common_elem_freqs => '{0.3,0.2,0.2,0.3,0.0}'::real[],
- range_empty_frac => -0.5::real,
- range_length_histogram => '{399,499,Infinity}'::text,
- range_bounds_histogram => '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
- );
-ERROR: unable to determine element type of attribute "arange"
-DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
---
--- Clear attribute stats to try again with restore functions
--- (relation stats were already cleared).
---
-SELECT
- pg_catalog.pg_clear_attribute_stats(
- 'stats_import.test'::regclass,
- s.attname,
- s.inherited)
-FROM pg_catalog.pg_stats AS s
-WHERE s.schemaname = 'stats_import'
-AND s.tablename = 'test'
-ORDER BY s.attname, s.inherited;
- pg_clear_attribute_stats
---------------------------
-
-
-
-(3 rows)
-
--- reject: argument name is NULL
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- NULL, '17'::integer,
- 'reltuples', 400::real,
- 'relallvisible', 4::integer);
-ERROR: name at variadic position 5 is NULL
--- reject: argument name is an integer
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- 17, '17'::integer,
- 'reltuples', 400::real,
- 'relallvisible', 4::integer);
-ERROR: name at variadic position 5 has type "integer", expected type "text"
--- reject: odd number of variadic arguments cannot be pairs
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- 'relpages', '17'::integer,
- 'reltuples', 400::real,
- 'relallvisible');
-ERROR: variadic arguments must be name/value pairs
-HINT: Provide an even number of variadic arguments that can be divided into pairs.
--- reject: object doesn't exist
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- 'relpages', '17'::integer,
- 'reltuples', 400::real,
- 'relallvisible', 4::integer);
-ERROR: could not open relation with OID 0
-- ok: set all stats
SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass,
@@ -856,15 +238,6 @@ WHERE oid = 'stats_import.test'::regclass;
16 | 500 | 5
(1 row)
--- warn and error: unrecognized argument name
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- 'relpages', '17'::integer,
- 'reltuples', 400::real,
- 'nope', 4::integer);
-WARNING: unrecognized argument name: "nope"
-ERROR: could not open relation with OID 0
-- warn: bad relpages type
SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass,
@@ -886,56 +259,19 @@ WHERE oid = 'stats_import.test'::regclass;
16 | 400 | 4
(1 row)
--- error: object does not exist
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', '0'::oid::regclass,
- 'attname', 'id'::name,
- 'inherited', false::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-ERROR: could not open relation with OID 0
--- error: relation null
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', NULL::oid,
- 'attname', 'id'::name,
- 'inherited', false::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-ERROR: "relation" cannot be NULL
--- error: attname null
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', 'stats_import.test'::regclass,
- 'attname', NULL::name,
- 'inherited', false::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-ERROR: "attname" cannot be NULL
--- error: attname doesn't exist
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', 'stats_import.test'::regclass,
- 'attname', 'nope'::name,
- 'inherited', false::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-ERROR: column "nope" of relation "test" does not exist
--- error: inherited null
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', 'stats_import.test'::regclass,
- 'attname', 'id'::name,
- 'inherited', NULL::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-ERROR: "inherited" cannot be NULL
+-- invalid relkinds for statistics
+CREATE SEQUENCE stats_import.testseq;
+CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
+SELECT
+ pg_catalog.pg_clear_relation_stats(
+ 'stats_import.testseq'::regclass);
+ERROR: cannot modify statistics for relation "testseq"
+DETAIL: This operation is not supported for sequences.
+SELECT
+ pg_catalog.pg_clear_relation_stats(
+ 'stats_import.testview'::regclass);
+ERROR: cannot modify statistics for relation "testview"
+DETAIL: This operation is not supported for views.
-- ok: no stakinds
SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass,
@@ -1409,6 +745,169 @@ AND attname = 'arange';
stats_import | test | arange | f | 0.2 | 3 | -0.39 | | | | | | | | {399,499,Infinity} | 0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
(1 row)
+-- warn: cannot set most_common_elems for range type
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'arange'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_vals', '{"[2,3)","[1,2)","[3,4)"}'::text,
+ 'most_common_freqs', '{0.3,0.25,0.05}'::real[],
+ 'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,5)"}'::text,
+ 'correlation', 1.1::real,
+ 'most_common_elems', '{3,1}'::text,
+ 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[],
+ 'range_empty_frac', -0.5::real,
+ 'range_length_histogram', '{399,499,Infinity}'::text,
+ 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
+ );
+WARNING: unable to determine element type of attribute "arange"
+DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
+ pg_restore_attribute_stats
+----------------------------
+ f
+(1 row)
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'arange';
+ schemaname | tablename | 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
+--------------+-----------+---------+-----------+-----------+-----------+------------+---------------------------+-------------------+-----------------------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test | arange | f | 0.5 | 2 | -0.1 | {"[2,3)","[1,2)","[3,4)"} | {0.3,0.25,0.05} | {"[1,2)","[2,3)","[3,4)","[4,5)"} | 1.1 | | | | {399,499,Infinity} | -0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+(1 row)
+
+-- warn: scalars can't have mcelem
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'id'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_elems', '{1,3}'::text,
+ 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
+ );
+WARNING: unable to determine element type of attribute "id"
+DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
+ pg_restore_attribute_stats
+----------------------------
+ f
+(1 row)
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'id';
+ schemaname | tablename | 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
+--------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test | id | f | 0.5 | 2 | -0.1 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | |
+(1 row)
+
+-- warn: mcelem / mcelem mismatch
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'tags'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_elems', '{one,two}'::text
+ );
+WARNING: "most_common_elem_freqs" must be specified when "most_common_elems" is specified
+ pg_restore_attribute_stats
+----------------------------
+ f
+(1 row)
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'tags';
+ schemaname | tablename | 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
+--------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test | tags | f | 0.5 | 2 | -0.1 | | | | | | | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | |
+(1 row)
+
+-- warn: mcelem / mcelem null mismatch part 2
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'tags'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
+ );
+WARNING: "most_common_elems" must be specified when "most_common_elem_freqs" is specified
+ pg_restore_attribute_stats
+----------------------------
+ f
+(1 row)
+
+-- ok: mcelem
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'tags'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_elems', '{one,three}'::text,
+ 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
+ );
+ pg_restore_attribute_stats
+----------------------------
+ t
+(1 row)
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'tags';
+ schemaname | tablename | 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
+--------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+------------------+------------------------
+ stats_import | test | tags | f | 0.5 | 2 | -0.1 | | | | | {one,three} | {0.3,0.2,0.2,0.3,0} | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} | | |
+(1 row)
+
+-- warn: scalars can't have elem_count_histogram
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'id'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
+ );
+WARNING: unable to determine element type of attribute "id"
+DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
+ pg_restore_attribute_stats
+----------------------------
+ f
+(1 row)
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'id';
+ schemaname | tablename | 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
+--------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+------------------------
+ stats_import | test | id | f | 0.5 | 2 | -0.1 | {2,1,3} | {0.3,0.25,0.05} | {1,2,3,4} | | | | | | |
+(1 row)
+
-- warn: too many stat kinds
SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass,
@@ -1434,6 +933,17 @@ DETAIL: Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.
f
(1 row)
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'arange';
+ schemaname | tablename | 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
+--------------+-----------+---------+-----------+-----------+-----------+------------+---------------------------+-------------------+----------------------------------+-------------+-------------------+------------------------+----------------------+------------------------+------------------+--------------------------------------
+ stats_import | test | arange | f | 0.5 | 2 | -0.1 | {"[2,3)","[1,3)","[3,9)"} | {0.3,0.25,0.05} | {"[1,2)","[2,3)","[3,4)","[4,)"} | 1.1 | | | | {399,499,Infinity} | -0.5 | {"[-1,1)","[0,4)","[1,4)","[1,100)"}
+(1 row)
+
--
-- Test the ability to exactly copy data from one table to an identical table,
-- correctly reconstructing the stakind order as well as the staopN and
@@ -1472,216 +982,6 @@ CREATE INDEX is_odd_clone ON stats_import.test_clone(((comp).a % 2 = 1));
--
-- Copy stats from test to test_clone, and is_odd to is_odd_clone
--
-SELECT s.schemaname, s.tablename, s.attname, s.inherited
-FROM pg_catalog.pg_stats AS s
-CROSS JOIN LATERAL
- pg_catalog.pg_set_attribute_stats(
- relation => ('stats_import.' || s.tablename || '_clone')::regclass::oid,
- attname => s.attname,
- inherited => s.inherited,
- null_frac => s.null_frac,
- avg_width => s.avg_width,
- n_distinct => s.n_distinct,
- most_common_vals => s.most_common_vals::text,
- most_common_freqs => s.most_common_freqs,
- histogram_bounds => s.histogram_bounds::text,
- correlation => s.correlation,
- most_common_elems => s.most_common_elems::text,
- most_common_elem_freqs => s.most_common_elem_freqs,
- elem_count_histogram => s.elem_count_histogram,
- range_bounds_histogram => s.range_bounds_histogram::text,
- range_empty_frac => s.range_empty_frac,
- range_length_histogram => s.range_length_histogram::text) AS r
-WHERE s.schemaname = 'stats_import'
-AND s.tablename IN ('test', 'is_odd')
-ORDER BY s.tablename, s.attname, s.inherited;
- schemaname | tablename | attname | inherited
---------------+-----------+---------+-----------
- stats_import | is_odd | expr | f
- stats_import | test | arange | f
- stats_import | test | comp | f
- stats_import | test | id | f
- stats_import | test | name | f
- stats_import | test | tags | f
-(6 rows)
-
-SELECT c.relname, COUNT(*) AS num_stats
-FROM pg_class AS c
-JOIN pg_statistic s ON s.starelid = c.oid
-WHERE c.relnamespace = 'stats_import'::regnamespace
-AND c.relname IN ('test', 'test_clone', 'is_odd', 'is_odd_clone')
-GROUP BY c.relname
-ORDER BY c.relname;
- relname | num_stats
---------------+-----------
- is_odd | 1
- is_odd_clone | 1
- test | 5
- test_clone | 5
-(4 rows)
-
--- check test minus test_clone
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'test' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.test'::regclass
-EXCEPT
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'test' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.test_clone'::regclass;
- attname | stainherit | stanullfrac | stawidth | stadistinct | stakind1 | stakind2 | stakind3 | stakind4 | stakind5 | staop1 | staop2 | staop3 | staop4 | staop5 | stacoll1 | stacoll2 | stacoll3 | stacoll4 | stacoll5 | stanumbers1 | stanumbers2 | stanumbers3 | stanumbers4 | stanumbers5 | sv1 | sv2 | sv3 | sv4 | sv5 | direction
----------+------------+-------------+----------+-------------+----------+----------+----------+----------+----------+--------+--------+--------+--------+--------+----------+----------+----------+----------+----------+-------------+-------------+-------------+-------------+-------------+-----+-----+-----+-----+-----+-----------
-(0 rows)
-
--- check test_clone minus test
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'test_clone' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.test_clone'::regclass
-EXCEPT
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'test_clone' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.test'::regclass;
- attname | stainherit | stanullfrac | stawidth | stadistinct | stakind1 | stakind2 | stakind3 | stakind4 | stakind5 | staop1 | staop2 | staop3 | staop4 | staop5 | stacoll1 | stacoll2 | stacoll3 | stacoll4 | stacoll5 | stanumbers1 | stanumbers2 | stanumbers3 | stanumbers4 | stanumbers5 | sv1 | sv2 | sv3 | sv4 | sv5 | direction
----------+------------+-------------+----------+-------------+----------+----------+----------+----------+----------+--------+--------+--------+--------+--------+----------+----------+----------+----------+----------+-------------+-------------+-------------+-------------+-------------+-----+-----+-----+-----+-----+-----------
-(0 rows)
-
--- check is_odd minus is_odd_clone
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'is_odd' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.is_odd'::regclass
-EXCEPT
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'is_odd' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.is_odd_clone'::regclass;
- attname | stainherit | stanullfrac | stawidth | stadistinct | stakind1 | stakind2 | stakind3 | stakind4 | stakind5 | staop1 | staop2 | staop3 | staop4 | staop5 | stacoll1 | stacoll2 | stacoll3 | stacoll4 | stacoll5 | stanumbers1 | stanumbers2 | stanumbers3 | stanumbers4 | stanumbers5 | sv1 | sv2 | sv3 | sv4 | sv5 | direction
----------+------------+-------------+----------+-------------+----------+----------+----------+----------+----------+--------+--------+--------+--------+--------+----------+----------+----------+----------+----------+-------------+-------------+-------------+-------------+-------------+-----+-----+-----+-----+-----+-----------
-(0 rows)
-
--- check is_odd_clone minus is_odd
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'is_odd_clone' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.is_odd_clone'::regclass
-EXCEPT
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'is_odd_clone' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.is_odd'::regclass;
- attname | stainherit | stanullfrac | stawidth | stadistinct | stakind1 | stakind2 | stakind3 | stakind4 | stakind5 | staop1 | staop2 | staop3 | staop4 | staop5 | stacoll1 | stacoll2 | stacoll3 | stacoll4 | stacoll5 | stanumbers1 | stanumbers2 | stanumbers3 | stanumbers4 | stanumbers5 | sv1 | sv2 | sv3 | sv4 | sv5 | direction
----------+------------+-------------+----------+-------------+----------+----------+----------+----------+----------+--------+--------+--------+--------+--------+----------+----------+----------+----------+----------+-------------+-------------+-------------+-------------+-------------+-----+-----+-----+-----+-----+-----------
-(0 rows)
-
---
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
- relpages | reltuples | relallvisible
-----------+-----------+---------------
- 1 | 4 | 0
-(1 row)
-
---
--- Clear clone stats to try again with pg_restore_attribute_stats
---
-SELECT
- pg_catalog.pg_clear_attribute_stats(
- ('stats_import.' || s.tablename)::regclass,
- s.attname,
- s.inherited)
-FROM pg_catalog.pg_stats AS s
-WHERE s.schemaname = 'stats_import'
-AND s.tablename IN ('test_clone', 'is_odd_clone')
-ORDER BY s.tablename, s.attname, s.inherited;
- pg_clear_attribute_stats
---------------------------
-
-
-
-
-
-
-(6 rows)
-
-SELECT
-SELECT COUNT(*)
-FROM pg_catalog.pg_stats AS s
-WHERE s.schemaname = 'stats_import'
-AND s.tablename IN ('test_clone', 'is_odd_clone');
-ERROR: syntax error at or near "SELECT"
-LINE 2: SELECT COUNT(*)
- ^
---
--- Copy stats from test to test_clone, and is_odd to is_odd_clone
---
SELECT s.schemaname, s.tablename, s.attname, s.inherited, r.*
FROM pg_catalog.pg_stats AS s
CROSS JOIN LATERAL
@@ -1851,11 +1151,158 @@ WHERE s.starelid = 'stats_import.is_odd'::regclass;
---------+------------+-------------+----------+-------------+----------+----------+----------+----------+----------+--------+--------+--------+--------+--------+----------+----------+----------+----------+----------+-------------+-------------+-------------+-------------+-------------+-----+-----+-----+-----+-----+-----------
(0 rows)
+-- ok
+SELECT pg_catalog.pg_clear_attribute_stats(
+ relation => 'stats_import.test'::regclass,
+ attname => 'arange'::name,
+ inherited => false::boolean);
+ pg_clear_attribute_stats
+--------------------------
+
+(1 row)
+
+--
+-- Negative tests
+--
+--- error: relation is wrong type
+SELECT pg_catalog.pg_restore_relation_stats(
+ 'relation', 0::oid,
+ 'relpages', 17::integer,
+ 'reltuples', 400.0::real,
+ 'relallvisible', 4::integer);
+WARNING: argument "relation" has type "oid", expected type "regclass"
+ERROR: "relation" cannot be NULL
+--- error: relation not found
+SELECT pg_catalog.pg_restore_relation_stats(
+ 'relation', 0::regclass,
+ 'relpages', 17::integer,
+ 'reltuples', 400.0::real,
+ 'relallvisible', 4::integer);
+ERROR: could not open relation with OID 0
+-- warn and error: unrecognized argument name
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ 'relpages', '17'::integer,
+ 'reltuples', 400::real,
+ 'nope', 4::integer);
+WARNING: unrecognized argument name: "nope"
+ERROR: could not open relation with OID 0
+-- error: argument name is NULL
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ NULL, '17'::integer,
+ 'reltuples', 400::real,
+ 'relallvisible', 4::integer);
+ERROR: name at variadic position 5 is NULL
+-- error: argument name is an integer
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ 17, '17'::integer,
+ 'reltuples', 400::real,
+ 'relallvisible', 4::integer);
+ERROR: name at variadic position 5 has type "integer", expected type "text"
+-- error: odd number of variadic arguments cannot be pairs
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ 'relpages', '17'::integer,
+ 'reltuples', 400::real,
+ 'relallvisible');
+ERROR: variadic arguments must be name/value pairs
+HINT: Provide an even number of variadic arguments that can be divided into pairs.
+-- error: object doesn't exist
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ 'relpages', '17'::integer,
+ 'reltuples', 400::real,
+ 'relallvisible', 4::integer);
+ERROR: could not open relation with OID 0
+-- error: object does not exist
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', '0'::oid::regclass,
+ 'attname', 'id'::name,
+ 'inherited', false::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+ERROR: could not open relation with OID 0
+-- error: relation null
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', NULL::oid,
+ 'attname', 'id'::name,
+ 'inherited', false::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+ERROR: "relation" cannot be NULL
+-- error: attname null
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', NULL::name,
+ 'inherited', false::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+ERROR: "attname" cannot be NULL
+-- error: attname doesn't exist
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'nope'::name,
+ 'inherited', false::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+ERROR: column "nope" of relation "test" does not exist
+-- error: attribute is system column
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'xmin'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+ERROR: cannot modify statistics on system column "xmin"
+-- error: inherited null
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'id'::name,
+ 'inherited', NULL::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+ERROR: "inherited" cannot be NULL
+-- error: relation not found
+SELECT pg_catalog.pg_clear_relation_stats(
+ relation => 'stats_import.nope'::regclass);
+ERROR: relation "stats_import.nope" does not exist
+LINE 2: relation => 'stats_import.nope'::regclass);
+ ^
+-- error: attribute is system column
+SELECT pg_catalog.pg_clear_attribute_stats(
+ relation => 'stats_import.test'::regclass,
+ attname => 'ctid'::name,
+ inherited => false::boolean);
+ERROR: cannot clear statistics on system column "ctid"
+-- error: attname doesn't exist
+SELECT pg_catalog.pg_clear_attribute_stats(
+ relation => 'stats_import.test'::regclass,
+ attname => 'nope'::name,
+ inherited => false::boolean);
+ERROR: column "nope" of relation "test" does not exist
DROP SCHEMA stats_import CASCADE;
NOTICE: drop cascades to 6 other objects
DETAIL: drop cascades to type stats_import.complex_type
drop cascades to table stats_import.test
+drop cascades to table stats_import.part_parent
drop cascades to sequence stats_import.testseq
drop cascades to view stats_import.testview
-drop cascades to table stats_import.part_parent
drop cascades to table stats_import.test_clone
diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql
index 9740ab3ff02..57422750b90 100644
--- a/src/test/regress/sql/stats_import.sql
+++ b/src/test/regress/sql/stats_import.sql
@@ -15,63 +15,19 @@ CREATE TABLE stats_import.test(
tags text[]
) WITH (autovacuum_enabled = false);
+CREATE INDEX test_i ON stats_import.test(id);
+
-- starting stats
SELECT relpages, reltuples, relallvisible
FROM pg_class
WHERE oid = 'stats_import.test'::regclass;
--- error: regclass not found
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 0::Oid,
- relpages => 17::integer,
- reltuples => 400.0::real,
- relallvisible => 4::integer);
-
--- relpages default
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => NULL::integer,
- reltuples => 400.0::real,
- relallvisible => 4::integer);
-
--- reltuples default
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => 17::integer,
- reltuples => NULL::real,
- relallvisible => 4::integer);
-
--- relallvisible default
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => 17::integer,
- reltuples => 400.0::real,
- relallvisible => NULL::integer);
-
--- named arguments
-SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test'::regclass,
- relpages => 17::integer,
- reltuples => 400.0::real,
- relallvisible => 4::integer);
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
-
-CREATE INDEX test_i ON stats_import.test(id);
-
BEGIN;
-- regular indexes have special case locking rules
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.test_i'::regclass,
- relpages => 18::integer);
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.test_i'::regclass,
+ 'relpages', 18::integer);
SELECT mode FROM pg_locks
WHERE relation = 'stats_import.test'::regclass AND
@@ -88,22 +44,6 @@ SELECT
'relation', 'stats_import.test_i'::regclass,
'relpages', 19::integer );
--- positional arguments
-SELECT
- pg_catalog.pg_set_relation_stats(
- 'stats_import.test'::regclass,
- 18::integer,
- 401.0::real,
- 5::integer);
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
-
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
-
-- clear
SELECT
pg_catalog.pg_clear_relation_stats(
@@ -113,16 +53,6 @@ SELECT relpages, reltuples, relallvisible
FROM pg_class
WHERE oid = 'stats_import.test'::regclass;
--- invalid relkinds for statistics
-CREATE SEQUENCE stats_import.testseq;
-CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
-SELECT
- pg_catalog.pg_clear_relation_stats(
- 'stats_import.testseq'::regclass);
-SELECT
- pg_catalog.pg_clear_relation_stats(
- 'stats_import.testview'::regclass);
-
-- relpages may be -1 for partitioned tables
CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i);
CREATE TABLE stats_import.part_child_1
@@ -141,14 +71,14 @@ WHERE oid = 'stats_import.part_parent'::regclass;
-- although partitioned tables have no storage, setting relpages to a
-- positive value is still allowed
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.part_parent_i'::regclass,
- relpages => 2::integer);
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.part_parent_i'::regclass,
+ 'relpages', 2::integer);
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.part_parent'::regclass,
- relpages => 2::integer);
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.part_parent'::regclass,
+ 'relpages', 2::integer);
--
-- Partitioned indexes aren't analyzed but it is possible to set
@@ -159,9 +89,9 @@ SELECT
BEGIN;
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.part_parent_i'::regclass,
- relpages => 2::integer);
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.part_parent_i'::regclass,
+ 'relpages', 2::integer);
SELECT mode FROM pg_locks
WHERE relation = 'stats_import.part_parent'::regclass AND
@@ -180,440 +110,9 @@ SELECT
-- nothing stops us from setting it to -1
SELECT
- pg_catalog.pg_set_relation_stats(
- relation => 'stats_import.part_parent'::regclass,
- relpages => -1::integer);
-
--- error: object doesn't exist
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => '0'::oid,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-
--- error: object doesn't exist
-SELECT pg_catalog.pg_clear_attribute_stats(
- relation => '0'::oid,
- attname => 'id'::name,
- inherited => false::boolean);
-
--- error: relation null
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => NULL::oid,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-
--- error: attribute is system column
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'xmin'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-
--- error: attname doesn't exist
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'nope'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-
--- error: attribute is system column
-SELECT pg_catalog.pg_clear_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'ctid'::name,
- inherited => false::boolean);
-
--- error: attname doesn't exist
-SELECT pg_catalog.pg_clear_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'nope'::name,
- inherited => false::boolean);
-
--- error: attname null
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => NULL::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-
--- error: inherited null
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => NULL::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-
--- ok: no stakinds
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.1::real,
- avg_width => 2::integer,
- n_distinct => 0.3::real);
-
-SELECT stanullfrac, stawidth, stadistinct
-FROM pg_statistic
-WHERE starelid = 'stats_import.test'::regclass;
-
--- error: mcv / mcf null mismatch
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_freqs => '{0.1,0.2,0.3}'::real[]
- );
-
--- error: mcv / mcf null mismatch part 2
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{1,2,3}'::text
- );
-
--- error: mcv / mcf type mismatch
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{2023-09-30,2024-10-31,3}'::text,
- most_common_freqs => '{0.2,0.1}'::real[]
- );
-
--- error: mcv cast failure
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{2,four,3}'::text,
- most_common_freqs => '{0.3,0.25,0.05}'::real[]
- );
-
--- ok: mcv+mcf
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{2,1,3}'::text,
- most_common_freqs => '{0.3,0.25,0.05}'::real[]
- );
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'id';
-
--- error: histogram elements null value
--- this generates no warnings, but perhaps it should
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- histogram_bounds => '{1,NULL,3,4}'::text
- );
-
--- ok: histogram_bounds
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- histogram_bounds => '{1,2,3,4}'::text
- );
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'id';
-
--- ok: correlation
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- correlation => 0.5::real);
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'id';
-
--- error: scalars can't have mcelem
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_elems => '{1,3}'::text,
- most_common_elem_freqs => '{0.3,0.2,0.2,0.3,0.0}'::real[]
- );
-
--- error: mcelem / mcelem mismatch
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_elems => '{one,two}'::text
- );
-
--- error: mcelem / mcelem null mismatch part 2
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_elem_freqs => '{0.3,0.2,0.2,0.3}'::real[]
- );
-
--- ok: mcelem
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_elems => '{one,three}'::text,
- most_common_elem_freqs => '{0.3,0.2,0.2,0.3,0.0}'::real[]
- );
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'tags';
-
--- error: scalars can't have elem_count_histogram
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- elem_count_histogram => '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
- );
--- error: elem_count_histogram null element
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- elem_count_histogram => '{1,1,NULL,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
- );
--- ok: elem_count_histogram
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'tags'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- elem_count_histogram => '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
- );
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'tags';
-
--- error: scalars can't have range stats
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_empty_frac => 0.5::real,
- range_length_histogram => '{399,499,Infinity}'::text
- );
--- error: range_empty_frac range_length_hist null mismatch
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_length_histogram => '{399,499,Infinity}'::text
- );
--- error: range_empty_frac range_length_hist null mismatch part 2
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_empty_frac => 0.5::real
- );
--- ok: range_empty_frac + range_length_hist
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_empty_frac => 0.5::real,
- range_length_histogram => '{399,499,Infinity}'::text
- );
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'arange';
-
--- error: scalars can't have range stats
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'id'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_bounds_histogram => '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
- );
--- ok: range_bounds_histogram
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- range_bounds_histogram => '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
- );
-
-SELECT *
-FROM pg_stats
-WHERE schemaname = 'stats_import'
-AND tablename = 'test'
-AND inherited = false
-AND attname = 'arange';
-
--- error: cannot set most_common_elems for range type
-SELECT pg_catalog.pg_set_attribute_stats(
- relation => 'stats_import.test'::regclass,
- attname => 'arange'::name,
- inherited => false::boolean,
- null_frac => 0.5::real,
- avg_width => 2::integer,
- n_distinct => -0.1::real,
- most_common_vals => '{"[2,3)","[1,2)","[3,4)"}'::text,
- most_common_freqs => '{0.3,0.25,0.05}'::real[],
- histogram_bounds => '{"[1,2)","[2,3)","[3,4)","[4,5)"}'::text,
- correlation => 1.1::real,
- most_common_elems => '{3,1}'::text,
- most_common_elem_freqs => '{0.3,0.2,0.2,0.3,0.0}'::real[],
- range_empty_frac => -0.5::real,
- range_length_histogram => '{399,499,Infinity}'::text,
- range_bounds_histogram => '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
- );
-
---
--- Clear attribute stats to try again with restore functions
--- (relation stats were already cleared).
---
-SELECT
- pg_catalog.pg_clear_attribute_stats(
- 'stats_import.test'::regclass,
- s.attname,
- s.inherited)
-FROM pg_catalog.pg_stats AS s
-WHERE s.schemaname = 'stats_import'
-AND s.tablename = 'test'
-ORDER BY s.attname, s.inherited;
-
--- reject: argument name is NULL
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- NULL, '17'::integer,
- 'reltuples', 400::real,
- 'relallvisible', 4::integer);
-
--- reject: argument name is an integer
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- 17, '17'::integer,
- 'reltuples', 400::real,
- 'relallvisible', 4::integer);
-
--- reject: odd number of variadic arguments cannot be pairs
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- 'relpages', '17'::integer,
- 'reltuples', 400::real,
- 'relallvisible');
-
--- reject: object doesn't exist
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- 'relpages', '17'::integer,
- 'reltuples', 400::real,
- 'relallvisible', 4::integer);
+ pg_catalog.pg_restore_relation_stats(
+ 'relation', 'stats_import.part_parent'::regclass,
+ 'relpages', -1::integer);
-- ok: set all stats
SELECT pg_restore_relation_stats(
@@ -657,14 +156,6 @@ SELECT relpages, reltuples, relallvisible
FROM pg_class
WHERE oid = 'stats_import.test'::regclass;
--- warn and error: unrecognized argument name
-SELECT pg_restore_relation_stats(
- 'relation', '0'::oid::regclass,
- 'version', 150000::integer,
- 'relpages', '17'::integer,
- 'reltuples', 400::real,
- 'nope', 4::integer);
-
-- warn: bad relpages type
SELECT pg_restore_relation_stats(
'relation', 'stats_import.test'::regclass,
@@ -677,55 +168,15 @@ SELECT relpages, reltuples, relallvisible
FROM pg_class
WHERE oid = 'stats_import.test'::regclass;
--- error: object does not exist
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', '0'::oid::regclass,
- 'attname', 'id'::name,
- 'inherited', false::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-
--- error: relation null
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', NULL::oid,
- 'attname', 'id'::name,
- 'inherited', false::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-
--- error: attname null
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', 'stats_import.test'::regclass,
- 'attname', NULL::name,
- 'inherited', false::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-
--- error: attname doesn't exist
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', 'stats_import.test'::regclass,
- 'attname', 'nope'::name,
- 'inherited', false::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
-
--- error: inherited null
-SELECT pg_catalog.pg_restore_attribute_stats(
- 'relation', 'stats_import.test'::regclass,
- 'attname', 'id'::name,
- 'inherited', NULL::boolean,
- 'version', 150000::integer,
- 'null_frac', 0.1::real,
- 'avg_width', 2::integer,
- 'n_distinct', 0.3::real);
+-- invalid relkinds for statistics
+CREATE SEQUENCE stats_import.testseq;
+CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test;
+SELECT
+ pg_catalog.pg_clear_relation_stats(
+ 'stats_import.testseq'::regclass);
+SELECT
+ pg_catalog.pg_clear_relation_stats(
+ 'stats_import.testview'::regclass);
-- ok: no stakinds
SELECT pg_catalog.pg_restore_attribute_stats(
@@ -1050,6 +501,117 @@ AND tablename = 'test'
AND inherited = false
AND attname = 'arange';
+-- warn: cannot set most_common_elems for range type
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'arange'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_vals', '{"[2,3)","[1,2)","[3,4)"}'::text,
+ 'most_common_freqs', '{0.3,0.25,0.05}'::real[],
+ 'histogram_bounds', '{"[1,2)","[2,3)","[3,4)","[4,5)"}'::text,
+ 'correlation', 1.1::real,
+ 'most_common_elems', '{3,1}'::text,
+ 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[],
+ 'range_empty_frac', -0.5::real,
+ 'range_length_histogram', '{399,499,Infinity}'::text,
+ 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text
+ );
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'arange';
+
+-- warn: scalars can't have mcelem
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'id'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_elems', '{1,3}'::text,
+ 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
+ );
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'id';
+
+-- warn: mcelem / mcelem mismatch
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'tags'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_elems', '{one,two}'::text
+ );
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'tags';
+
+-- warn: mcelem / mcelem null mismatch part 2
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'tags'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[]
+ );
+
+-- ok: mcelem
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'tags'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'most_common_elems', '{one,three}'::text,
+ 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[]
+ );
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'tags';
+
+-- warn: scalars can't have elem_count_histogram
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'id'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.5::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', -0.1::real,
+ 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[]
+ );
+
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'id';
+
-- warn: too many stat kinds
SELECT pg_catalog.pg_restore_attribute_stats(
'relation', 'stats_import.test'::regclass,
@@ -1069,6 +631,13 @@ SELECT pg_catalog.pg_restore_attribute_stats(
'range_length_histogram', '{399,499,Infinity}'::text,
'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text);
+SELECT *
+FROM pg_stats
+WHERE schemaname = 'stats_import'
+AND tablename = 'test'
+AND inherited = false
+AND attname = 'arange';
+
--
-- Test the ability to exactly copy data from one table to an identical table,
-- correctly reconstructing the stakind order as well as the staopN and
@@ -1105,173 +674,6 @@ CREATE TABLE stats_import.test_clone ( LIKE stats_import.test )
CREATE INDEX is_odd_clone ON stats_import.test_clone(((comp).a % 2 = 1));
---
--- Copy stats from test to test_clone, and is_odd to is_odd_clone
---
-SELECT s.schemaname, s.tablename, s.attname, s.inherited
-FROM pg_catalog.pg_stats AS s
-CROSS JOIN LATERAL
- pg_catalog.pg_set_attribute_stats(
- relation => ('stats_import.' || s.tablename || '_clone')::regclass::oid,
- attname => s.attname,
- inherited => s.inherited,
- null_frac => s.null_frac,
- avg_width => s.avg_width,
- n_distinct => s.n_distinct,
- most_common_vals => s.most_common_vals::text,
- most_common_freqs => s.most_common_freqs,
- histogram_bounds => s.histogram_bounds::text,
- correlation => s.correlation,
- most_common_elems => s.most_common_elems::text,
- most_common_elem_freqs => s.most_common_elem_freqs,
- elem_count_histogram => s.elem_count_histogram,
- range_bounds_histogram => s.range_bounds_histogram::text,
- range_empty_frac => s.range_empty_frac,
- range_length_histogram => s.range_length_histogram::text) AS r
-WHERE s.schemaname = 'stats_import'
-AND s.tablename IN ('test', 'is_odd')
-ORDER BY s.tablename, s.attname, s.inherited;
-
-SELECT c.relname, COUNT(*) AS num_stats
-FROM pg_class AS c
-JOIN pg_statistic s ON s.starelid = c.oid
-WHERE c.relnamespace = 'stats_import'::regnamespace
-AND c.relname IN ('test', 'test_clone', 'is_odd', 'is_odd_clone')
-GROUP BY c.relname
-ORDER BY c.relname;
-
--- check test minus test_clone
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'test' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.test'::regclass
-EXCEPT
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'test' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.test_clone'::regclass;
-
--- check test_clone minus test
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'test_clone' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.test_clone'::regclass
-EXCEPT
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'test_clone' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.test'::regclass;
-
--- check is_odd minus is_odd_clone
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'is_odd' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.is_odd'::regclass
-EXCEPT
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'is_odd' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.is_odd_clone'::regclass;
-
--- check is_odd_clone minus is_odd
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'is_odd_clone' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.is_odd_clone'::regclass
-EXCEPT
-SELECT
- a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct,
- s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5,
- s.staop1, s.staop2, s.staop3, s.staop4, s.staop5,
- s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5,
- s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5,
- s.stavalues1::text AS sv1, s.stavalues2::text AS sv2,
- s.stavalues3::text AS sv3, s.stavalues4::text AS sv4,
- s.stavalues5::text AS sv5, 'is_odd_clone' AS direction
-FROM pg_statistic s
-JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
-WHERE s.starelid = 'stats_import.is_odd'::regclass;
-
---
-SELECT relpages, reltuples, relallvisible
-FROM pg_class
-WHERE oid = 'stats_import.test'::regclass;
-
---
--- Clear clone stats to try again with pg_restore_attribute_stats
---
-SELECT
- pg_catalog.pg_clear_attribute_stats(
- ('stats_import.' || s.tablename)::regclass,
- s.attname,
- s.inherited)
-FROM pg_catalog.pg_stats AS s
-WHERE s.schemaname = 'stats_import'
-AND s.tablename IN ('test_clone', 'is_odd_clone')
-ORDER BY s.tablename, s.attname, s.inherited;
-SELECT
-
-SELECT COUNT(*)
-FROM pg_catalog.pg_stats AS s
-WHERE s.schemaname = 'stats_import'
-AND s.tablename IN ('test_clone', 'is_odd_clone');
-
--
-- Copy stats from test to test_clone, and is_odd to is_odd_clone
--
@@ -1416,4 +818,143 @@ FROM pg_statistic s
JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum
WHERE s.starelid = 'stats_import.is_odd'::regclass;
+-- ok
+SELECT pg_catalog.pg_clear_attribute_stats(
+ relation => 'stats_import.test'::regclass,
+ attname => 'arange'::name,
+ inherited => false::boolean);
+
+--
+-- Negative tests
+--
+
+--- error: relation is wrong type
+SELECT pg_catalog.pg_restore_relation_stats(
+ 'relation', 0::oid,
+ 'relpages', 17::integer,
+ 'reltuples', 400.0::real,
+ 'relallvisible', 4::integer);
+
+--- error: relation not found
+SELECT pg_catalog.pg_restore_relation_stats(
+ 'relation', 0::regclass,
+ 'relpages', 17::integer,
+ 'reltuples', 400.0::real,
+ 'relallvisible', 4::integer);
+
+-- warn and error: unrecognized argument name
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ 'relpages', '17'::integer,
+ 'reltuples', 400::real,
+ 'nope', 4::integer);
+
+-- error: argument name is NULL
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ NULL, '17'::integer,
+ 'reltuples', 400::real,
+ 'relallvisible', 4::integer);
+
+-- error: argument name is an integer
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ 17, '17'::integer,
+ 'reltuples', 400::real,
+ 'relallvisible', 4::integer);
+
+-- error: odd number of variadic arguments cannot be pairs
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ 'relpages', '17'::integer,
+ 'reltuples', 400::real,
+ 'relallvisible');
+
+-- error: object doesn't exist
+SELECT pg_restore_relation_stats(
+ 'relation', '0'::oid::regclass,
+ 'version', 150000::integer,
+ 'relpages', '17'::integer,
+ 'reltuples', 400::real,
+ 'relallvisible', 4::integer);
+
+-- error: object does not exist
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', '0'::oid::regclass,
+ 'attname', 'id'::name,
+ 'inherited', false::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+
+-- error: relation null
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', NULL::oid,
+ 'attname', 'id'::name,
+ 'inherited', false::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+
+-- error: attname null
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', NULL::name,
+ 'inherited', false::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+
+-- error: attname doesn't exist
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'nope'::name,
+ 'inherited', false::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+
+-- error: attribute is system column
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'xmin'::name,
+ 'inherited', false::boolean,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+
+-- error: inherited null
+SELECT pg_catalog.pg_restore_attribute_stats(
+ 'relation', 'stats_import.test'::regclass,
+ 'attname', 'id'::name,
+ 'inherited', NULL::boolean,
+ 'version', 150000::integer,
+ 'null_frac', 0.1::real,
+ 'avg_width', 2::integer,
+ 'n_distinct', 0.3::real);
+
+-- error: relation not found
+SELECT pg_catalog.pg_clear_relation_stats(
+ relation => 'stats_import.nope'::regclass);
+
+-- error: attribute is system column
+SELECT pg_catalog.pg_clear_attribute_stats(
+ relation => 'stats_import.test'::regclass,
+ attname => 'ctid'::name,
+ inherited => false::boolean);
+
+-- error: attname doesn't exist
+SELECT pg_catalog.pg_clear_attribute_stats(
+ relation => 'stats_import.test'::regclass,
+ attname => 'nope'::name,
+ inherited => false::boolean);
+
DROP SCHEMA stats_import CASCADE;