Commit ee0202d5 authored by Peter Eisentraut's avatar Peter Eisentraut

pgstattuple: Have pgstattuple_approx accept TOAST tables

TOAST tables have a visibility map and a free space map, so they can
be supported by pgstattuple_approx just fine.

Add test cases to show how various pgstattuple functions accept TOAST
tables.  Also add similar tests to pg_visibility, which already
accepted TOAST tables correctly but had no test coverage for them.
Reviewed-by: default avatarLaurenz Albe <laurenz.albe@cybertec.at>
Discussion: https://www.postgresql.org/message-id/flat/27c4496a-02b9-dc87-8f6f-bddbef54e0fe@2ndquadrant.com
parent ea57e531
...@@ -102,8 +102,9 @@ ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table ...@@ -102,8 +102,9 @@ ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
select pg_truncate_visibility_map('test_foreign_table'); select pg_truncate_visibility_map('test_foreign_table');
ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
-- check some of the allowed relkinds -- check some of the allowed relkinds
create table regular_table (a int); create table regular_table (a int, b text);
insert into regular_table values (1), (2); alter table regular_table alter column b set storage external;
insert into regular_table values (1, repeat('one', 1000)), (2, repeat('two', 1000));
vacuum regular_table; vacuum regular_table;
select count(*) > 0 from pg_visibility('regular_table'); select count(*) > 0 from pg_visibility('regular_table');
?column? ?column?
...@@ -111,6 +112,12 @@ select count(*) > 0 from pg_visibility('regular_table'); ...@@ -111,6 +112,12 @@ select count(*) > 0 from pg_visibility('regular_table');
t t
(1 row) (1 row)
select count(*) > 0 from pg_visibility((select reltoastrelid from pg_class where relname = 'regular_table'));
?column?
----------
t
(1 row)
truncate regular_table; truncate regular_table;
select count(*) > 0 from pg_visibility('regular_table'); select count(*) > 0 from pg_visibility('regular_table');
?column? ?column?
...@@ -118,6 +125,12 @@ select count(*) > 0 from pg_visibility('regular_table'); ...@@ -118,6 +125,12 @@ select count(*) > 0 from pg_visibility('regular_table');
f f
(1 row) (1 row)
select count(*) > 0 from pg_visibility((select reltoastrelid from pg_class where relname = 'regular_table'));
?column?
----------
f
(1 row)
create materialized view matview_visibility_test as select * from regular_table; create materialized view matview_visibility_test as select * from regular_table;
vacuum matview_visibility_test; vacuum matview_visibility_test;
select count(*) > 0 from pg_visibility('matview_visibility_test'); select count(*) > 0 from pg_visibility('matview_visibility_test');
......
...@@ -68,12 +68,15 @@ select pg_check_frozen('test_foreign_table'); ...@@ -68,12 +68,15 @@ select pg_check_frozen('test_foreign_table');
select pg_truncate_visibility_map('test_foreign_table'); select pg_truncate_visibility_map('test_foreign_table');
-- check some of the allowed relkinds -- check some of the allowed relkinds
create table regular_table (a int); create table regular_table (a int, b text);
insert into regular_table values (1), (2); alter table regular_table alter column b set storage external;
insert into regular_table values (1, repeat('one', 1000)), (2, repeat('two', 1000));
vacuum regular_table; vacuum regular_table;
select count(*) > 0 from pg_visibility('regular_table'); select count(*) > 0 from pg_visibility('regular_table');
select count(*) > 0 from pg_visibility((select reltoastrelid from pg_class where relname = 'regular_table'));
truncate regular_table; truncate regular_table;
select count(*) > 0 from pg_visibility('regular_table'); select count(*) > 0 from pg_visibility('regular_table');
select count(*) > 0 from pg_visibility((select reltoastrelid from pg_class where relname = 'regular_table'));
create materialized view matview_visibility_test as select * from regular_table; create materialized view matview_visibility_test as select * from regular_table;
vacuum matview_visibility_test; vacuum matview_visibility_test;
......
...@@ -159,7 +159,7 @@ ERROR: "test_partitioned" (partitioned table) is not supported ...@@ -159,7 +159,7 @@ ERROR: "test_partitioned" (partitioned table) is not supported
select pgstattuple('test_partitioned_index'); select pgstattuple('test_partitioned_index');
ERROR: "test_partitioned_index" (partitioned index) is not supported ERROR: "test_partitioned_index" (partitioned index) is not supported
select pgstattuple_approx('test_partitioned'); select pgstattuple_approx('test_partitioned');
ERROR: "test_partitioned" is not a table or materialized view ERROR: "test_partitioned" is not a table, materialized view, or TOAST table
select pg_relpages('test_partitioned'); select pg_relpages('test_partitioned');
ERROR: "test_partitioned" is not a table, index, materialized view, sequence, or TOAST table ERROR: "test_partitioned" is not a table, index, materialized view, sequence, or TOAST table
select pgstatindex('test_partitioned'); select pgstatindex('test_partitioned');
...@@ -173,7 +173,7 @@ create view test_view as select 1; ...@@ -173,7 +173,7 @@ create view test_view as select 1;
select pgstattuple('test_view'); select pgstattuple('test_view');
ERROR: "test_view" (view) is not supported ERROR: "test_view" (view) is not supported
select pgstattuple_approx('test_view'); select pgstattuple_approx('test_view');
ERROR: "test_view" is not a table or materialized view ERROR: "test_view" is not a table, materialized view, or TOAST table
select pg_relpages('test_view'); select pg_relpages('test_view');
ERROR: "test_view" is not a table, index, materialized view, sequence, or TOAST table ERROR: "test_view" is not a table, index, materialized view, sequence, or TOAST table
select pgstatindex('test_view'); select pgstatindex('test_view');
...@@ -189,7 +189,7 @@ create foreign table test_foreign_table () server dummy_server; ...@@ -189,7 +189,7 @@ create foreign table test_foreign_table () server dummy_server;
select pgstattuple('test_foreign_table'); select pgstattuple('test_foreign_table');
ERROR: "test_foreign_table" (foreign table) is not supported ERROR: "test_foreign_table" (foreign table) is not supported
select pgstattuple_approx('test_foreign_table'); select pgstattuple_approx('test_foreign_table');
ERROR: "test_foreign_table" is not a table or materialized view ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
select pg_relpages('test_foreign_table'); select pg_relpages('test_foreign_table');
ERROR: "test_foreign_table" is not a table, index, materialized view, sequence, or TOAST table ERROR: "test_foreign_table" is not a table, index, materialized view, sequence, or TOAST table
select pgstatindex('test_foreign_table'); select pgstatindex('test_foreign_table');
...@@ -218,6 +218,25 @@ select pg_relpages('test_partition'); ...@@ -218,6 +218,25 @@ select pg_relpages('test_partition');
0 0
(1 row) (1 row)
-- toast tables should work
select pgstattuple((select reltoastrelid from pg_class where relname = 'test'));
pgstattuple
---------------------
(0,0,0,0,0,0,0,0,0)
(1 row)
select pgstattuple_approx((select reltoastrelid from pg_class where relname = 'test'));
pgstattuple_approx
-----------------------
(0,0,0,0,0,0,0,0,0,0)
(1 row)
select pg_relpages((select reltoastrelid from pg_class where relname = 'test'));
pg_relpages
-------------
0
(1 row)
-- not for the index calls though, of course -- not for the index calls though, of course
select pgstatindex('test_partition'); select pgstatindex('test_partition');
ERROR: relation "test_partition" is not a btree index ERROR: relation "test_partition" is not a btree index
......
...@@ -278,15 +278,15 @@ pgstattuple_approx_internal(Oid relid, FunctionCallInfo fcinfo) ...@@ -278,15 +278,15 @@ pgstattuple_approx_internal(Oid relid, FunctionCallInfo fcinfo)
errmsg("cannot access temporary tables of other sessions"))); errmsg("cannot access temporary tables of other sessions")));
/* /*
* We support only ordinary relations and materialised views, because we * We support only relation kinds with a visibility map and a free space
* depend on the visibility map and free space map for our estimates about * map.
* unscanned pages.
*/ */
if (!(rel->rd_rel->relkind == RELKIND_RELATION || if (!(rel->rd_rel->relkind == RELKIND_RELATION ||
rel->rd_rel->relkind == RELKIND_MATVIEW)) rel->rd_rel->relkind == RELKIND_MATVIEW ||
rel->rd_rel->relkind == RELKIND_TOASTVALUE))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("\"%s\" is not a table or materialized view", errmsg("\"%s\" is not a table, materialized view, or TOAST table",
RelationGetRelationName(rel)))); RelationGetRelationName(rel))));
if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
......
...@@ -100,6 +100,11 @@ select pgstattuple('test_partition'); ...@@ -100,6 +100,11 @@ select pgstattuple('test_partition');
select pgstattuple_approx('test_partition'); select pgstattuple_approx('test_partition');
select pg_relpages('test_partition'); select pg_relpages('test_partition');
-- toast tables should work
select pgstattuple((select reltoastrelid from pg_class where relname = 'test'));
select pgstattuple_approx((select reltoastrelid from pg_class where relname = 'test'));
select pg_relpages((select reltoastrelid from pg_class where relname = 'test'));
-- not for the index calls though, of course -- not for the index calls though, of course
select pgstatindex('test_partition'); select pgstatindex('test_partition');
select pgstatginindex('test_partition'); select pgstatginindex('test_partition');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment