summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/amcheck/expected/check_heap.out15
-rw-r--r--contrib/amcheck/verify_heapam.c38
-rw-r--r--contrib/pageinspect/expected/page.out6
-rw-r--r--contrib/pageinspect/rawpage.c28
-rw-r--r--contrib/pg_surgery/expected/heap_surgery.out6
-rw-r--r--contrib/pg_surgery/heap_surgery.c54
-rw-r--r--contrib/pg_visibility/expected/pg_visibility.out75
-rw-r--r--contrib/pg_visibility/pg_visibility.c5
-rw-r--r--contrib/pgstattuple/expected/pgstattuple.out30
-rw-r--r--contrib/pgstattuple/pgstatapprox.c5
-rw-r--r--contrib/pgstattuple/pgstatindex.c75
-rw-r--r--contrib/pgstattuple/pgstattuple.c31
12 files changed, 166 insertions, 202 deletions
diff --git a/contrib/amcheck/expected/check_heap.out b/contrib/amcheck/expected/check_heap.out
index 1fb3823142..ad3086d2aa 100644
--- a/contrib/amcheck/expected/check_heap.out
+++ b/contrib/amcheck/expected/check_heap.out
@@ -139,7 +139,8 @@ CREATE TABLE test_partitioned (a int, b text default repeat('x', 5000))
SELECT * FROM verify_heapam('test_partitioned',
startblock := NULL,
endblock := NULL);
-ERROR: "test_partitioned" is not a table, materialized view, or TOAST table
+ERROR: cannot check relation "test_partitioned"
+DETAIL: This operation is not supported for partitioned tables.
-- Check that valid options are not rejected nor corruption reported
-- for an empty partition table (the child one)
CREATE TABLE test_partition partition OF test_partitioned FOR VALUES IN (1);
@@ -165,19 +166,22 @@ CREATE INDEX test_index ON test_partition (a);
SELECT * FROM verify_heapam('test_index',
startblock := NULL,
endblock := NULL);
-ERROR: "test_index" is not a table, materialized view, or TOAST table
+ERROR: cannot check relation "test_index"
+DETAIL: This operation is not supported for indexes.
-- Check that views are rejected
CREATE VIEW test_view AS SELECT 1;
SELECT * FROM verify_heapam('test_view',
startblock := NULL,
endblock := NULL);
-ERROR: "test_view" is not a table, materialized view, or TOAST table
+ERROR: cannot check relation "test_view"
+DETAIL: This operation is not supported for views.
-- Check that sequences are rejected
CREATE SEQUENCE test_sequence;
SELECT * FROM verify_heapam('test_sequence',
startblock := NULL,
endblock := NULL);
-ERROR: "test_sequence" is not a table, materialized view, or TOAST table
+ERROR: cannot check relation "test_sequence"
+DETAIL: This operation is not supported for sequences.
-- Check that foreign tables are rejected
CREATE FOREIGN DATA WRAPPER dummy;
CREATE SERVER dummy_server FOREIGN DATA WRAPPER dummy;
@@ -185,7 +189,8 @@ CREATE FOREIGN TABLE test_foreign_table () SERVER dummy_server;
SELECT * FROM verify_heapam('test_foreign_table',
startblock := NULL,
endblock := NULL);
-ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
+ERROR: cannot check relation "test_foreign_table"
+DETAIL: This operation is not supported for foreign tables.
-- cleanup
DROP TABLE heaptest;
DROP TABLE test_partition;
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index a3caee7cdd..226271923a 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -147,7 +147,6 @@ typedef struct HeapCheckContext
} HeapCheckContext;
/* Internal implementation */
-static void sanity_check_relation(Relation rel);
static void check_tuple(HeapCheckContext *ctx);
static void check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
ToastedAttribute *ta, int32 *expected_chunk_seq,
@@ -300,7 +299,23 @@ verify_heapam(PG_FUNCTION_ARGS)
/* Open relation, check relkind and access method */
ctx.rel = relation_open(relid, AccessShareLock);
- sanity_check_relation(ctx.rel);
+
+ /*
+ * Check that a relation's relkind and access method are both supported.
+ */
+ if (ctx.rel->rd_rel->relkind != RELKIND_RELATION &&
+ ctx.rel->rd_rel->relkind != RELKIND_MATVIEW &&
+ ctx.rel->rd_rel->relkind != RELKIND_TOASTVALUE)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot check relation \"%s\"",
+ RelationGetRelationName(ctx.rel)),
+ errdetail_relkind_not_supported(ctx.rel->rd_rel->relkind)));
+
+ if (ctx.rel->rd_rel->relam != HEAP_TABLE_AM_OID)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("only heap AM is supported")));
/* Early exit if the relation is empty */
nblocks = RelationGetNumberOfBlocks(ctx.rel);
@@ -524,25 +539,6 @@ verify_heapam(PG_FUNCTION_ARGS)
}
/*
- * Check that a relation's relkind and access method are both supported.
- */
-static void
-sanity_check_relation(Relation rel)
-{
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_MATVIEW &&
- rel->rd_rel->relkind != RELKIND_TOASTVALUE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, materialized view, or TOAST table",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("only heap AM is supported")));
-}
-
-/*
* Shared internal implementation for report_corruption and
* report_toast_corruption.
*/
diff --git a/contrib/pageinspect/expected/page.out b/contrib/pageinspect/expected/page.out
index 4da28f0a1d..4e325ae56d 100644
--- a/contrib/pageinspect/expected/page.out
+++ b/contrib/pageinspect/expected/page.out
@@ -180,9 +180,11 @@ DROP TABLE test1;
create table test_partitioned (a int) partition by range (a);
create index test_partitioned_index on test_partitioned (a);
select get_raw_page('test_partitioned', 0); -- error about partitioned table
-ERROR: cannot get raw page from partitioned table "test_partitioned"
+ERROR: cannot get raw page from relation "test_partitioned"
+DETAIL: This operation is not supported for partitioned tables.
select get_raw_page('test_partitioned_index', 0); -- error about partitioned index
-ERROR: cannot get raw page from partitioned index "test_partitioned_index"
+ERROR: cannot get raw page from relation "test_partitioned_index"
+DETAIL: This operation is not supported for partitioned indexes.
-- a regular table which is a member of a partition set should work though
create table test_part1 partition of test_partitioned for values from ( 1 ) to (100);
select get_raw_page('test_part1', 0); -- get farther and error about empty table
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index 7272b21016..e9fee73bc4 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -155,32 +155,12 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
- /* Check that this relation has storage */
- if (rel->rd_rel->relkind == RELKIND_VIEW)
+ if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from view \"%s\"",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from composite type \"%s\"",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from foreign table \"%s\"",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from partitioned table \"%s\"",
- RelationGetRelationName(rel))));
- if (rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("cannot get raw page from partitioned index \"%s\"",
- RelationGetRelationName(rel))));
+ errmsg("cannot get raw page from relation \"%s\"",
+ RelationGetRelationName(rel)),
+ errdetail_relkind_not_supported(rel->rd_rel->relkind)));
/*
* Reject attempts to read non-local temporary relations; we would be
diff --git a/contrib/pg_surgery/expected/heap_surgery.out b/contrib/pg_surgery/expected/heap_surgery.out
index d4a757ffa0..df7d13b090 100644
--- a/contrib/pg_surgery/expected/heap_surgery.out
+++ b/contrib/pg_surgery/expected/heap_surgery.out
@@ -170,9 +170,11 @@ rollback;
-- check that it fails on an unsupported relkind
create view vw as select 1;
select heap_force_kill('vw'::regclass, ARRAY['(0, 1)']::tid[]);
-ERROR: "vw" is not a table, materialized view, or TOAST table
+ERROR: cannot operate on relation "vw"
+DETAIL: This operation is not supported for views.
select heap_force_freeze('vw'::regclass, ARRAY['(0, 1)']::tid[]);
-ERROR: "vw" is not a table, materialized view, or TOAST table
+ERROR: cannot operate on relation "vw"
+DETAIL: This operation is not supported for views.
-- cleanup.
drop view vw;
drop extension pg_surgery;
diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c
index d31e5f31fd..7edfe4f326 100644
--- a/contrib/pg_surgery/heap_surgery.c
+++ b/contrib/pg_surgery/heap_surgery.c
@@ -37,7 +37,6 @@ static int32 tidcmp(const void *a, const void *b);
static Datum heap_force_common(FunctionCallInfo fcinfo,
HeapTupleForceOption heap_force_opt);
static void sanity_check_tid_array(ArrayType *ta, int *ntids);
-static void sanity_check_relation(Relation rel);
static BlockNumber find_tids_one_page(ItemPointer tids, int ntids,
OffsetNumber *next_start_ptr);
@@ -101,8 +100,28 @@ heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt)
rel = relation_open(relid, RowExclusiveLock);
- /* Check target relation. */
- sanity_check_relation(rel);
+ /*
+ * Check target relation.
+ */
+ if (rel->rd_rel->relkind != RELKIND_RELATION &&
+ rel->rd_rel->relkind != RELKIND_MATVIEW &&
+ rel->rd_rel->relkind != RELKIND_TOASTVALUE)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot operate on relation \"%s\"",
+ RelationGetRelationName(rel)),
+ errdetail_relkind_not_supported(rel->rd_rel->relkind)));
+
+ if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("only heap AM is supported")));
+
+ /* Must be owner of the table or superuser. */
+ if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER,
+ get_relkind_objtype(rel->rd_rel->relkind),
+ RelationGetRelationName(rel));
tids = ((ItemPointer) ARR_DATA_PTR(ta));
@@ -364,35 +383,6 @@ sanity_check_tid_array(ArrayType *ta, int *ntids)
}
/*-------------------------------------------------------------------------
- * sanity_check_relation()
- *
- * Perform sanity checks on the given relation.
- * ------------------------------------------------------------------------
- */
-static void
-sanity_check_relation(Relation rel)
-{
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_MATVIEW &&
- rel->rd_rel->relkind != RELKIND_TOASTVALUE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, materialized view, or TOAST table",
- RelationGetRelationName(rel))));
-
- if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("only heap AM is supported")));
-
- /* Must be owner of the table or superuser. */
- if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER,
- get_relkind_objtype(rel->rd_rel->relkind),
- RelationGetRelationName(rel));
-}
-
-/*-------------------------------------------------------------------------
* find_tids_one_page()
*
* Find all the tids residing in the same page as tids[next_start_ptr], and
diff --git a/contrib/pg_visibility/expected/pg_visibility.out b/contrib/pg_visibility/expected/pg_visibility.out
index 315633bfea..9de54db2a2 100644
--- a/contrib/pg_visibility/expected/pg_visibility.out
+++ b/contrib/pg_visibility/expected/pg_visibility.out
@@ -41,66 +41,91 @@ ROLLBACK;
create table test_partitioned (a int) partition by list (a);
-- these should all fail
select pg_visibility('test_partitioned', 0);
-ERROR: "test_partitioned" is not a table, materialized view, or TOAST table
+ERROR: relation "test_partitioned" is of wrong relation kind
+DETAIL: This operation is not supported for partitioned tables.
select pg_visibility_map('test_partitioned');
-ERROR: "test_partitioned" is not a table, materialized view, or TOAST table
+ERROR: relation "test_partitioned" is of wrong relation kind
+DETAIL: This operation is not supported for partitioned tables.
select pg_visibility_map_summary('test_partitioned');
-ERROR: "test_partitioned" is not a table, materialized view, or TOAST table
+ERROR: relation "test_partitioned" is of wrong relation kind
+DETAIL: This operation is not supported for partitioned tables.
select pg_check_frozen('test_partitioned');
-ERROR: "test_partitioned" is not a table, materialized view, or TOAST table
+ERROR: relation "test_partitioned" is of wrong relation kind
+DETAIL: This operation is not supported for partitioned tables.
select pg_truncate_visibility_map('test_partitioned');
-ERROR: "test_partitioned" is not a table, materialized view, or TOAST table
+ERROR: relation "test_partitioned" is of wrong relation kind
+DETAIL: This operation is not supported for partitioned tables.
create table test_partition partition of test_partitioned for values in (1);
create index test_index on test_partition (a);
-- indexes do not, so these all fail
select pg_visibility('test_index', 0);
-ERROR: "test_index" is not a table, materialized view, or TOAST table
+ERROR: relation "test_index" is of wrong relation kind
+DETAIL: This operation is not supported for indexes.
select pg_visibility_map('test_index');
-ERROR: "test_index" is not a table, materialized view, or TOAST table
+ERROR: relation "test_index" is of wrong relation kind
+DETAIL: This operation is not supported for indexes.
select pg_visibility_map_summary('test_index');
-ERROR: "test_index" is not a table, materialized view, or TOAST table
+ERROR: relation "test_index" is of wrong relation kind
+DETAIL: This operation is not supported for indexes.
select pg_check_frozen('test_index');
-ERROR: "test_index" is not a table, materialized view, or TOAST table
+ERROR: relation "test_index" is of wrong relation kind
+DETAIL: This operation is not supported for indexes.
select pg_truncate_visibility_map('test_index');
-ERROR: "test_index" is not a table, materialized view, or TOAST table
+ERROR: relation "test_index" is of wrong relation kind
+DETAIL: This operation is not supported for indexes.
create view test_view as select 1;
-- views do not have VMs, so these all fail
select pg_visibility('test_view', 0);
-ERROR: "test_view" is not a table, materialized view, or TOAST table
+ERROR: relation "test_view" is of wrong relation kind
+DETAIL: This operation is not supported for views.
select pg_visibility_map('test_view');
-ERROR: "test_view" is not a table, materialized view, or TOAST table
+ERROR: relation "test_view" is of wrong relation kind
+DETAIL: This operation is not supported for views.
select pg_visibility_map_summary('test_view');
-ERROR: "test_view" is not a table, materialized view, or TOAST table
+ERROR: relation "test_view" is of wrong relation kind
+DETAIL: This operation is not supported for views.
select pg_check_frozen('test_view');
-ERROR: "test_view" is not a table, materialized view, or TOAST table
+ERROR: relation "test_view" is of wrong relation kind
+DETAIL: This operation is not supported for views.
select pg_truncate_visibility_map('test_view');
-ERROR: "test_view" is not a table, materialized view, or TOAST table
+ERROR: relation "test_view" is of wrong relation kind
+DETAIL: This operation is not supported for views.
create sequence test_sequence;
-- sequences do not have VMs, so these all fail
select pg_visibility('test_sequence', 0);
-ERROR: "test_sequence" is not a table, materialized view, or TOAST table
+ERROR: relation "test_sequence" is of wrong relation kind
+DETAIL: This operation is not supported for sequences.
select pg_visibility_map('test_sequence');
-ERROR: "test_sequence" is not a table, materialized view, or TOAST table
+ERROR: relation "test_sequence" is of wrong relation kind
+DETAIL: This operation is not supported for sequences.
select pg_visibility_map_summary('test_sequence');
-ERROR: "test_sequence" is not a table, materialized view, or TOAST table
+ERROR: relation "test_sequence" is of wrong relation kind
+DETAIL: This operation is not supported for sequences.
select pg_check_frozen('test_sequence');
-ERROR: "test_sequence" is not a table, materialized view, or TOAST table
+ERROR: relation "test_sequence" is of wrong relation kind
+DETAIL: This operation is not supported for sequences.
select pg_truncate_visibility_map('test_sequence');
-ERROR: "test_sequence" is not a table, materialized view, or TOAST table
+ERROR: relation "test_sequence" is of wrong relation kind
+DETAIL: This operation is not supported for sequences.
create foreign data wrapper dummy;
create server dummy_server foreign data wrapper dummy;
create foreign table test_foreign_table () server dummy_server;
-- foreign tables do not have VMs, so these all fail
select pg_visibility('test_foreign_table', 0);
-ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
+ERROR: relation "test_foreign_table" is of wrong relation kind
+DETAIL: This operation is not supported for foreign tables.
select pg_visibility_map('test_foreign_table');
-ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
+ERROR: relation "test_foreign_table" is of wrong relation kind
+DETAIL: This operation is not supported for foreign tables.
select pg_visibility_map_summary('test_foreign_table');
-ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
+ERROR: relation "test_foreign_table" is of wrong relation kind
+DETAIL: This operation is not supported for foreign tables.
select pg_check_frozen('test_foreign_table');
-ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
+ERROR: relation "test_foreign_table" is of wrong relation kind
+DETAIL: This operation is not supported for foreign tables.
select pg_truncate_visibility_map('test_foreign_table');
-ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
+ERROR: relation "test_foreign_table" is of wrong relation kind
+DETAIL: This operation is not supported for foreign tables.
-- check some of the allowed relkinds
create table regular_table (a int, b text);
alter table regular_table alter column b set storage external;
diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index dd0c124e62..c6d983183d 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -781,6 +781,7 @@ check_relation_relkind(Relation rel)
rel->rd_rel->relkind != RELKIND_TOASTVALUE)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, materialized view, or TOAST table",
- RelationGetRelationName(rel))));
+ errmsg("relation \"%s\" is of wrong relation kind",
+ RelationGetRelationName(rel)),
+ errdetail_relkind_not_supported(rel->rd_rel->relkind)));
}
diff --git a/contrib/pgstattuple/expected/pgstattuple.out b/contrib/pgstattuple/expected/pgstattuple.out
index 40f7825ddb..e4ac86f9e3 100644
--- a/contrib/pgstattuple/expected/pgstattuple.out
+++ b/contrib/pgstattuple/expected/pgstattuple.out
@@ -155,13 +155,17 @@ create table test_partitioned (a int) partition by range (a);
create index test_partitioned_index on test_partitioned(a);
-- these should all fail
select pgstattuple('test_partitioned');
-ERROR: "test_partitioned" (partitioned table) is not supported
+ERROR: cannot get tuple-level statistics for relation "test_partitioned"
+DETAIL: This operation is not supported for partitioned tables.
select pgstattuple('test_partitioned_index');
-ERROR: "test_partitioned_index" (partitioned index) is not supported
+ERROR: cannot get tuple-level statistics for relation "test_partitioned_index"
+DETAIL: This operation is not supported for partitioned indexes.
select pgstattuple_approx('test_partitioned');
-ERROR: "test_partitioned" is not a table, materialized view, or TOAST table
+ERROR: relation "test_partitioned" is of wrong relation kind
+DETAIL: This operation is not supported for partitioned tables.
select pg_relpages('test_partitioned');
-ERROR: "test_partitioned" is not a table, index, materialized view, sequence, or TOAST table
+ERROR: cannot get page count of relation "test_partitioned"
+DETAIL: This operation is not supported for partitioned tables.
select pgstatindex('test_partitioned');
ERROR: relation "test_partitioned" is not a btree index
select pgstatginindex('test_partitioned');
@@ -171,11 +175,14 @@ ERROR: "test_partitioned" is not an index
create view test_view as select 1;
-- these should all fail
select pgstattuple('test_view');
-ERROR: "test_view" (view) is not supported
+ERROR: cannot get tuple-level statistics for relation "test_view"
+DETAIL: This operation is not supported for views.
select pgstattuple_approx('test_view');
-ERROR: "test_view" is not a table, materialized view, or TOAST table
+ERROR: relation "test_view" is of wrong relation kind
+DETAIL: This operation is not supported for views.
select pg_relpages('test_view');
-ERROR: "test_view" is not a table, index, materialized view, sequence, or TOAST table
+ERROR: cannot get page count of relation "test_view"
+DETAIL: This operation is not supported for views.
select pgstatindex('test_view');
ERROR: relation "test_view" is not a btree index
select pgstatginindex('test_view');
@@ -187,11 +194,14 @@ create server dummy_server foreign data wrapper dummy;
create foreign table test_foreign_table () server dummy_server;
-- these should all fail
select pgstattuple('test_foreign_table');
-ERROR: "test_foreign_table" (foreign table) is not supported
+ERROR: cannot get tuple-level statistics for relation "test_foreign_table"
+DETAIL: This operation is not supported for foreign tables.
select pgstattuple_approx('test_foreign_table');
-ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table
+ERROR: relation "test_foreign_table" is of wrong relation kind
+DETAIL: This operation is not supported for foreign tables.
select pg_relpages('test_foreign_table');
-ERROR: "test_foreign_table" is not a table, index, materialized view, sequence, or TOAST table
+ERROR: cannot get page count of relation "test_foreign_table"
+DETAIL: This operation is not supported for foreign tables.
select pgstatindex('test_foreign_table');
ERROR: relation "test_foreign_table" is not a btree index
select pgstatginindex('test_foreign_table');
diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c
index 1fe193bb25..3b836f370e 100644
--- a/contrib/pgstattuple/pgstatapprox.c
+++ b/contrib/pgstattuple/pgstatapprox.c
@@ -289,8 +289,9 @@ pgstattuple_approx_internal(Oid relid, FunctionCallInfo fcinfo)
rel->rd_rel->relkind == RELKIND_TOASTVALUE))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("\"%s\" is not a table, materialized view, or TOAST table",
- RelationGetRelationName(rel))));
+ errmsg("relation \"%s\" is of wrong relation kind",
+ RelationGetRelationName(rel)),
+ errdetail_relkind_not_supported(rel->rd_rel->relkind)));
if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c
index 5368bb30f0..6c4b053dd0 100644
--- a/contrib/pgstattuple/pgstatindex.c
+++ b/contrib/pgstattuple/pgstatindex.c
@@ -128,8 +128,8 @@ typedef struct HashIndexStat
} HashIndexStat;
static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo);
+static int64 pg_relpages_impl(Relation rel);
static void GetHashPageStats(Page page, HashIndexStat *stats);
-static void check_relation_relkind(Relation rel);
/* ------------------------------------------------------
* pgstatindex()
@@ -383,7 +383,6 @@ Datum
pg_relpages(PG_FUNCTION_ARGS)
{
text *relname = PG_GETARG_TEXT_PP(0);
- int64 relpages;
Relation rel;
RangeVar *relrv;
@@ -395,16 +394,7 @@ pg_relpages(PG_FUNCTION_ARGS)
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
- /* only some relkinds have storage */
- check_relation_relkind(rel);
-
- /* note: this will work OK on non-local temp tables */
-
- relpages = RelationGetNumberOfBlocks(rel);
-
- relation_close(rel, AccessShareLock);
-
- PG_RETURN_INT64(relpages);
+ PG_RETURN_INT64(pg_relpages_impl(rel));
}
/* No need for superuser checks in v1.5, see above */
@@ -412,23 +402,13 @@ Datum
pg_relpages_v1_5(PG_FUNCTION_ARGS)
{
text *relname = PG_GETARG_TEXT_PP(0);
- int64 relpages;
Relation rel;
RangeVar *relrv;
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
- /* only some relkinds have storage */
- check_relation_relkind(rel);
-
- /* note: this will work OK on non-local temp tables */
-
- relpages = RelationGetNumberOfBlocks(rel);
-
- relation_close(rel, AccessShareLock);
-
- PG_RETURN_INT64(relpages);
+ PG_RETURN_INT64(pg_relpages_impl(rel));
}
/* Must keep superuser() check, see above. */
@@ -436,7 +416,6 @@ Datum
pg_relpagesbyid(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
- int64 relpages;
Relation rel;
if (!superuser())
@@ -446,16 +425,7 @@ pg_relpagesbyid(PG_FUNCTION_ARGS)
rel = relation_open(relid, AccessShareLock);
- /* only some relkinds have storage */
- check_relation_relkind(rel);
-
- /* note: this will work OK on non-local temp tables */
-
- relpages = RelationGetNumberOfBlocks(rel);
-
- relation_close(rel, AccessShareLock);
-
- PG_RETURN_INT64(relpages);
+ PG_RETURN_INT64(pg_relpages_impl(rel));
}
/* No need for superuser checks in v1.5, see above */
@@ -463,13 +433,24 @@ Datum
pg_relpagesbyid_v1_5(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
- int64 relpages;
Relation rel;
rel = relation_open(relid, AccessShareLock);
- /* only some relkinds have storage */
- check_relation_relkind(rel);
+ PG_RETURN_INT64(pg_relpages_impl(rel));
+}
+
+static int64
+pg_relpages_impl(Relation rel)
+{
+ int64 relpages;
+
+ if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot get page count of relation \"%s\"",
+ RelationGetRelationName(rel)),
+ errdetail_relkind_not_supported(rel->rd_rel->relkind)));
/* note: this will work OK on non-local temp tables */
@@ -477,7 +458,7 @@ pg_relpagesbyid_v1_5(PG_FUNCTION_ARGS)
relation_close(rel, AccessShareLock);
- PG_RETURN_INT64(relpages);
+ return relpages;
}
/* ------------------------------------------------------
@@ -754,21 +735,3 @@ GetHashPageStats(Page page, HashIndexStat *stats)
}
stats->free_space += PageGetExactFreeSpace(page);
}
-
-/*
- * check_relation_relkind - convenience routine to check that relation
- * is of the relkind supported by the callers
- */
-static void
-check_relation_relkind(Relation rel)
-{
- if (rel->rd_rel->relkind != RELKIND_RELATION &&
- rel->rd_rel->relkind != RELKIND_INDEX &&
- rel->rd_rel->relkind != RELKIND_MATVIEW &&
- rel->rd_rel->relkind != RELKIND_SEQUENCE &&
- rel->rd_rel->relkind != RELKIND_TOASTVALUE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table, index, materialized view, sequence, or TOAST table",
- RelationGetRelationName(rel))));
-}
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index 21fdeff8af..f408e6d84d 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -284,31 +284,20 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
err = "unknown index";
break;
}
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("index \"%s\" (%s) is not supported",
+ RelationGetRelationName(rel), err)));
break;
- case RELKIND_VIEW:
- err = "view";
- break;
- case RELKIND_COMPOSITE_TYPE:
- err = "composite type";
- break;
- case RELKIND_FOREIGN_TABLE:
- err = "foreign table";
- break;
- case RELKIND_PARTITIONED_TABLE:
- err = "partitioned table";
- break;
- case RELKIND_PARTITIONED_INDEX:
- err = "partitioned index";
- break;
+
default:
- err = "unknown";
- break;
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot get tuple-level statistics for relation \"%s\"",
+ RelationGetRelationName(rel)),
+ errdetail_relkind_not_supported(rel->rd_rel->relkind)));
}
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("\"%s\" (%s) is not supported",
- RelationGetRelationName(rel), err)));
return 0; /* should not happen */
}