OSDN Git Service

Remove pg_am.amindexnulls.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 8 Jan 2011 21:08:05 +0000 (16:08 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 8 Jan 2011 21:08:05 +0000 (16:08 -0500)
The only use we have had for amindexnulls is in determining whether an
index is safe to cluster on; but since the addition of the amclusterable
flag, that usage is pretty redundant.

In passing, clean up assorted sloppiness from the last patch that touched
pg_am.h: Natts_pg_am was wrong, and ambuildempty was not documented.

doc/src/sgml/catalogs.sgml
doc/src/sgml/indexam.sgml
src/backend/commands/cluster.c
src/include/catalog/catversion.h
src/include/catalog/pg_am.h

index 67ba340..cd390d8 100644 (file)
      </row>
 
      <row>
-      <entry><structfield>amindexnulls</structfield></entry>
-      <entry><type>bool</type></entry>
-      <entry></entry>
-      <entry>Does the access method support null index entries?</entry>
-     </row>
-
-     <row>
       <entry><structfield>amsearchnulls</structfield></entry>
       <entry><type>bool</type></entry>
       <entry></entry>
      </row>
 
      <row>
+      <entry><structfield>ambuildempty</structfield></entry>
+      <entry><type>regproc</type></entry>
+      <entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
+      <entry><quote>Build empty index</quote> function</entry>
+     </row>
+
+     <row>
       <entry><structfield>ambulkdelete</structfield></entry>
       <entry><type>regproc</type></entry>
       <entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
index 51e70e9..241064a 100644 (file)
    where no indexable restriction clause is given for the first index column.
    When <structfield>amcanmulticol</structfield> is false,
    <structfield>amoptionalkey</structfield> essentially says whether the
-   access method allows full-index scans without any restriction clause.
+   access method supports full-index scans without any restriction clause.
    Access methods that support multiple index columns <emphasis>must</>
    support scans that omit restrictions on any or all of the columns after
    the first; however they are permitted to require some restriction to
    appear for the first index column, and this is signaled by setting
    <structfield>amoptionalkey</structfield> false.
-   <structfield>amindexnulls</structfield> asserts that index entries are
-   created for NULL key values.  Since most indexable operators are
+   One reason that an index AM might set
+   <structfield>amoptionalkey</structfield> false is if it doesn't index
+   NULLs.  Since most indexable operators are
    strict and hence cannot return TRUE for NULL inputs,
    it is at first sight attractive to not store index entries for null values:
    they could never be returned by an index scan anyway.  However, this
    used to scan for rows with <literal>a = 4</literal>, which is wrong if the
    index omits rows where <literal>b</> is null.
    It is, however, OK to omit rows where the first indexed column is null.
-   Thus, <structfield>amindexnulls</structfield> should be set true only if the
-   index access method indexes all rows, including arbitrary combinations of
-   null values.  An index access method that sets
-   <structfield>amindexnulls</structfield> may also set
+   An index access method that does index nulls may also set
    <structfield>amsearchnulls</structfield>, indicating that it supports
    <literal>IS NULL</> and <literal>IS NOT NULL</> clauses as search
    conditions.
index 560f42b..19c3cf9 100644 (file)
@@ -436,43 +436,6 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck, LOCKMOD
                                 errmsg("cannot cluster on partial index \"%s\"",
                                                RelationGetRelationName(OldIndex))));
 
-       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.
-                */
-               colno = OldIndex->rd_index->indkey.values[0];
-               if (colno > 0)
-               {
-                       /* ordinary user attribute */
-                       if (!OldHeap->rd_att->attrs[colno - 1]->attnotnull)
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                errmsg("cannot cluster on index \"%s\" because access method does not handle null values",
-                                                               RelationGetRelationName(OldIndex)),
-                                                recheck
-                                                ? errhint("You might be able to work around this by marking column \"%s\" NOT NULL, or use ALTER TABLE ... SET WITHOUT CLUSTER to remove the cluster specification from the table.",
-                                                NameStr(OldHeap->rd_att->attrs[colno - 1]->attname))
-                                                : errhint("You might be able to work around this by marking column \"%s\" NOT NULL.",
-                                         NameStr(OldHeap->rd_att->attrs[colno - 1]->attname))));
-               }
-               else if (colno < 0)
-               {
-                       /* system column --- okay, always non-null */
-               }
-               else
-                       /* index expression, lose... */
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                        errmsg("cannot cluster on expressional index \"%s\" because its index access method does not handle null values",
-                                                       RelationGetRelationName(OldIndex))));
-       }
-
        /*
         * Disallow if index is left over from a failed CREATE INDEX CONCURRENTLY;
         * it might well not contain entries for every heap row, or might not even
index 92e1a0f..7a03b1c 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201101071
+#define CATALOG_VERSION_NO     201101081
 
 #endif
index a0822db..16fbdd6 100644 (file)
@@ -46,7 +46,6 @@ CATALOG(pg_am,2601)
        bool            amcanunique;    /* does AM support UNIQUE indexes? */
        bool            amcanmulticol;  /* does AM support multi-column indexes? */
        bool            amoptionalkey;  /* can query omit key for the first column? */
