]> granicus.if.org Git - postgresql/commitdiff
Prevent clustering on incomplete indexes: partial indexes are verboten,
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Mar 2003 04:37:37 +0000 (04:37 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Mar 2003 04:37:37 +0000 (04:37 +0000)
as are non-amindexnulls AMs unless first column is attnotnull.

src/backend/commands/cluster.c

index 0a0e0afae34aab2a43b8bdfdf8f305d64d065695..30d251869bc553d08823f21952af732e5f412bcc 100644 (file)
@@ -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;
 
@@ -313,6 +314,34 @@ cluster_rel(RelToCluster *rvtc, bool recheck)
                         RelationGetRelationName(OldIndex),
                         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