diff options
Diffstat (limited to 'contrib')
| -rw-r--r-- | contrib/amcheck/expected/check_heap.out | 15 | ||||
| -rw-r--r-- | contrib/amcheck/verify_heapam.c | 38 | ||||
| -rw-r--r-- | contrib/pageinspect/expected/page.out | 6 | ||||
| -rw-r--r-- | contrib/pageinspect/rawpage.c | 28 | ||||
| -rw-r--r-- | contrib/pg_surgery/expected/heap_surgery.out | 6 | ||||
| -rw-r--r-- | contrib/pg_surgery/heap_surgery.c | 54 | ||||
| -rw-r--r-- | contrib/pg_visibility/expected/pg_visibility.out | 75 | ||||
| -rw-r--r-- | contrib/pg_visibility/pg_visibility.c | 5 | ||||
| -rw-r--r-- | contrib/pgstattuple/expected/pgstattuple.out | 30 | ||||
| -rw-r--r-- | contrib/pgstattuple/pgstatapprox.c | 5 | ||||
| -rw-r--r-- | contrib/pgstattuple/pgstatindex.c | 75 | ||||
| -rw-r--r-- | contrib/pgstattuple/pgstattuple.c | 31 |
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 */ } |