-       bool            amindexnulls;   /* does AM support NULL index entries? */
        bool            amsearchnulls;  /* can AM search for NULL/NOT NULL entries? */
        bool            amstorage;              /* can storage type differ from column type? */
        bool            amclusterable;  /* does AM support cluster command? */
@@ -88,41 +87,40 @@ typedef FormData_pg_am *Form_pg_am;
 #define Anum_pg_am_amcanunique                 7
 #define Anum_pg_am_amcanmulticol               8
 #define Anum_pg_am_amoptionalkey               9
-#define Anum_pg_am_amindexnulls                        10
-#define Anum_pg_am_amsearchnulls               11
-#define Anum_pg_am_amstorage                   12
-#define Anum_pg_am_amclusterable               13
-#define Anum_pg_am_amkeytype                   14
-#define Anum_pg_am_aminsert                            15
-#define Anum_pg_am_ambeginscan                 16
-#define Anum_pg_am_amgettuple                  17
-#define Anum_pg_am_amgetbitmap                 18
-#define Anum_pg_am_amrescan                            19
-#define Anum_pg_am_amendscan                   20
-#define Anum_pg_am_ammarkpos                   21
-#define Anum_pg_am_amrestrpos                  22
-#define Anum_pg_am_ambuild                             23
-#define Anum_pg_am_ambuildempty                        24
-#define Anum_pg_am_ambulkdelete                        25
-#define Anum_pg_am_amvacuumcleanup             26
-#define Anum_pg_am_amcostestimate              27
-#define Anum_pg_am_amoptions                   28
+#define Anum_pg_am_amsearchnulls               10
+#define Anum_pg_am_amstorage                   11
+#define Anum_pg_am_amclusterable               12
+#define Anum_pg_am_amkeytype                   13
+#define Anum_pg_am_aminsert                            14
+#define Anum_pg_am_ambeginscan                 15
+#define Anum_pg_am_amgettuple                  16
+#define Anum_pg_am_amgetbitmap                 17
+#define Anum_pg_am_amrescan                            18
+#define Anum_pg_am_amendscan                   19
+#define Anum_pg_am_ammarkpos                   20
+#define Anum_pg_am_amrestrpos                  21
+#define Anum_pg_am_ambuild                             22
+#define Anum_pg_am_ambuildempty                        23
+#define Anum_pg_am_ambulkdelete                        24
+#define Anum_pg_am_amvacuumcleanup             25
+#define Anum_pg_am_amcostestimate              26
+#define Anum_pg_am_amoptions                   27
 
 /* ----------------
  *             initial contents of pg_am
  * ----------------
  */
 
-DATA(insert OID = 403 (  btree 5 1 t f t t t t t f t 0 btinsert btbeginscan btgettuple btgetbitmap btrescan btendscan btmarkpos btrestrpos btbuild btbuildempty btbulkdelete btvacuumcleanup btcostestimate btoptions ));
+DATA(insert OID = 403 (  btree 5 1 t f t t t t t f t 0 btinsert btbeginscan btgettuple btgetbitmap btrescan btendscan btmarkpos btrestrpos btbuild btbuildempty btbulkdelete btvacuumcleanup btcostestimate btoptions ));
 DESCR("b-tree index access method");
 #define BTREE_AM_OID 403
-DATA(insert OID = 405 (  hash  1 1 f f t f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions ));
+DATA(insert OID = 405 (  hash  1 1 f f t f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions ));
 DESCR("hash index access method");
 #define HASH_AM_OID 405
-DATA(insert OID = 783 (  gist  0 8 f t f f t t t t t 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions ));
+DATA(insert OID = 783 (  gist  0 8 f t f f t t t t t 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions ));
 DESCR("GiST index access method");
 #define GIST_AM_OID 783
-DATA(insert OID = 2742 (  gin  0 5 f f f f t t f t f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup gincostestimate ginoptions ));
+DATA(insert OID = 2742 (  gin  0 5 f f f f t t f t f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup gincostestimate ginoptions ));
 DESCR("GIN index access method");
 #define GIN_AM_OID 2742