<para>
<command>CREATE STATISTICS</command> will create a new extended statistics
- object on the specified table.
+ object on the specified table, foreign table or materialized view.
The statistics will be created in the current database and
will be owned by the user issuing the command.
</para>
* take only ShareUpdateExclusiveLock on relation, conflicting with
* ANALYZE and other DDL that sets statistical information.
*/
- rel = heap_openrv(stmt->relation, ShareUpdateExclusiveLock);
+ rel = relation_openrv(stmt->relation, ShareUpdateExclusiveLock);
relid = RelationGetRelid(rel);
if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_MATVIEW)
+ rel->rd_rel->relkind != RELKIND_MATVIEW &&
+ rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
+ rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("relation \"%s\" is not a table or materialized view",
+ errmsg("relation \"%s\" is not a table, foreign table, or materialized view",
RelationGetRelationName(rel))));
/*
CatalogTupleInsert(statrel, htup);
statoid = HeapTupleGetOid(htup);
heap_freetuple(htup);
- heap_close(statrel, RowExclusiveLock);
+ relation_close(statrel, RowExclusiveLock);
/*
* Invalidate relcache so that others see the new statistics.
{
TableInfo *tbinfo = &tblinfo[i];
- /* Only plain tables and materialized views can have extended statistics. */
+ /*
+ * Only plain tables, materialized views, foreign tables and
+ * partitioned tables can have extended statistics.
+ */
if (tbinfo->relkind != RELKIND_RELATION &&
- tbinfo->relkind != RELKIND_MATVIEW)
+ tbinfo->relkind != RELKIND_MATVIEW &&
+ tbinfo->relkind != RELKIND_FOREIGN_TABLE &&
+ tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
continue;
/*
WARNING: extended statistics "public.ab1_a_b_stats" could not be collected for relation public.ab1
ANALYZE ab1;
DROP TABLE ab1;
+-- Verify supported object types for extended statistics
+CREATE schema tststats;
+CREATE TABLE tststats.t (a int, b int, c text);
+CREATE INDEX ti ON tststats.t (a, b);
+CREATE SEQUENCE tststats.s;
+CREATE VIEW tststats.v AS SELECT * FROM tststats.t;
+CREATE MATERIALIZED VIEW tststats.mv AS SELECT * FROM tststats.t;
+CREATE TYPE tststats.ty AS (a int, b int, c text);
+CREATE FOREIGN DATA WRAPPER extstats_dummy_fdw;
+CREATE SERVER extstats_dummy_srv FOREIGN DATA WRAPPER extstats_dummy_fdw;
+CREATE FOREIGN TABLE tststats.f (a int, b int, c text) SERVER extstats_dummy_srv;
+CREATE TABLE tststats.pt (a int, b int, c text) PARTITION BY RANGE (a, b);
+CREATE TABLE tststats.pt1 PARTITION OF tststats.pt FOR VALUES FROM (-10, -10) TO (10, 10);
+CREATE STATISTICS tststats.s1 ON (a, b) FROM tststats.t;
+CREATE STATISTICS tststats.s2 ON (a, b) FROM tststats.ti;
+ERROR: relation "ti" is not a table, foreign table, or materialized view
+CREATE STATISTICS tststats.s3 ON (a, b) FROM tststats.s;
+ERROR: relation "s" is not a table, foreign table, or materialized view
+CREATE STATISTICS tststats.s4 ON (a, b) FROM tststats.v;
+ERROR: relation "v" is not a table, foreign table, or materialized view
+CREATE STATISTICS tststats.s5 ON (a, b) FROM tststats.mv;
+CREATE STATISTICS tststats.s6 ON (a, b) FROM tststats.ty;
+ERROR: relation "ty" is not a table, foreign table, or materialized view
+CREATE STATISTICS tststats.s7 ON (a, b) FROM tststats.f;
+CREATE STATISTICS tststats.s8 ON (a, b) FROM tststats.pt;
+CREATE STATISTICS tststats.s9 ON (a, b) FROM tststats.pt1;
+DO $$
+DECLARE
+ relname text := reltoastrelid::regclass FROM pg_class WHERE oid = 'tststats.t'::regclass;
+BEGIN
+ EXECUTE 'CREATE STATISTICS tststats.s10 ON (a, b) FROM ' || relname;
+EXCEPTION WHEN wrong_object_type THEN
+ RAISE NOTICE 'stats on toast table not created';
+END;
+$$;
+NOTICE: stats on toast table not created
+SET client_min_messages TO warning;
+DROP SCHEMA tststats CASCADE;
+DROP FOREIGN DATA WRAPPER extstats_dummy_fdw CASCADE;
+RESET client_min_messages;
-- n-distinct tests
CREATE TABLE ndistinct (
filler1 TEXT,
ANALYZE ab1;
DROP TABLE ab1;
+-- Verify supported object types for extended statistics
+CREATE schema tststats;
+
+CREATE TABLE tststats.t (a int, b int, c text);
+CREATE INDEX ti ON tststats.t (a, b);
+CREATE SEQUENCE tststats.s;
+CREATE VIEW tststats.v AS SELECT * FROM tststats.t;
+CREATE MATERIALIZED VIEW tststats.mv AS SELECT * FROM tststats.t;
+CREATE TYPE tststats.ty AS (a int, b int, c text);
+CREATE FOREIGN DATA WRAPPER extstats_dummy_fdw;
+CREATE SERVER extstats_dummy_srv FOREIGN DATA WRAPPER extstats_dummy_fdw;
+CREATE FOREIGN TABLE tststats.f (a int, b int, c text) SERVER extstats_dummy_srv;
+CREATE TABLE tststats.pt (a int, b int, c text) PARTITION BY RANGE (a, b);
+CREATE TABLE tststats.pt1 PARTITION OF tststats.pt FOR VALUES FROM (-10, -10) TO (10, 10);
+
+CREATE STATISTICS tststats.s1 ON (a, b) FROM tststats.t;
+CREATE STATISTICS tststats.s2 ON (a, b) FROM tststats.ti;
+CREATE STATISTICS tststats.s3 ON (a, b) FROM tststats.s;
+CREATE STATISTICS tststats.s4 ON (a, b) FROM tststats.v;
+CREATE STATISTICS tststats.s5 ON (a, b) FROM tststats.mv;
+CREATE STATISTICS tststats.s6 ON (a, b) FROM tststats.ty;
+CREATE STATISTICS tststats.s7 ON (a, b) FROM tststats.f;
+CREATE STATISTICS tststats.s8 ON (a, b) FROM tststats.pt;
+CREATE STATISTICS tststats.s9 ON (a, b) FROM tststats.pt1;
+DO $$
+DECLARE
+ relname text := reltoastrelid::regclass FROM pg_class WHERE oid = 'tststats.t'::regclass;
+BEGIN
+ EXECUTE 'CREATE STATISTICS tststats.s10 ON (a, b) FROM ' || relname;
+EXCEPTION WHEN wrong_object_type THEN
+ RAISE NOTICE 'stats on toast table not created';
+END;
+$$;
+
+SET client_min_messages TO warning;
+DROP SCHEMA tststats CASCADE;
+DROP FOREIGN DATA WRAPPER extstats_dummy_fdw CASCADE;
+RESET client_min_messages;
-- n-distinct tests
CREATE TABLE ndistinct (