aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/indexcmds.c37
-rw-r--r--src/test/regress/expected/create_index.out16
-rw-r--r--src/test/regress/sql/create_index.sql19
3 files changed, 72 insertions, 0 deletions
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 13b04e68f01..d14d540b26e 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -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"
@@ -575,6 +577,41 @@ DefineIndex(Oid relationId,
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)
*/
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index b72e65d1bd0..97cc49e6235 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -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;
diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
index ff8695361ce..7c582ea810e 100644
--- a/src/test/regress/sql/create_index.sql
+++ b/src/test/regress/sql/create_index.sql
@@ -825,6 +825,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
--