From: MasaoFujii Date: Fri, 14 Aug 2015 10:09:05 +0000 (+0900) Subject: Make pg_gin_pending_stats() check whether given relation is a GIN index. X-Git-Tag: v1.2-20161011~31 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=5117b57b4e0cf343b87662f3c4e26c64df98e0cc;p=pgbigm%2Fpg_bigm.git Make pg_gin_pending_stats() check whether given relation is a GIN index. Previously pg_gin_pending_stats() didn't do such a check, so it could return an improper and irrelevant result when non-GIN index was specified. This is a bug. This patch changes pg_gin_pending_stats() so that it exits with an error when the given relation is not a GIN index. Also this patch prevents pg_gin_pending_stats() from reading non-local temporary relations. Back-patch to all supported versions. --- diff --git a/bigm_gin.c b/bigm_gin.c index d5e9a25..f65855f 100644 --- a/bigm_gin.c +++ b/bigm_gin.c @@ -27,6 +27,7 @@ #include "tsearch/ts_locale.h" #include "utils/array.h" #include "utils/builtins.h" +#include "utils/rel.h" PG_FUNCTION_INFO_V1(gin_extract_value_bigm); @@ -372,15 +373,32 @@ pg_gin_pending_stats(PG_FUNCTION_ARGS) HeapTuple tuple; TupleDesc tupdesc; + indexRel = relation_open(indexOid, AccessShareLock); + + if (indexRel->rd_rel->relkind != RELKIND_INDEX || + indexRel->rd_rel->relam != GIN_AM_OID) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("relation \"%s\" is not a GIN index", + RelationGetRelationName(indexRel)))); + + /* + * Reject attempts to read non-local temporary relations; we would be + * likely to get wrong data since we have no visibility into the owning + * session's local buffers. + */ + if (RELATION_IS_OTHER_TEMP(indexRel)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot access temporary indexes of other sessions"))); + /* * Obtain statistic information from the meta page */ - indexRel = index_open(indexOid, AccessShareLock); metabuffer = ReadBuffer(indexRel, GIN_METAPAGE_BLKNO); LockBuffer(metabuffer, GIN_SHARE); metapage = BufferGetPage(metabuffer); metadata = GinPageGetMeta(metapage); - index_close(indexRel, AccessShareLock); /* * Construct a tuple descriptor for the result row. This must match this @@ -402,6 +420,7 @@ pg_gin_pending_stats(PG_FUNCTION_ARGS) isnull[1] = false; UnlockReleaseBuffer(metabuffer); + relation_close(indexRel, AccessShareLock); tuple = heap_form_tuple(tupdesc, values, isnull); PG_RETURN_DATUM(HeapTupleGetDatum(tuple)); diff --git a/expected/pg_bigm.out b/expected/pg_bigm.out index 7e175cc..6ccc4ce 100644 --- a/expected/pg_bigm.out +++ b/expected/pg_bigm.out @@ -114,6 +114,12 @@ SELECT * FROM pg_gin_pending_stats('test_bigm_idx'); 0 | 0 (1 row) +SELECT * FROM pg_gin_pending_stats('test_bigm'); +ERROR: relation "test_bigm" is not a GIN index +CREATE INDEX test_bigm_btree ON test_bigm USING btree (col2); +SELECT * FROM pg_gin_pending_stats('test_bigm_btree'); +ERROR: relation "test_bigm_btree" is not a GIN index +DROP INDEX test_bigm_btree; -- tests for full-text search EXPLAIN (COSTS off) SELECT * FROM test_bigm WHERE col1 LIKE likequery('a'); QUERY PLAN diff --git a/sql/pg_bigm.sql b/sql/pg_bigm.sql index 0fa397a..76d186d 100644 --- a/sql/pg_bigm.sql +++ b/sql/pg_bigm.sql @@ -41,6 +41,10 @@ CREATE INDEX test_bigm_idx ON test_bigm SELECT * FROM pg_gin_pending_stats('test_bigm_idx'); VACUUM; SELECT * FROM pg_gin_pending_stats('test_bigm_idx'); +SELECT * FROM pg_gin_pending_stats('test_bigm'); +CREATE INDEX test_bigm_btree ON test_bigm USING btree (col2); +SELECT * FROM pg_gin_pending_stats('test_bigm_btree'); +DROP INDEX test_bigm_btree; -- tests for full-text search EXPLAIN (COSTS off) SELECT * FROM test_bigm WHERE col1 LIKE likequery('a');