</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>
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.
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
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201101071
+#define CATALOG_VERSION_NO 201101081
#endif
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? */
#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 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 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 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 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