summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2003-03-03 04:37:37 +0000
committerTom Lane2003-03-03 04:37:37 +0000
commita455c942574f2d6414d49893fe8ee2779c636acb (patch)
tree29a1606afe83a49c2b3ea5d17dfbac7df90d3228
parentd28cd2273b81c17ce3ddcc09d90353daa229a2a7 (diff)
Prevent clustering on incomplete indexes: partial indexes are verboten,
as are non-amindexnulls AMs unless first column is attnotnull.
-rw-r--r--src/backend/commands/cluster.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 0a0e0afae34..30d251869bc 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.105 2003/02/09 06:56:26 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.106 2003/03/03 04:37:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -160,6 +160,7 @@ cluster(ClusterStmt *stmt)
stmt->indexname, stmt->relation->relname);
}
+ /* All other checks are done in cluster_rel() */
rvtc.tableOid = tableOid;
rvtc.indexOid = indexOid;
@@ -314,6 +315,34 @@ cluster_rel(RelToCluster *rvtc, bool recheck)
RelationGetRelationName(OldHeap));
/*
+ * Disallow clustering on incomplete indexes (those that might not index
+ * every row of the relation). We could relax this by making a separate
+ * seqscan pass over the table to copy the missing rows, but that seems
+ * expensive and tedious.
+ */
+ if (VARSIZE(&OldIndex->rd_index->indpred) > VARHDRSZ) /* partial? */
+ elog(ERROR, "CLUSTER: cannot cluster on partial index");
+ if (!OldIndex->rd_am->amindexnulls)
+ {
+ AttrNumber colno;
+
+ /*
+ * If the AM doesn't index nulls, then it's a partial index unless
+ * we can prove all the rows are non-null. Note we only need look
+ * at the first column; multicolumn-capable AMs are *required* to
+ * index nulls in columns after the first.
+ */
+ if (OidIsValid(OldIndex->rd_index->indproc))
+ elog(ERROR, "CLUSTER: cannot cluster on functional index when index access method does not handle nulls");
+ colno = OldIndex->rd_index->indkey[0];
+ if (colno > 0) /* system columns are non-null */
+ if (!OldHeap->rd_att->attrs[colno - 1]->attnotnull)
+ elog(ERROR, "CLUSTER: cannot cluster when index access method does not handle nulls"
+ "\n\tYou may be able to work around this by marking column \"%s\" NOT NULL",
+ NameStr(OldHeap->rd_att->attrs[colno - 1]->attname));
+ }
+
+ /*
* Disallow clustering system relations. This will definitely NOT
* work for shared relations (we have no way to update pg_class rows
* in other databases), nor for nailed-in-cache relations (the