]> granicus.if.org Git - postgresql/commitdiff
Disallow creation of indexes on system columns (except for OID).
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 16 Apr 2016 16:11:41 +0000 (12:11 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 16 Apr 2016 16:11:41 +0000 (12:11 -0400)
Although OID acts pretty much like user data, the other system columns do
not, so an index on one would likely misbehave.  And it's pretty hard to
see a use-case for one, anyway.  Let's just forbid the case rather than
worry about whether it should be supported.

David Rowley

src/backend/commands/indexcmds.c
src/test/regress/expected/create_index.out
src/test/regress/sql/create_index.sql

index 13b04e68f01dda3a8511ed8ba1556a84109550fa..d14d540b26e0d706126da5575295aa903dcfc26c 100644 (file)
@@ -18,6 +18,7 @@
 #include "access/amapi.h"
 #include "access/htup_details.h"
 #include "access/reloptions.h"
+#include "access/sysattr.h"
 #include "access/xact.h"
 #include "catalog/catalog.h"
 #include "catalog/index.h"
@@ -37,6 +38,7 @@
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/planner.h"
+#include "optimizer/var.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_func.h"
 #include "parser/parse_oper.h"
@@ -574,6 +576,41 @@ DefineIndex(Oid relationId,
        if (stmt->primary)
                index_check_primary_key(rel, indexInfo, is_alter_table);
 
+       /*
+        * We disallow indexes on system columns other than OID.  They would not
+        * necessarily get updated correctly, and they don't seem useful anyway.
+        */
+       for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
+       {
+               AttrNumber      attno = indexInfo->ii_KeyAttrNumbers[i];
+
+               if (attno < 0 && attno != ObjectIdAttributeNumber)
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                          errmsg("index creation on system columns is not supported")));
+       }
+
+       /*
+        * Also check for system columns used in expressions or predicates.
+        */
+       if (indexInfo->ii_Expressions || indexInfo->ii_Predicate)
+       {
+               Bitmapset  *indexattrs = NULL;
+
+               pull_varattnos((Node *) indexInfo->ii_Expressions, 1, &indexattrs);
+               pull_varattnos((Node *) indexInfo->ii_Predicate, 1, &indexattrs);
+
+               for (i = FirstLowInvalidHeapAttributeNumber + 1; i < 0; i++)
+               {
+                       if (i != ObjectIdAttributeNumber &&
+                               bms_is_member(i - FirstLowInvalidHeapAttributeNumber,
+                                                         indexattrs))
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                               errmsg("index creation on system columns is not supported")));
+               }
+       }
+
        /*
         * Report index creation if appropriate (delay this till after most of the
         * error checks)
index b72e65d1bd086baac657414f4e71aa9bf7fa6b48..97cc49e623557d6b900dc6c589f7cc87bb8ffe99 100644 (file)
@@ -2541,6 +2541,22 @@ ERROR:  cannot drop index cwi_replaced_pkey because constraint cwi_replaced_pkey
 HINT:  You can drop constraint cwi_replaced_pkey on table cwi_test instead.
 DROP TABLE cwi_test;
 --
+-- Check handling of indexes on system columns
+--
+CREATE TABLE oid_table (a INT) WITH OIDS;
+-- An index on the OID column should be allowed
+CREATE INDEX ON oid_table (oid);
+-- Other system columns cannot be indexed
+CREATE INDEX ON oid_table (ctid);
+ERROR:  index creation on system columns is not supported
+-- nor used in expressions
+CREATE INDEX ON oid_table ((ctid >= '(1000,0)'));
+ERROR:  index creation on system columns is not supported
+-- nor used in predicates
+CREATE INDEX ON oid_table (a) WHERE ctid >= '(1000,0)';
+ERROR:  index creation on system columns is not supported
+DROP TABLE oid_table;
+--
 -- Tests for IS NULL/IS NOT NULL with b-tree indexes
 --
 SELECT unique1, unique2 INTO onek_with_null FROM onek;
index ff8695361ce65a79855a9a4fa7313584886eb911..7c582ea810e979ddf2c86d83e329f35d165fd4af 100644 (file)
@@ -824,6 +824,25 @@ DROP INDEX cwi_replaced_pkey;      -- Should fail; a constraint depends on it
 
 DROP TABLE cwi_test;
 
+--
+-- Check handling of indexes on system columns
+--
+CREATE TABLE oid_table (a INT) WITH OIDS;
+
+-- An index on the OID column should be allowed
+CREATE INDEX ON oid_table (oid);
+
+-- Other system columns cannot be indexed
+CREATE INDEX ON oid_table (ctid);
+
+-- nor used in expressions
+CREATE INDEX ON oid_table ((ctid >= '(1000,0)'));
+
+-- nor used in predicates
+CREATE INDEX ON oid_table (a) WHERE ctid >= '(1000,0)';
+
+DROP TABLE oid_table;
+
 --
 -- Tests for IS NULL/IS NOT NULL with b-tree indexes
 --