aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/cluster.c14
-rw-r--r--src/backend/optimizer/util/plancat.c10
-rw-r--r--src/test/regress/expected/cluster.out8
-rw-r--r--src/test/regress/expected/indexing.out11
-rw-r--r--src/test/regress/sql/cluster.sql7
-rw-r--r--src/test/regress/sql/indexing.sql8
6 files changed, 58 insertions, 0 deletions
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index eb73299199a..1701548d844 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -128,6 +128,14 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot cluster temporary tables of other sessions")));
+ /*
+ * Reject clustering a partitioned table.
+ */
+ if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot cluster a partitioned table")));
+
if (stmt->indexname == NULL)
{
ListCell *index;
@@ -482,6 +490,12 @@ mark_index_clustered(Relation rel, Oid indexOid, bool is_internal)
Relation pg_index;
ListCell *index;
+ /* Disallow applying to a partitioned table */
+ if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot mark index clustered in partitioned table")));
+
/*
* If the index is already marked clustered, no need to do anything.
*/
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 8c60b35068e..60f21711f4f 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -208,6 +208,16 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
}
/*
+ * Ignore partitioned indexes, since they are not usable for
+ * queries.
+ */
+ if (indexRelation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
+ {
+ index_close(indexRelation, NoLock);
+ continue;
+ }
+
+ /*
* If the index is valid, but cannot yet be used, ignore it; but
* mark the plan we are generating as transient. See
* src/backend/access/heap/README.HOT for discussion.
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 82713bfa2c7..2bb62212ea7 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -439,6 +439,14 @@ select * from clstr_temp;
drop table clstr_temp;
RESET SESSION AUTHORIZATION;
+-- Check that partitioned tables cannot be clustered
+CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a);
+CREATE INDEX clstrpart_idx ON clstrpart (a);
+ALTER TABLE clstrpart CLUSTER ON clstrpart_idx;
+ERROR: cannot mark index clustered in partitioned table
+CLUSTER clstrpart USING clstrpart_idx;
+ERROR: cannot cluster a partitioned table
+DROP TABLE clstrpart;
-- Test CLUSTER with external tuplesorting
create table clstr_4 as select * from tenk1;
create index cluster_sort on clstr_4 (hundred, thousand, tenthous);
diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out
index ffd4b10c37e..e034ad3aadb 100644
--- a/src/test/regress/expected/indexing.out
+++ b/src/test/regress/expected/indexing.out
@@ -31,6 +31,17 @@ ERROR: cannot create unique index on partitioned table "idxpart"
create index concurrently on idxpart (a);
ERROR: cannot create index on partitioned table "idxpart" concurrently
drop table idxpart;
+-- Verify bugfix with query on indexed partitioned table with no partitions
+-- https://postgr.es/m/20180124162006.pmapfiznhgngwtjf@alvherre.pgsql
+CREATE TABLE idxpart (col1 INT) PARTITION BY RANGE (col1);
+CREATE INDEX ON idxpart (col1);
+CREATE TABLE idxpart_two (col2 INT);
+SELECT col2 FROM idxpart_two fk LEFT OUTER JOIN idxpart pk ON (col1 = col2);
+ col2
+------
+(0 rows)
+
+DROP table idxpart, idxpart_two;
-- If a table without index is attached as partition to a table with
-- an index, the index is automatically created
create table idxpart (a int, b int, c text) partition by range (a);
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index a6c2757efaa..522bfeead41 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -196,6 +196,13 @@ drop table clstr_temp;
RESET SESSION AUTHORIZATION;
+-- Check that partitioned tables cannot be clustered
+CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a);
+CREATE INDEX clstrpart_idx ON clstrpart (a);
+ALTER TABLE clstrpart CLUSTER ON clstrpart_idx;
+CLUSTER clstrpart USING clstrpart_idx;
+DROP TABLE clstrpart;
+
-- Test CLUSTER with external tuplesorting
create table clstr_4 as select * from tenk1;
diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql
index 2f985ec8667..1a9ea89adeb 100644
--- a/src/test/regress/sql/indexing.sql
+++ b/src/test/regress/sql/indexing.sql
@@ -19,6 +19,14 @@ create unique index on idxpart (a);
create index concurrently on idxpart (a);
drop table idxpart;
+-- Verify bugfix with query on indexed partitioned table with no partitions
+-- https://postgr.es/m/20180124162006.pmapfiznhgngwtjf@alvherre.pgsql
+CREATE TABLE idxpart (col1 INT) PARTITION BY RANGE (col1);
+CREATE INDEX ON idxpart (col1);
+CREATE TABLE idxpart_two (col2 INT);
+SELECT col2 FROM idxpart_two fk LEFT OUTER JOIN idxpart pk ON (col1 = col2);
+DROP table idxpart, idxpart_two;
+
-- If a table without index is attached as partition to a table with
-- an index, the index is automatically created
create table idxpart (a int, b int, c text) partition by range (a);