diff options
author | Tom Lane | 2003-03-03 04:37:37 +0000 |
---|---|---|
committer | Tom Lane | 2003-03-03 04:37:37 +0000 |
commit | a455c942574f2d6414d49893fe8ee2779c636acb (patch) | |
tree | 29a1606afe83a49c2b3ea5d17dfbac7df90d3228 | |
parent | d28cd2273b81c17ce3ddcc09d90353daa229a2a7 (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.c | 31 |
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 |