Some contrib functions fail to fail sooner when relations of unsupported
relkinds are passed, resulting in error message like one below:
create table foo (a int);
create view foov as select * from foo;
select pg_visibility('foov', 0);
ERROR: could not open file "base/13123/16488": No such file or directory
Attached patch fixes that for all such functions I could find in contrib.
It also installs RELKIND_PARTITIONED_TABLE as unsupported in a couple of
places (in pageinspect and pgstattuple).
Thanks,
Amit
>From 9324727c58f2debb45ceeee7ecd6d620a3fe8b2a Mon Sep 17 00:00:00 2001
From: amit <[email protected]>
Date: Tue, 24 Jan 2017 13:22:17 +0900
Subject: [PATCH] Add relkind checks to certain contrib modules
Contrib functions such a pg_visibility, pg_relpages are only applicable
to certain relkinds; error out if otherwise.
Also, RELKIND_PARTITIONED_TABLE was not added to the pageinspect's and
pgstattuple's list of unsupported relkinds.
---
contrib/pageinspect/rawpage.c | 5 ++++
contrib/pg_visibility/pg_visibility.c | 28 ++++++++++++++++++++++
contrib/pgstattuple/pgstatindex.c | 44 +++++++++++++++++++++++++++++++++++
contrib/pgstattuple/pgstattuple.c | 3 +++
4 files changed, 80 insertions(+)
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index a2ac078d40..65aae6b6f8 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -121,6 +121,11 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
(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))));
/*
* Reject attempts to read non-local temporary relations; we would be
diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index 5580637870..61d7224ee7 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -114,6 +114,15 @@ pg_visibility(PG_FUNCTION_ARGS)
rel = relation_open(relid, AccessShareLock);
+ /* Other relkinds don't have visibility info */
+ if (rel->rd_rel->relkind != RELKIND_RELATION &&
+ rel->rd_rel->relkind != RELKIND_MATVIEW &&
+ 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))));
+
if (blkno < 0 || blkno > MaxBlockNumber)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -257,6 +266,16 @@ pg_visibility_map_summary(PG_FUNCTION_ARGS)
bool nulls[2];
rel = relation_open(relid, AccessShareLock);
+
+ /* Other relkinds don't have visibility info */
+ if (rel->rd_rel->relkind != RELKIND_RELATION &&
+ rel->rd_rel->relkind != RELKIND_MATVIEW &&
+ 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))));
+
nblocks = RelationGetNumberOfBlocks(rel);
for (blkno = 0; blkno < nblocks; ++blkno)
@@ -464,6 +483,15 @@ collect_visibility_data(Oid relid, bool include_pd)
rel = relation_open(relid, AccessShareLock);
+ /* Other relkinds don't have visibility info */
+ if (rel->rd_rel->relkind != RELKIND_RELATION &&
+ rel->rd_rel->relkind != RELKIND_MATVIEW &&
+ 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))));
+
nblocks = RelationGetNumberOfBlocks(rel);
info = palloc0(offsetof(vbits, bits) +nblocks);
info->next = 0;
diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c
index b40669250a..e9e2dc2207 100644
--- a/contrib/pgstattuple/pgstatindex.c
+++ b/contrib/pgstattuple/pgstatindex.c
@@ -362,6 +362,17 @@ pg_relpages(PG_FUNCTION_ARGS)
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
+ /* only the following relkinds have storage */
+ 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_FEATURE_NOT_SUPPORTED),
+ errmsg("\"%s\" is not a table, index, materialized view, sequence, or TOAST table",
+ RelationGetRelationName(rel))));
+
/* note: this will work OK on non-local temp tables */
relpages = RelationGetNumberOfBlocks(rel);
@@ -383,6 +394,17 @@ pg_relpages_v1_5(PG_FUNCTION_ARGS)
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
+ /* only the following relkinds have storage */
+ 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_FEATURE_NOT_SUPPORTED),
+ errmsg("\"%s\" is not a table, index, materialized view, sequence, or TOAST table",
+ RelationGetRelationName(rel))));
+
/* note: this will work OK on non-local temp tables */
relpages = RelationGetNumberOfBlocks(rel);
@@ -407,6 +429,17 @@ pg_relpagesbyid(PG_FUNCTION_ARGS)
rel = relation_open(relid, AccessShareLock);
+ /* only the following relkinds have storage */
+ 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_FEATURE_NOT_SUPPORTED),
+ errmsg("\"%s\" is not a table, index, materialized view, sequence, or TOAST table",
+ RelationGetRelationName(rel))));
+
/* note: this will work OK on non-local temp tables */
relpages = RelationGetNumberOfBlocks(rel);
@@ -426,6 +459,17 @@ pg_relpagesbyid_v1_5(PG_FUNCTION_ARGS)
rel = relation_open(relid, AccessShareLock);
+ /* only the following relkinds have storage */
+ 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_FEATURE_NOT_SUPPORTED),
+ errmsg("\"%s\" is not a table, index, materialized view, sequence, or TOAST table",
+ RelationGetRelationName(rel))));
+
/* note: this will work OK on non-local temp tables */
relpages = RelationGetNumberOfBlocks(rel);
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index 06a1992bb1..b2432f43ed 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -293,6 +293,9 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo)
case RELKIND_FOREIGN_TABLE:
err = "foreign table";
break;
+ case RELKIND_PARTITIONED_TABLE:
+ err = "partitioned table";
+ break;
default:
err = "unknown";
break;
--
2.11.0
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers