OSDN Git Service

Make pg_gin_pending_stats() check whether given relation is a GIN index.
authorMasaoFujii <masao.fujii@gmail.com>
Fri, 14 Aug 2015 10:09:05 +0000 (19:09 +0900)
committerMasaoFujii <masao.fujii@gmail.com>
Fri, 14 Aug 2015 10:09:05 +0000 (19:09 +0900)
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.

bigm_gin.c
expected/pg_bigm.out
sql/pg_bigm.sql

index d5e9a25..f65855f 100644 (file)
@@ -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));
index 7e175cc..6ccc4ce 100644 (file)
@@ -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                 
index 0fa397a..76d186d 100644 (file)
@@ -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');