mirror of
https://github.com/postgres/postgres.git
synced 2025-07-12 21:01:52 +03:00
Create functions pg_set_relation_stats, pg_clear_relation_stats.
These functions are used to tweak statistics on any relation, provided that the user has MAINTAIN privilege on the relation, or is the database owner. Bump catalog version. Author: Corey Huinker Discussion: https://postgr.es/m/CADkLM=eErgzn7ECDpwFcptJKOk9SxZEk5Pot4d94eVTZsvj3gw@mail.gmail.com
This commit is contained in:
@ -30135,6 +30135,100 @@ DETAIL: Make sure pg_wal_replay_wait() isn't called within a transaction with a
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
<xref linkend="functions-admin-statsmod"/> lists functions used to
|
||||
manipulate statistics.
|
||||
<warning>
|
||||
<para>
|
||||
Changes made by these statistics manipulation functions are likely to be
|
||||
overwritten by <link linkend="autovacuum">autovacuum</link> (or manual
|
||||
<command>VACUUM</command> or <command>ANALYZE</command>) and should be
|
||||
considered temporary.
|
||||
</para>
|
||||
</warning>
|
||||
</para>
|
||||
|
||||
<table id="functions-admin-statsmod">
|
||||
<title>Database Object Statistics Manipulation Functions</title>
|
||||
<tgroup cols="1">
|
||||
<thead>
|
||||
<row>
|
||||
<entry role="func_table_entry"><para role="func_signature">
|
||||
Function
|
||||
</para>
|
||||
<para>
|
||||
Description
|
||||
</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry role="func_table_entry">
|
||||
<para role="func_signature">
|
||||
<indexterm>
|
||||
<primary>pg_set_relation_stats</primary>
|
||||
</indexterm>
|
||||
<function>pg_set_relation_stats</function> (
|
||||
<parameter>relation</parameter> <type>regclass</type>
|
||||
<optional>, <parameter>relpages</parameter> <type>integer</type></optional>
|
||||
<optional>, <parameter>reltuples</parameter> <type>real</type></optional>
|
||||
<optional>, <parameter>relallvisible</parameter> <type>integer</type></optional> )
|
||||
<returnvalue>boolean</returnvalue>
|
||||
</para>
|
||||
<para>
|
||||
Updates relation-level statistics for the given relation to the
|
||||
specified values. The parameters correspond to columns in <link
|
||||
linkend="catalog-pg-class"><structname>pg_class</structname></link>. Unspecified
|
||||
or <literal>NULL</literal> values leave the setting
|
||||
unchanged. Returns <literal>true</literal> if a change was made;
|
||||
<literal>false</literal> otherwise.
|
||||
</para>
|
||||
<para>
|
||||
Ordinarily, these statistics are collected automatically or updated
|
||||
as a part of <xref linkend="sql-vacuum"/> or <xref
|
||||
linkend="sql-analyze"/>, so it's not necessary to call this
|
||||
function. However, it may be useful when testing the effects of
|
||||
statistics on the planner to understand or anticipate plan changes.
|
||||
</para>
|
||||
<para>
|
||||
The caller must have the <literal>MAINTAIN</literal> privilege on
|
||||
the table or be the owner of the database.
|
||||
</para>
|
||||
<para>
|
||||
The value of <structfield>relpages</structfield> must be greater than
|
||||
or equal to <literal>0</literal>,
|
||||
<structfield>reltuples</structfield> must be greater than or equal to
|
||||
<literal>-1.0</literal>, and <structfield>relallvisible</structfield>
|
||||
must be greater than or equal to <literal>0</literal>.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="func_table_entry">
|
||||
<para role="func_signature">
|
||||
<indexterm>
|
||||
<primary>pg_clear_relation_stats</primary>
|
||||
</indexterm>
|
||||
<function>pg_clear_relation_stats</function> ( <parameter>relation</parameter> <type>regclass</type> )
|
||||
<returnvalue>boolean</returnvalue>
|
||||
</para>
|
||||
<para>
|
||||
Clears table-level statistics for the given relation, as though the
|
||||
table was newly created. Returns <literal>true</literal> if a change
|
||||
was made; <literal>false</literal> otherwise.
|
||||
</para>
|
||||
<para>
|
||||
The caller must have the <literal>MAINTAIN</literal> privilege on
|
||||
the table or be the owner of the database.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
<xref linkend="functions-info-partition"/> lists functions that provide
|
||||
information about the structure of partitioned tables.
|
||||
|
@ -639,6 +639,16 @@ 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 bool
|
||||
LANGUAGE INTERNAL
|
||||
CALLED ON NULL INPUT VOLATILE
|
||||
AS 'pg_set_relation_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
|
||||
|
@ -16,6 +16,8 @@ OBJS = \
|
||||
dependencies.o \
|
||||
extended_stats.o \
|
||||
mcv.o \
|
||||
mvdistinct.o
|
||||
mvdistinct.o \
|
||||
relation_stats.o \
|
||||
stat_utils.o
|
||||
|
||||
include $(top_srcdir)/src/backend/common.mk
|
||||
|
@ -5,4 +5,6 @@ backend_sources += files(
|
||||
'extended_stats.c',
|
||||
'mcv.c',
|
||||
'mvdistinct.c',
|
||||
'relation_stats.c',
|
||||
'stat_utils.c'
|
||||
)
|
||||
|
210
src/backend/statistics/relation_stats.c
Normal file
210
src/backend/statistics/relation_stats.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
* relation_stats.c
|
||||
*
|
||||
* PostgreSQL relation statistics manipulation
|
||||
*
|
||||
* Code supporting the direct import of relation statistics, similar to
|
||||
* what is done by the ANALYZE command.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/backend/statistics/relation_stats.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "statistics/stat_utils.h"
|
||||
#include "utils/fmgrprotos.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
#define DEFAULT_RELPAGES Int32GetDatum(0)
|
||||
#define DEFAULT_RELTUPLES Float4GetDatum(-1.0)
|
||||
#define DEFAULT_RELALLVISIBLE Int32GetDatum(0)
|
||||
|
||||
/*
|
||||
* Positional argument numbers, names, and types for
|
||||
* relation_statistics_update().
|
||||
*/
|
||||
|
||||
enum relation_stats_argnum
|
||||
{
|
||||
RELATION_ARG = 0,
|
||||
RELPAGES_ARG,
|
||||
RELTUPLES_ARG,
|
||||
RELALLVISIBLE_ARG,
|
||||
NUM_RELATION_STATS_ARGS
|
||||
};
|
||||
|
||||
static struct StatsArgInfo relarginfo[] =
|
||||
{
|
||||
[RELATION_ARG] = {"relation", REGCLASSOID},
|
||||
[RELPAGES_ARG] = {"relpages", INT4OID},
|
||||
[RELTUPLES_ARG] = {"reltuples", FLOAT4OID},
|
||||
[RELALLVISIBLE_ARG] = {"relallvisible", INT4OID},
|
||||
[NUM_RELATION_STATS_ARGS] = {0}
|
||||
};
|
||||
|
||||
static bool relation_statistics_update(FunctionCallInfo fcinfo, int elevel);
|
||||
|
||||
/*
|
||||
* Internal function for modifying statistics for a relation.
|
||||
*/
|
||||
static bool
|
||||
relation_statistics_update(FunctionCallInfo fcinfo, int elevel)
|
||||
{
|
||||
Oid reloid;
|
||||
Relation crel;
|
||||
HeapTuple ctup;
|
||||
Form_pg_class pgcform;
|
||||
int replaces[3] = {0};
|
||||
Datum values[3] = {0};
|
||||
bool nulls[3] = {0};
|
||||
int ncols = 0;
|
||||
TupleDesc tupdesc;
|
||||
HeapTuple newtup;
|
||||
|
||||
|
||||
stats_check_required_arg(fcinfo, relarginfo, RELATION_ARG);
|
||||
reloid = PG_GETARG_OID(RELATION_ARG);
|
||||
|
||||
stats_lock_check_privileges(reloid);
|
||||
|
||||
/*
|
||||
* Take RowExclusiveLock on pg_class, consistent with
|
||||
* vac_update_relstats().
|
||||
*/
|
||||
crel = table_open(RelationRelationId, RowExclusiveLock);
|
||||
|
||||
tupdesc = RelationGetDescr(crel);
|
||||
ctup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(reloid));
|
||||
if (!HeapTupleIsValid(ctup))
|
||||
{
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_OBJECT_IN_USE),
|
||||
errmsg("pg_class entry for relid %u not found", reloid)));
|
||||
table_close(crel, RowExclusiveLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
pgcform = (Form_pg_class) GETSTRUCT(ctup);
|
||||
|
||||
/* relpages */
|
||||
if (!PG_ARGISNULL(RELPAGES_ARG))
|
||||
{
|
||||
int32 relpages = PG_GETARG_INT32(RELPAGES_ARG);
|
||||
|
||||
if (relpages < -1)
|
||||
{
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("relpages cannot be < -1")));
|
||||
table_close(crel, RowExclusiveLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (relpages != pgcform->relpages)
|
||||
{
|
||||
replaces[ncols] = Anum_pg_class_relpages;
|
||||
values[ncols] = Int32GetDatum(relpages);
|
||||
ncols++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PG_ARGISNULL(RELTUPLES_ARG))
|
||||
{
|
||||
float reltuples = PG_GETARG_FLOAT4(RELTUPLES_ARG);
|
||||
|
||||
if (reltuples < -1.0)
|
||||
{
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("reltuples cannot be < -1.0")));
|
||||
table_close(crel, RowExclusiveLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reltuples != pgcform->reltuples)
|
||||
{
|
||||
replaces[ncols] = Anum_pg_class_reltuples;
|
||||
values[ncols] = Float4GetDatum(reltuples);
|
||||
ncols++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PG_ARGISNULL(RELALLVISIBLE_ARG))
|
||||
{
|
||||
int32 relallvisible = PG_GETARG_INT32(RELALLVISIBLE_ARG);
|
||||
|
||||
if (relallvisible < 0)
|
||||
{
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("relallvisible cannot be < 0")));
|
||||
table_close(crel, RowExclusiveLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (relallvisible != pgcform->relallvisible)
|
||||
{
|
||||
replaces[ncols] = Anum_pg_class_relallvisible;
|
||||
values[ncols] = Int32GetDatum(relallvisible);
|
||||
ncols++;
|
||||
}
|
||||
}
|
||||
|
||||
/* only update pg_class if there is a meaningful change */
|
||||
if (ncols == 0)
|
||||
{
|
||||
table_close(crel, RowExclusiveLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
newtup = heap_modify_tuple_by_cols(ctup, tupdesc, ncols, replaces, values,
|
||||
nulls);
|
||||
|
||||
CatalogTupleUpdate(crel, &newtup->t_self, newtup);
|
||||
heap_freetuple(newtup);
|
||||
|
||||
/* release the lock, consistent with vac_update_relstats() */
|
||||
table_close(crel, RowExclusiveLock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set statistics for a given pg_class entry.
|
||||
*/
|
||||
Datum
|
||||
pg_set_relation_stats(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_BOOL(relation_statistics_update(fcinfo, ERROR));
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear statistics for a given pg_class entry; that is, set back to initial
|
||||
* stats for a newly-created table.
|
||||
*/
|
||||
Datum
|
||||
pg_clear_relation_stats(PG_FUNCTION_ARGS)
|
||||
{
|
||||
LOCAL_FCINFO(newfcinfo, 4);
|
||||
|
||||
InitFunctionCallInfoData(*newfcinfo, NULL, 4, InvalidOid, NULL, NULL);
|
||||
|
||||
newfcinfo->args[0].value = PG_GETARG_OID(0);
|
||||
newfcinfo->args[0].isnull = PG_ARGISNULL(0);
|
||||
newfcinfo->args[1].value = DEFAULT_RELPAGES;
|
||||
newfcinfo->args[1].isnull = false;
|
||||
newfcinfo->args[2].value = DEFAULT_RELTUPLES;
|
||||
newfcinfo->args[2].isnull = false;
|
||||
newfcinfo->args[3].value = DEFAULT_RELALLVISIBLE;
|
||||
newfcinfo->args[3].isnull = false;
|
||||
|
||||
PG_RETURN_BOOL(relation_statistics_update(newfcinfo, ERROR));
|
||||
}
|
94
src/backend/statistics/stat_utils.c
Normal file
94
src/backend/statistics/stat_utils.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
* stat_utils.c
|
||||
*
|
||||
* PostgreSQL statistics manipulation utilities.
|
||||
*
|
||||
* Code supporting the direct manipulation of statistics.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/backend/statistics/stat_utils.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/relation.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "miscadmin.h"
|
||||
#include "statistics/stat_utils.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
/*
|
||||
* Ensure that a given argument is not null.
|
||||
*/
|
||||
void
|
||||
stats_check_required_arg(FunctionCallInfo fcinfo,
|
||||
struct StatsArgInfo *arginfo,
|
||||
int argnum)
|
||||
{
|
||||
if (PG_ARGISNULL(argnum))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("\"%s\" cannot be NULL",
|
||||
arginfo[argnum].argname)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock relation in ShareUpdateExclusive mode, check privileges, and close the
|
||||
* relation (but retain the lock).
|
||||
*
|
||||
* A role has privileges to set statistics on the relation if any of the
|
||||
* following are true:
|
||||
* - the role owns the current database and the relation is not shared
|
||||
* - the role has the MAINTAIN privilege on the relation
|
||||
*/
|
||||
void
|
||||
stats_lock_check_privileges(Oid reloid)
|
||||
{
|
||||
Relation rel = relation_open(reloid, ShareUpdateExclusiveLock);
|
||||
const char relkind = rel->rd_rel->relkind;
|
||||
|
||||
/* All of the types that can be used with ANALYZE, plus indexes */
|
||||
switch (relkind)
|
||||
{
|
||||
case RELKIND_RELATION:
|
||||
case RELKIND_INDEX:
|
||||
case RELKIND_MATVIEW:
|
||||
case RELKIND_FOREIGN_TABLE:
|
||||
case RELKIND_PARTITIONED_TABLE:
|
||||
case RELKIND_PARTITIONED_INDEX:
|
||||
break;
|
||||
default:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||
errmsg("cannot modify statistics for relation \"%s\"",
|
||||
RelationGetRelationName(rel)),
|
||||
errdetail_relkind_not_supported(rel->rd_rel->relkind)));
|
||||
}
|
||||
|
||||
if (rel->rd_rel->relisshared)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot modify statistics for shared relation")));
|
||||
|
||||
if (!object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()))
|
||||
{
|
||||
AclResult aclresult = pg_class_aclcheck(RelationGetRelid(rel),
|
||||
GetUserId(),
|
||||
ACL_MAINTAIN);
|
||||
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult,
|
||||
get_relkind_objtype(rel->rd_rel->relkind),
|
||||
NameStr(rel->rd_rel->relname));
|
||||
}
|
||||
|
||||
relation_close(rel, NoLock);
|
||||
}
|
@ -57,6 +57,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 202410113
|
||||
#define CATALOG_VERSION_NO 202410114
|
||||
|
||||
#endif
|
||||
|
@ -12341,6 +12341,21 @@
|
||||
proallargtypes => '{int8,pg_lsn,pg_lsn,int4}', proargmodes => '{o,o,o,o}',
|
||||
proargnames => '{summarized_tli,summarized_lsn,pending_lsn,summarizer_pid}',
|
||||
prosrc => 'pg_get_wal_summarizer_state' },
|
||||
+# Statistics Import
|
||||
{ oid => '9944',
|
||||
descr => 'set statistics on relation',
|
||||
proname => 'pg_set_relation_stats', provolatile => 'v', proisstrict => 'f',
|
||||
proparallel => 'u', prorettype => 'bool',
|
||||
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 => 'bool',
|
||||
proargtypes => 'regclass',
|
||||
proargnames => '{relation}',
|
||||
prosrc => 'pg_clear_relation_stats' },
|
||||
|
||||
# GiST stratnum implementations
|
||||
{ oid => '8047', descr => 'GiST support',
|
||||
|
29
src/include/statistics/stat_utils.h
Normal file
29
src/include/statistics/stat_utils.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* stat_utils.h
|
||||
* Extended statistics and selectivity estimation functions.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/statistics/stat_utils.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef STATS_UTILS_H
|
||||
#define STATS_UTILS_H
|
||||
|
||||
#include "fmgr.h"
|
||||
|
||||
struct StatsArgInfo
|
||||
{
|
||||
const char *argname;
|
||||
Oid argtype;
|
||||
};
|
||||
|
||||
extern void stats_check_required_arg(FunctionCallInfo fcinfo,
|
||||
struct StatsArgInfo *arginfo,
|
||||
int argnum);
|
||||
extern void stats_lock_check_privileges(Oid reloid);
|
||||
|
||||
#endif /* STATS_UTILS_H */
|
143
src/test/regress/expected/stats_import.out
Normal file
143
src/test/regress/expected/stats_import.out
Normal file
@ -0,0 +1,143 @@
|
||||
CREATE SCHEMA stats_import;
|
||||
CREATE TYPE stats_import.complex_type AS (
|
||||
a integer,
|
||||
b real,
|
||||
c text,
|
||||
d date,
|
||||
e jsonb);
|
||||
CREATE TABLE stats_import.test(
|
||||
id INTEGER PRIMARY KEY,
|
||||
name text,
|
||||
comp stats_import.complex_type,
|
||||
arange int4range,
|
||||
tags text[]
|
||||
);
|
||||
-- starting stats
|
||||
SELECT relpages, reltuples, relallvisible
|
||||
FROM pg_class
|
||||
WHERE oid = 'stats_import.test'::regclass;
|
||||
relpages | reltuples | relallvisible
|
||||
----------+-----------+---------------
|
||||
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
|
||||
-----------------------
|
||||
t
|
||||
(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
|
||||
-----------------------
|
||||
t
|
||||
(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
|
||||
-----------------------
|
||||
f
|
||||
(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
|
||||
-----------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT relpages, reltuples, relallvisible
|
||||
FROM pg_class
|
||||
WHERE oid = 'stats_import.test'::regclass;
|
||||
relpages | reltuples | relallvisible
|
||||
----------+-----------+---------------
|
||||
17 | 400 | 4
|
||||
(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
|
||||
-----------------------
|
||||
t
|
||||
(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(
|
||||
'stats_import.test'::regclass);
|
||||
pg_clear_relation_stats
|
||||
-------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT relpages, reltuples, relallvisible
|
||||
FROM pg_class
|
||||
WHERE oid = 'stats_import.test'::regclass;
|
||||
relpages | reltuples | relallvisible
|
||||
----------+-----------+---------------
|
||||
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.
|
||||
DROP SCHEMA stats_import CASCADE;
|
||||
NOTICE: drop cascades to 4 other objects
|
||||
DETAIL: drop cascades to type stats_import.complex_type
|
||||
drop cascades to table stats_import.test
|
||||
drop cascades to sequence stats_import.testseq
|
||||
drop cascades to view stats_import.testview
|
@ -28,7 +28,7 @@ test: strings md5 numerology point lseg line box path polygon circle date time t
|
||||
# geometry depends on point, lseg, line, box, path, polygon, circle
|
||||
# horology depends on date, time, timetz, timestamp, timestamptz, interval
|
||||
# ----------
|
||||
test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc database
|
||||
test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc database stats_import
|
||||
|
||||
# ----------
|
||||
# Load huge amounts of data
|
||||
|
98
src/test/regress/sql/stats_import.sql
Normal file
98
src/test/regress/sql/stats_import.sql
Normal file
@ -0,0 +1,98 @@
|
||||
CREATE SCHEMA stats_import;
|
||||
|
||||
CREATE TYPE stats_import.complex_type AS (
|
||||
a integer,
|
||||
b real,
|
||||
c text,
|
||||
d date,
|
||||
e jsonb);
|
||||
|
||||
CREATE TABLE stats_import.test(
|
||||
id INTEGER PRIMARY KEY,
|
||||
name text,
|
||||
comp stats_import.complex_type,
|
||||
arange int4range,
|
||||
tags text[]
|
||||
);
|
||||
|
||||
-- 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;
|
||||
|
||||
-- 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;
|
||||
|
||||
-- clear
|
||||
SELECT
|
||||
pg_catalog.pg_clear_relation_stats(
|
||||
'stats_import.test'::regclass);
|
||||
|
||||
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);
|
||||
|
||||
DROP SCHEMA stats_import CASCADE;
|
Reference in New Issue
Block a user