]> granicus.if.org Git - postgresql/commitdiff
Revert CREATE INDEX ... INCLUDING ...
authorTeodor Sigaev <teodor@sigaev.ru>
Fri, 8 Apr 2016 18:52:13 +0000 (21:52 +0300)
committerTeodor Sigaev <teodor@sigaev.ru>
Fri, 8 Apr 2016 18:52:13 +0000 (21:52 +0300)
It's not ready yet, revert two commits
690c543550b0d2852060c18d270cdb534d339d9a - unstable test output
386e3d7609c49505e079c40c65919d99feb82505 - patch itself

68 files changed:
contrib/dblink/dblink.c
contrib/tcn/tcn.c
doc/src/sgml/catalogs.sgml
doc/src/sgml/indexam.sgml
doc/src/sgml/indices.sgml
doc/src/sgml/ref/create_index.sgml
doc/src/sgml/ref/create_table.sgml
src/backend/access/brin/brin.c
src/backend/access/common/indextuple.c
src/backend/access/gin/ginutil.c
src/backend/access/gist/gist.c
src/backend/access/hash/hash.c
src/backend/access/index/genam.c
src/backend/access/nbtree/nbtinsert.c
src/backend/access/nbtree/nbtpage.c
src/backend/access/nbtree/nbtree.c
src/backend/access/nbtree/nbtsearch.c
src/backend/access/nbtree/nbtsort.c
src/backend/access/nbtree/nbtutils.c
src/backend/access/spgist/spgutils.c
src/backend/bootstrap/bootparse.y
src/backend/bootstrap/bootstrap.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/indexing.c
src/backend/catalog/pg_constraint.c
src/backend/catalog/toasting.c
src/backend/commands/indexcmds.c
src/backend/commands/matview.c
src/backend/commands/tablecmds.c
src/backend/commands/trigger.c
src/backend/commands/typecmds.c
src/backend/executor/execIndexing.c
src/backend/executor/nodeIndexscan.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/path/pathkeys.c
src/backend/optimizer/util/plancat.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/parse_relation.c
src/backend/parser/parse_target.c
src/backend/parser/parse_utilcmd.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/adt/selfuncs.c
src/backend/utils/cache/relcache.c
src/backend/utils/sort/tuplesort.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/include/access/amapi.h
src/include/access/itup.h
src/include/access/nbtree.h
src/include/catalog/catversion.h
src/include/catalog/pg_constraint.h
src/include/catalog/pg_constraint_fn.h
src/include/catalog/pg_index.h
src/include/nodes/execnodes.h
src/include/nodes/parsenodes.h
src/include/nodes/relation.h
src/include/utils/rel.h
src/test/regress/expected/create_index.out
src/test/regress/expected/index_including.out [deleted file]
src/test/regress/parallel_schedule
src/test/regress/serial_schedule
src/test/regress/sql/create_index.sql
src/test/regress/sql/index_including.sql [deleted file]

index 891325d9d3d21d869eeeb7be745469810a4f8e7e..9c8e3083584ac93ae50078d4e137f20c58942b81 100644 (file)
@@ -100,7 +100,7 @@ static remoteConn *getConnectionByName(const char *name);
 static HTAB *createConnHash(void);
 static void createNewConnection(const char *name, remoteConn *rconn);
 static void deleteConnection(const char *name);
-static char **get_pkey_attnames(Relation rel, int16 *indnkeyatts);
+static char **get_pkey_attnames(Relation rel, int16 *numatts);
 static char **get_text_array_contents(ArrayType *array, int *numitems);
 static char *get_sql_insert(Relation rel, int *pkattnums, int pknumatts, char **src_pkattvals, char **tgt_pkattvals);
 static char *get_sql_delete(Relation rel, int *pkattnums, int pknumatts, char **tgt_pkattvals);
@@ -1485,7 +1485,7 @@ PG_FUNCTION_INFO_V1(dblink_get_pkey);
 Datum
 dblink_get_pkey(PG_FUNCTION_ARGS)
 {
-       int16           indnkeyatts;
+       int16           numatts;
        char      **results;
        FuncCallContext *funcctx;
        int32           call_cntr;
@@ -1511,7 +1511,7 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
                rel = get_rel_from_relname(PG_GETARG_TEXT_P(0), AccessShareLock, ACL_SELECT);
 
                /* get the array of attnums */
-               results = get_pkey_attnames(rel, &indnkeyatts);
+               results = get_pkey_attnames(rel, &numatts);
 
                relation_close(rel, AccessShareLock);
 
@@ -1531,9 +1531,9 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
                attinmeta = TupleDescGetAttInMetadata(tupdesc);
                funcctx->attinmeta = attinmeta;
 
-               if ((results != NULL) && (indnkeyatts > 0))
+               if ((results != NULL) && (numatts > 0))
                {
-                       funcctx->max_calls = indnkeyatts;
+                       funcctx->max_calls = numatts;
 
                        /* got results, keep track of them */
                        funcctx->user_fctx = results;
@@ -2023,10 +2023,10 @@ dblink_fdw_validator(PG_FUNCTION_ARGS)
  * get_pkey_attnames
  *
  * Get the primary key attnames for the given relation.
- * Return NULL, and set indnkeyatts = 0, if no primary key exists.
+ * Return NULL, and set numatts = 0, if no primary key exists.
  */
 static char **
-get_pkey_attnames(Relation rel, int16 *indnkeyatts)
+get_pkey_attnames(Relation rel, int16 *numatts)
 {
        Relation        indexRelation;
        ScanKeyData skey;
@@ -2036,8 +2036,8 @@ get_pkey_attnames(Relation rel, int16 *indnkeyatts)
        char      **result = NULL;
        TupleDesc       tupdesc;
 
-       /* initialize indnkeyatts to 0 in case no primary key exists */
-       *indnkeyatts = 0;
+       /* initialize numatts to 0 in case no primary key exists */
+       *numatts = 0;
 
        tupdesc = rel->rd_att;
 
@@ -2058,12 +2058,12 @@ get_pkey_attnames(Relation rel, int16 *indnkeyatts)
                /* we're only interested if it is the primary key */
                if (index->indisprimary)
                {
-                       *indnkeyatts = index->indnkeyatts;
-                       if (*indnkeyatts > 0)
+                       *numatts = index->indnatts;
+                       if (*numatts > 0)
                        {
-                               result = (char **) palloc(*indnkeyatts * sizeof(char *));
+                               result = (char **) palloc(*numatts * sizeof(char *));
 
-                               for (i = 0; i < *indnkeyatts; i++)
+                               for (i = 0; i < *numatts; i++)
                                        result[i] = SPI_fname(tupdesc, index->indkey.values[i]);
                        }
                        break;
index 142730a3214cc99fee9487c6eb65c0f3ef0fdb84..7352b292b98d21a76a39412d0117acc9a5b2b6dc 100644 (file)
@@ -138,9 +138,9 @@ triggered_change_notification(PG_FUNCTION_ARGS)
                /* we're only interested if it is the primary key and valid */
                if (index->indisprimary && IndexIsValid(index))
                {
-                       int                     indnkeyatts = index->indnkeyatts;
+                       int                     numatts = index->indnatts;
 
-                       if (indnkeyatts > 0)
+                       if (numatts > 0)
                        {
                                int                     i;
 
@@ -150,7 +150,7 @@ triggered_change_notification(PG_FUNCTION_ARGS)
                                appendStringInfoCharMacro(payload, ',');
                                appendStringInfoCharMacro(payload, operation);
 
-                               for (i = 0; i < indnkeyatts; i++)
+                               for (i = 0; i < numatts; i++)
                                {
                                        int                     colno = index->indkey.values[i];
 
index 342d5ecb037893e046af780a1b54cad4f56ab07f..d6b60db074478b20bd0c0fb3f6ddb57469f88b2a 100644 (file)
       <literal>pg_class.relnatts</literal>)</entry>
      </row>
 
-      <row>
-      <entry><structfield>indnkeyatts</structfield></entry>
-      <entry><type>int2</type></entry>
-      <entry></entry>
-      <entry>The number of key columns in the index. "Key columns" are ordinary
-      index columns in contrast with "included" columns.</entry>
-     </row>
-
      <row>
       <entry><structfield>indisunique</structfield></entry>
       <entry><type>bool</type></entry>
index 340904142e4bb64728b8597db676b97df16a53c3..b36889b856b275cd70d7b86204b824351c4e48a5 100644 (file)
@@ -117,8 +117,6 @@ typedef struct IndexAmRoutine
     bool        amclusterable;
     /* does AM handle predicate locks? */
     bool        ampredlocks;
-    /* does AM support columns included with clause INCLUDING? */
-    bool    amcaninclude;
     /* type of data stored in index, or InvalidOid if variable */
     Oid         amkeytype;
 
@@ -860,8 +858,7 @@ amrestrpos (IndexScanDesc scan);
    using <firstterm>unique indexes</>, which are indexes that disallow
    multiple entries with identical keys.  An access method that supports this
    feature sets <structfield>amcanunique</> true.
-   (At present, only B-tree supports it.) Columns which are present in the
-   <literal>INCLUDING</> clause are not used to enforce uniqueness.
+   (At present, only b-tree supports it.)
   </para>
 
   <para>
index 7c4fdc0403fc67da4533a30192b8d22e04cc7347..5f72e7d07359c7035963ae5121bd5bf7e7c8f30b 100644 (file)
@@ -643,8 +643,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
    Indexes can also be used to enforce uniqueness of a column's value,
    or the uniqueness of the combined values of more than one column.
 <synopsis>
-CREATE UNIQUE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> (<replaceable>column</replaceable> <optional>, ...</optional>)
-<optional>INCLUDING (<replaceable>column</replaceable> <optional>, ...</optional>)</optional>;
+CREATE UNIQUE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> (<replaceable>column</replaceable> <optional>, ...</optional>);
 </synopsis>
    Currently, only B-tree indexes can be declared unique.
   </para>
@@ -653,9 +652,7 @@ CREATE UNIQUE INDEX <replaceable>name</replaceable> ON <replaceable>table</repla
    When an index is declared unique, multiple table rows with equal
    indexed values are not allowed.  Null values are not considered
    equal.  A multicolumn unique index will only reject cases where all
-   indexed columns are equal in multiple rows. Columns included with clause
-   <literal>INCLUDING</literal> aren't used to enforce constraints (UNIQUE,
-   PRIMARY KEY, etc).
+   indexed columns are equal in multiple rows.
   </para>
 
   <para>
index 25b3c26f551195c387935939b12c7143325bbdeb..7dee4055dbc0bbcc468891bc54d269c212aa0621 100644 (file)
@@ -23,7 +23,6 @@ PostgreSQL documentation
 <synopsis>
 CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> ] ON <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
     ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
-    [ INCLUDING ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
     [ WITH ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ]
     [ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
     [ WHERE <replaceable class="parameter">predicate</replaceable> ]
@@ -139,35 +138,6 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class=
       </listitem>
      </varlistentry>
 
-     <varlistentry>
-      <term><literal>INCLUDING</literal></term>
-      <listitem>
-       <para>
-        An optional <literal>INCLUDING</> clause allows a list of columns to be
-        specified which will be included in the index, in the non-key portion of
-        the index. Columns which are part of this clause cannot also exist in
-        the key columns portion of the index, and vice versa. The
-        <literal>INCLUDING</> columns exist solely to allow more queries to
-        benefit from <firstterm>index-only scans</> by including certain
-        columns in the index, the value of which would otherwise have to be
-        obtained by reading
-        the table's heap. Having these columns in the <literal>INCLUDING</>
-        clause in some cases allows <productname>PostgreSQL</> to skip the heap
-        read completely. This also allows <literal>UNIQUE</> indexes to be
-        defined on one set of columns, which can include another set of column
-        in the <literal>INCLUDING</> clause, on which the uniqueness is not
-        enforced upon.  It's the same with other constraints (PRIMARY KEY and
-        EXCLUDE). This can also can be used for non-unique indexes as any
-        columns which are not required for the searching or ordering of records
-        can be included in the <literal>INCLUDING</> clause, which can slightly
-        reduce the size of the index, due to storing included attributes only
-        in leaf index pages. Currently, only the B-tree access method supports
-        this feature.  Expressions as included columns are not supported since
-        they cannot be used in index-only scan.
-       </para>
-      </listitem>
-     </varlistentry>
-
      <varlistentry>
       <term><replaceable class="parameter">name</replaceable></term>
       <listitem>
@@ -629,22 +599,13 @@ Indexes:
   <title>Examples</title>
 
   <para>
-   To create a unique B-tree index on the column <literal>title</literal> in
+   To create a B-tree index on the column <literal>title</literal> in
    the table <literal>films</literal>:
 <programlisting>
 CREATE UNIQUE INDEX title_idx ON films (title);
 </programlisting>
   </para>
 
-  <para>
-   To create a unique B-tree index on the column <literal>title</literal>
-   and included columns <literal>director</literal> and <literal>rating</literal>
-   in the table <literal>films</literal>:
-<programlisting>
-CREATE UNIQUE INDEX title_idx ON films (title) INCLUDING (director, rating);
-</programlisting>
-  </para>
-
   <para>
    To create an index on the expression <literal>lower(title)</>,
    allowing efficient case-insensitive searches:
index 473023e88e4eaf7a800c72695812066709cf76ac..d1807ed0dbfe7b24b87721f270dd1a153691ce0b 100644 (file)
@@ -59,8 +59,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
 
 [ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
 { CHECK ( <replaceable class="PARAMETER">expression</replaceable> ) [ NO INHERIT ] |
-  UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> <optional>INCLUDING (<replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional> |
-  PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> <optional>INCLUDING (<replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional> |
+  UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> |
+  PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> |
   EXCLUDE [ USING <replaceable class="parameter">index_method</replaceable> ] ( <replaceable class="parameter">exclude_element</replaceable> WITH <replaceable class="parameter">operator</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> [ WHERE ( <replaceable class="parameter">predicate</replaceable> ) ] |
   FOREIGN KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) REFERENCES <replaceable class="PARAMETER">reftable</replaceable> [ ( <replaceable class="PARAMETER">refcolumn</replaceable> [, ... ] ) ]
     [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ] }
@@ -476,8 +476,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
 
    <varlistentry>
     <term><literal>UNIQUE</> (column constraint)</term>
-    <term><literal>UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )
-    <optional>INCLUDING ( <replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional></> (table constraint)</term>
+    <term><literal>UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )</> (table constraint)</term>
+
     <listitem>
      <para>
       The <literal>UNIQUE</literal> constraint specifies that a
@@ -498,26 +498,12 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
       primary key constraint defined for the table.  (Otherwise it
       would just be the same constraint listed twice.)
      </para>
-
-     <para>
-      Adding a unique constraint will automatically create a unique btree
-      index on the column or group of columns used in the constraint.
-      Optional clause <literal>INCLUDING</literal> allows to add into the index
-      a portion of columns on which the uniqueness is not enforced upon.
-      Note, that althogh constraint is not enforced upon included columns, it still
-      depends on them. Consequently, some operations on these columns (e.g. <literal>DROP COLUMN</literal>)
-      can cause cascade constraint and index deletion.
-      See paragraph about <literal>INCLUDING</literal> in
-      <xref linkend="SQL-CREATEINDEX"> for more information.
-     </para>
-
     </listitem>
    </varlistentry>
 
    <varlistentry>
     <term><literal>PRIMARY KEY</> (column constraint)</term>
-    <term><literal>PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )
-    <optional>INCLUDING ( <replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional></> (table constraint)</term>
+    <term><literal>PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )</> (table constraint)</term>
     <listitem>
      <para>
       The <literal>PRIMARY KEY</> constraint specifies that a column or
@@ -540,18 +526,6 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
       about the design of the schema, since a primary key implies that other
       tables can rely on this set of columns as a unique identifier for rows.
      </para>
-
-     <para>
-      Adding a <literal>PRIMARY KEY</literal> constraint will automatically create a unique btree
-      index on the column or group of columns used in the constraint.
-      Optional clause <literal>INCLUDING</literal> allows to add into the index
-      a portion of columns on which the constraint is not enforced upon.
-      Note, that althogh constraint is not enforced upon included columns, it still
-      depends on them. Consequently, some operations on these columns (e.g. <literal>DROP COLUMN</literal>)
-      can cause cascade constraint and index deletion.
-      See paragraph about <literal>INCLUDING</literal> in
-      <xref linkend="SQL-CREATEINDEX"> for more information.
-     </para>
     </listitem>
    </varlistentry>
 
index c68df18ed324b333dba15b8de1648eccbee02e66..c7409529234c4c2c7f8236c230c433f54309ff7f 100644 (file)
@@ -92,7 +92,6 @@ brinhandler(PG_FUNCTION_ARGS)
        amroutine->amstorage = true;
        amroutine->amclusterable = false;
        amroutine->ampredlocks = false;
-       amroutine->amcaninclude = false;
        amroutine->amkeytype = InvalidOid;
 
        amroutine->ambuild = brinbuild;
index 8884c1e56c43d59a0d28da719d492d70c9cff1a9..274a6c2e7023e2e6afb8352442b6c6c2fcfc298c 100644 (file)
@@ -19,7 +19,6 @@
 #include "access/heapam.h"
 #include "access/itup.h"
 #include "access/tuptoaster.h"
-#include "utils/rel.h"
 
 
 /* ----------------------------------------------------------------
@@ -442,33 +441,3 @@ CopyIndexTuple(IndexTuple source)
        memcpy(result, source, size);
        return result;
 }
-
-/*
- * Reform index tuple. Truncate nonkey (INCLUDING) attributes.
- */
-IndexTuple
-index_truncate_tuple(Relation idxrel, IndexTuple olditup)
-{
-       TupleDesc   itupdesc = RelationGetDescr(idxrel);
-       Datum       values[INDEX_MAX_KEYS];
-       bool        isnull[INDEX_MAX_KEYS];
-       IndexTuple      newitup;
-       int indnatts = IndexRelationGetNumberOfAttributes(idxrel);
-       int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(idxrel);
-
-       Assert(indnatts <= INDEX_MAX_KEYS);
-       Assert(indnkeyatts > 0);
-       Assert(indnkeyatts < indnatts);
-
-       index_deform_tuple(olditup, itupdesc, values, isnull);
-
-       /* form new tuple that will contain only key attributes */
-       itupdesc->natts = indnkeyatts;
-       newitup = index_form_tuple(itupdesc, values, isnull);
-       newitup->t_tid = olditup->t_tid;
-
-       itupdesc->natts = indnatts;
-
-       Assert(IndexTupleSize(newitup) <= IndexTupleSize(olditup));
-       return newitup;
-}
index b4c69e7bfe7c0e4ce1eb33079acf196082ae14ae..94502678abb7210bce3eb75698e1bf4f5165950a 100644 (file)
@@ -47,7 +47,6 @@ ginhandler(PG_FUNCTION_ARGS)
        amroutine->amstorage = true;
        amroutine->amclusterable = false;
        amroutine->ampredlocks = false;
-       amroutine->amcaninclude = false;
        amroutine->amkeytype = InvalidOid;
 
        amroutine->ambuild = ginbuild;
index 64cc8df5d30c37d760eb0f32457a255782c65ca9..996363c2ded5386673b55c5bbc8e5bbc209a129a 100644 (file)
@@ -69,7 +69,6 @@ gisthandler(PG_FUNCTION_ARGS)
        amroutine->amstorage = true;
        amroutine->amclusterable = true;
        amroutine->ampredlocks = false;
-       amroutine->amcaninclude = false;
        amroutine->amkeytype = InvalidOid;
 
        amroutine->ambuild = gistbuild;
index 6d8d68d4a37ff4e384c0a36da4b41917fcba9173..3d48c4f0310a82ca1bc5db95c17a9f96eeac9b3b 100644 (file)
@@ -64,7 +64,6 @@ hashhandler(PG_FUNCTION_ARGS)
        amroutine->amstorage = false;
        amroutine->amclusterable = false;
        amroutine->ampredlocks = false;
-       amroutine->amcaninclude = false;
        amroutine->amkeytype = INT4OID;
 
        amroutine->ambuild = hashbuild;
index de5781458e3e4213349bca597a98098f529ee95d..65c941d812c53c4c2f7ad249510c0e0ca41cd6e6 100644 (file)
@@ -174,15 +174,13 @@ BuildIndexValueDescription(Relation indexRelation,
        StringInfoData buf;
        Form_pg_index idxrec;
        HeapTuple       ht_idx;
-       int                     indnkeyatts;
+       int                     natts = indexRelation->rd_rel->relnatts;
        int                     i;
        int                     keyno;
        Oid                     indexrelid = RelationGetRelid(indexRelation);
        Oid                     indrelid;
        AclResult       aclresult;
 
-       indnkeyatts = IndexRelationGetNumberOfKeyAttributes(indexRelation);
-
        /*
         * Check permissions- if the user does not have access to view all of the
         * key columns then return NULL to avoid leaking data.
@@ -220,7 +218,7 @@ BuildIndexValueDescription(Relation indexRelation,
                 * No table-level access, so step through the columns in the index and
                 * make sure the user has SELECT rights on all of them.
                 */
-               for (keyno = 0; keyno < idxrec->indnkeyatts; keyno++)
+               for (keyno = 0; keyno < idxrec->indnatts; keyno++)
                {
                        AttrNumber      attnum = idxrec->indkey.values[keyno];
 
@@ -246,7 +244,7 @@ BuildIndexValueDescription(Relation indexRelation,
        appendStringInfo(&buf, "(%s)=(",
                                         pg_get_indexdef_columns(indexrelid, true));
 
-       for (i = 0; i < indnkeyatts; i++)
+       for (i = 0; i < natts; i++)
        {
                char       *val;
 
@@ -364,7 +362,7 @@ systable_beginscan(Relation heapRelation,
                {
                        int                     j;
 
-                       for (j = 0; j < IndexRelationGetNumberOfAttributes(irel); j++)
+                       for (j = 0; j < irel->rd_index->indnatts; j++)
                        {
                                if (key[i].sk_attno == irel->rd_index->indkey.values[j])
                                {
@@ -372,7 +370,7 @@ systable_beginscan(Relation heapRelation,
                                        break;
                                }
                        }
-                       if (j == IndexRelationGetNumberOfAttributes(irel))
+                       if (j == irel->rd_index->indnatts)
                                elog(ERROR, "column is not in index");
                }
 
@@ -566,7 +564,7 @@ systable_beginscan_ordered(Relation heapRelation,
        {
                int                     j;
 
-               for (j = 0; j < IndexRelationGetNumberOfAttributes(indexRelation); j++)
+               for (j = 0; j < indexRelation->rd_index->indnatts; j++)
                {
                        if (key[i].sk_attno == indexRelation->rd_index->indkey.values[j])
                        {
@@ -574,7 +572,7 @@ systable_beginscan_ordered(Relation heapRelation,
                                break;
                        }
                }
-               if (j == IndexRelationGetNumberOfAttributes(indexRelation))
+               if (j == indexRelation->rd_index->indnatts)
                        elog(ERROR, "column is not in index");
        }
 
index 6ef820f682347f2964aad81254e19e35d5534112..3e100aabec74035d8a7f54591ab88cf4ee4f5e9d 100644 (file)
@@ -78,6 +78,8 @@ static OffsetNumber _bt_findsplitloc(Relation rel, Page page,
 static void _bt_checksplitloc(FindSplitData *state,
                                  OffsetNumber firstoldonright, bool newitemonleft,
                                  int dataitemstoleft, Size firstoldonrightsz);
+static bool _bt_pgaddtup(Page page, Size itemsize, IndexTuple itup,
+                        OffsetNumber itup_off);
 static bool _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
                        int keysz, ScanKey scankey);
 static void _bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel);
@@ -106,22 +108,18 @@ _bt_doinsert(Relation rel, IndexTuple itup,
                         IndexUniqueCheck checkUnique, Relation heapRel)
 {
        bool            is_unique = false;
-       int                     indnkeyatts;
+       int                     natts = rel->rd_rel->relnatts;
        ScanKey         itup_scankey;
        BTStack         stack;
        Buffer          buf;
        OffsetNumber offset;
 
-       Assert(IndexRelationGetNumberOfAttributes(rel) != 0);
-       indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
-       Assert(indnkeyatts != 0);
-
        /* we need an insertion scan key to do our search, so build one */
        itup_scankey = _bt_mkscankey(rel, itup);
 
 top:
        /* find the first page containing this key */
-       stack = _bt_search(rel, indnkeyatts, itup_scankey, false, &buf, BT_WRITE);
+       stack = _bt_search(rel, natts, itup_scankey, false, &buf, BT_WRITE);
 
        offset = InvalidOffsetNumber;
 
@@ -136,7 +134,7 @@ top:
         * move right in the tree.  See Lehman and Yao for an excruciatingly
         * precise description.
         */
-       buf = _bt_moveright(rel, buf, indnkeyatts, itup_scankey, false,
+       buf = _bt_moveright(rel, buf, natts, itup_scankey, false,
                                                true, stack, BT_WRITE);
 
        /*
@@ -165,7 +163,7 @@ top:
                TransactionId xwait;
                uint32          speculativeToken;
 
-               offset = _bt_binsrch(rel, buf, indnkeyatts, itup_scankey, false);
+               offset = _bt_binsrch(rel, buf, natts, itup_scankey, false);
                xwait = _bt_check_unique(rel, itup, heapRel, buf, offset, itup_scankey,
                                                                 checkUnique, &is_unique, &speculativeToken);
 
@@ -201,7 +199,7 @@ top:
                 */
                CheckForSerializableConflictIn(rel, NULL, buf);
                /* do the insertion */
-               _bt_findinsertloc(rel, &buf, &offset, indnkeyatts, itup_scankey, itup,
+               _bt_findinsertloc(rel, &buf, &offset, natts, itup_scankey, itup,
                                                  stack, heapRel);
                _bt_insertonpg(rel, buf, InvalidBuffer, stack, itup, offset, false);
        }
@@ -244,7 +242,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
                                 uint32 *speculativeToken)
 {
        TupleDesc       itupdesc = RelationGetDescr(rel);
-       int                     indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
+       int                     natts = rel->rd_rel->relnatts;
        SnapshotData SnapshotDirty;
        OffsetNumber maxoff;
        Page            page;
@@ -303,7 +301,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
                                 * in real comparison, but only for ordering/finding items on
                                 * pages. - vadim 03/24/97
                                 */
-                               if (!_bt_isequal(itupdesc, page, offset, indnkeyatts, itup_scankey))
+                               if (!_bt_isequal(itupdesc, page, offset, natts, itup_scankey))
                                        break;          /* we're past all the equal tuples */
 
                                /* okay, we gotta fetch the heap tuple ... */
@@ -467,7 +465,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
                        if (P_RIGHTMOST(opaque))
                                break;
                        if (!_bt_isequal(itupdesc, page, P_HIKEY,
-                                                        indnkeyatts, itup_scankey))
+                                                        natts, itup_scankey))
                                break;
                        /* Advance to next non-dead page --- there must be one */
                        for (;;)
@@ -982,9 +980,6 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright,
        OffsetNumber i;
        bool            isroot;
        bool            isleaf;
-       IndexTuple lefthikey;
-       int indnatts = IndexRelationGetNumberOfAttributes(rel);
-       int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
 
        /* Acquire a new page to split into */
        rbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
@@ -1085,22 +1080,7 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright,
                itemsz = ItemIdGetLength(itemid);
                item = (IndexTuple) PageGetItem(origpage, itemid);
        }
-
-       /*
-        * We must truncate the "high key" item, before insert it onto the leaf page.
-        * It's the only point in insertion process, where we perform truncation.
-        * All other functions work with this high key and do not change it.
-        */
-       if (indnatts != indnkeyatts && P_ISLEAF(lopaque))
-       {
-               lefthikey = index_truncate_tuple(rel, item);
-               itemsz = IndexTupleSize(lefthikey);
-               itemsz = MAXALIGN(itemsz);
-       }
-       else
-               lefthikey = item;
-
-       if (PageAddItem(leftpage, (Item) lefthikey, itemsz, leftoff,
+       if (PageAddItem(leftpage, (Item) item, itemsz, leftoff,
                                        false, false) == InvalidOffsetNumber)
        {
                memset(rightpage, 0, BufferGetPageSize(rbuf));
@@ -1989,7 +1969,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
        itemid = PageGetItemId(lpage, P_HIKEY);
        right_item_sz = ItemIdGetLength(itemid);
        item = (IndexTuple) PageGetItem(lpage, itemid);
-
        right_item = CopyIndexTuple(item);
        ItemPointerSet(&(right_item->t_tid), rbkno, P_HIKEY);
 
@@ -2107,7 +2086,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
  *             we insert the tuples in order, so that the given itup_off does
  *             represent the final position of the tuple!
  */
-bool
+static bool
 _bt_pgaddtup(Page page,
                         Size itemsize,
                         IndexTuple itup,
index 6d64a8b65b5c76802fd56a0d85a97fa0d201d13d..67755d75acb10e69a4d904ee910aa0525f14fec9 100644 (file)
@@ -1254,9 +1254,8 @@ _bt_pagedel(Relation rel, Buffer buf)
                                /* we need an insertion scan key for the search, so build one */
                                itup_scankey = _bt_mkscankey(rel, targetkey);
                                /* find the leftmost leaf page containing this key */
-                               stack = _bt_search(rel,
-                                                                  IndexRelationGetNumberOfKeyAttributes(rel),
-                                                                  itup_scankey, false, &lbuf, BT_READ);
+                               stack = _bt_search(rel, rel->rd_rel->relnatts, itup_scankey,
+                                                                  false, &lbuf, BT_READ);
                                /* don't need a pin on the page */
                                _bt_relbuf(rel, lbuf);
 
index 39d46644993c72a5539eb86adec64418798cf25b..bf8ade375d187d3809a452d410ed0b3830492469 100644 (file)
@@ -97,7 +97,6 @@ bthandler(PG_FUNCTION_ARGS)
        amroutine->amstorage = false;
        amroutine->amclusterable = true;
        amroutine->ampredlocks = true;
-       amroutine->amcaninclude = true;
        amroutine->amkeytype = InvalidOid;
 
        amroutine->ambuild = btbuild;
index 5b1adeea41938d87fbb67d565170828353fb9a5f..14dffe07db6940169f5db029f9450ad214804815 100644 (file)
@@ -431,8 +431,6 @@ _bt_compare(Relation rel,
 
        itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
 
-       Assert (keysz <= rel->rd_index->indnkeyatts);
-
        /*
         * The scan key is set up with the attribute number associated with each
         * term in the key.  It is important that, if the index is multi-key, the
index 8a2d7742294ae2a4d92fbed6567546282c76252d..99a014e8f47c77268c63e1ef7a4a1a01805d4729 100644 (file)
@@ -456,9 +456,6 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
        OffsetNumber last_off;
        Size            pgspc;
        Size            itupsz;
-       BTPageOpaque pageop;
-       int indnatts = IndexRelationGetNumberOfAttributes(wstate->index);
-       int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(wstate->index);
 
        /*
         * This is a handy place to check for cancel interrupts during the btree
@@ -513,8 +510,6 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
                ItemId          ii;
                ItemId          hii;
                IndexTuple      oitup;
-               IndexTuple      keytup;
-               BTPageOpaque opageop = (BTPageOpaque) PageGetSpecialPointer(opage);
 
                /* Create new page of same level */
                npage = _bt_blnewpage(state->btps_level);
@@ -542,28 +537,6 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
                ItemIdSetUnused(ii);    /* redundant */
                ((PageHeader) opage)->pd_lower -= sizeof(ItemIdData);
 
-               if (indnkeyatts != indnatts && P_ISLEAF(opageop))
-               {
-                       /*
-                        * It's essential to truncate High key here.
-                        * The purpose is not just to save more space on this particular page,
-                        * but to keep whole b-tree structure consistent. Subsequent insertions
-                        * assume that hikey is already truncated, and so they should not
-                        * worry about it, when copying the high key into the parent page
-                        * as a downlink.
-                        * NOTE It is not crutial for reliability in present,
-                        * but maybe it will be that in the future.
-                        */
-                       keytup = index_truncate_tuple(wstate->index, oitup);
-
-                       /*  delete "wrong" high key, insert keytup as P_HIKEY. */
-                       PageIndexTupleDelete(opage, P_HIKEY);
-
-                       if (!_bt_pgaddtup(opage, IndexTupleSize(keytup), keytup, P_HIKEY))
-                               elog(ERROR, "failed to rewrite compressed item in index \"%s\"",
-                                       RelationGetRelationName(wstate->index));
-               }
-
                /*
                 * Link the old page into its parent, using its minimum key. If we
                 * don't have a parent, we have to create one; this adds a new btree
@@ -581,15 +554,8 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
                 * Save a copy of the minimum key for the new page.  We have to copy
                 * it off the old page, not the new one, in case we are not at leaf
                 * level.
-                * If tuple contains non-key attributes, truncate them.
-                * We perform truncation only for leaf pages,
-                * beacuse all tuples at inner pages will be already
-                * truncated by the time we handle them.
                 */
-               if (indnkeyatts != indnatts && P_ISLEAF(opageop))
-                       state->btps_minkey = index_truncate_tuple(wstate->index, oitup);
-               else
-                       state->btps_minkey = CopyIndexTuple(oitup);
+               state->btps_minkey = CopyIndexTuple(oitup);
 
                /*
                 * Set the sibling links for both pages.
@@ -615,7 +581,6 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
                last_off = P_FIRSTKEY;
        }
 
-       pageop = (BTPageOpaque) PageGetSpecialPointer(npage);
        /*
         * If the new item is the first for its page, stash a copy for later. Note
         * this will only happen for the first item on a level; on later pages,
@@ -625,14 +590,7 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
        if (last_off == P_HIKEY)
        {
                Assert(state->btps_minkey == NULL);
-               /*
-                * Truncate the tuple that we're going to insert
-                * into the parent page as a downlink
-                */
-               if (indnkeyatts != indnatts && P_ISLEAF(pageop))
-                       state->btps_minkey = index_truncate_tuple(wstate->index, itup);
-               else
-                       state->btps_minkey = CopyIndexTuple(itup);
+               state->btps_minkey = CopyIndexTuple(itup);
        }
 
        /*
@@ -727,7 +685,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
                                load1;
        TupleDesc       tupdes = RelationGetDescr(wstate->index);
        int                     i,
-                               keysz = IndexRelationGetNumberOfKeyAttributes(wstate->index);
+                               keysz = RelationGetNumberOfAttributes(wstate->index);
        ScanKey         indexScanKey = NULL;
        SortSupport sortKeys;
 
index 8c5509f4a2c036a2f873cd8ffa67f35943aac84d..83c553ca279e2db0ef1590ed38409666b5e9e9e0 100644 (file)
@@ -63,26 +63,17 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
 {
        ScanKey         skey;
        TupleDesc       itupdesc;
-       int                     indnatts,
-                               indnkeyatts;
+       int                     natts;
        int16      *indoption;
        int                     i;
 
        itupdesc = RelationGetDescr(rel);
-       indnatts = IndexRelationGetNumberOfAttributes(rel);
-       indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
+       natts = RelationGetNumberOfAttributes(rel);
        indoption = rel->rd_indoption;
 
-       Assert(indnkeyatts != 0);
-       Assert(indnkeyatts <= indnatts);
+       skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
 
-       /*
-        * We'll execute search using ScanKey constructed on key columns.
-        * Non key (included) columns must be omitted.
-        */
-       skey = (ScanKey) palloc(indnkeyatts * sizeof(ScanKeyData));
-
-       for (i = 0; i < indnkeyatts; i++)
+       for (i = 0; i < natts; i++)
        {
                FmgrInfo   *procinfo;
                Datum           arg;
@@ -124,16 +115,16 @@ ScanKey
 _bt_mkscankey_nodata(Relation rel)
 {
        ScanKey         skey;
-       int                     indnkeyatts;
+       int                     natts;
        int16      *indoption;
        int                     i;
 
-       indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
+       natts = RelationGetNumberOfAttributes(rel);
        indoption = rel->rd_indoption;
 
-       skey = (ScanKey) palloc(indnkeyatts * sizeof(ScanKeyData));
+       skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
 
-       for (i = 0; i < indnkeyatts; i++)
+       for (i = 0; i < natts; i++)
        {
                FmgrInfo   *procinfo;
                int                     flags;
index befb47ab06c1e4d5acf193b4e2f396017dba801c..201203f91a306bda263e0c3d1f90947bf24df59e 100644 (file)
@@ -48,7 +48,6 @@ spghandler(PG_FUNCTION_ARGS)
        amroutine->amstorage = false;
        amroutine->amclusterable = false;
        amroutine->ampredlocks = false;
-       amroutine->amcaninclude = false;
        amroutine->amkeytype = InvalidOid;
 
        amroutine->ambuild = spgbuild;
index c47c387d75bdedc6855f6f08e286168d3c924369..41d2fd4a5f354250508cbeae6960dfd97c0870b9 100644 (file)
@@ -293,7 +293,6 @@ Boot_DeclareIndexStmt:
                                        stmt->accessMethod = $8;
                                        stmt->tableSpace = NULL;
                                        stmt->indexParams = $10;
-                                       stmt->indexIncludingParams = NIL;
                                        stmt->options = NIL;
                                        stmt->whereClause = NULL;
                                        stmt->excludeOpNames = NIL;
@@ -337,7 +336,6 @@ Boot_DeclareUniqueIndexStmt:
                                        stmt->accessMethod = $9;
                                        stmt->tableSpace = NULL;
                                        stmt->indexParams = $11;
-                                       stmt->indexIncludingParams = NIL;
                                        stmt->options = NIL;
                                        stmt->whereClause = NULL;
                                        stmt->excludeOpNames = NIL;
index 8939506081b979688f438913472f59a29be1f065..e518e178bb4b43958a929aa0b998f09d92f5a1b6 100644 (file)
@@ -593,7 +593,7 @@ boot_openrel(char *relname)
                 relname, (int) ATTRIBUTE_FIXED_PART_SIZE);
 
        boot_reldesc = heap_openrv(makeRangeVar(NULL, relname, -1), NoLock);
-       numattr = RelationGetNumberOfAttributes(boot_reldesc);
+       numattr = boot_reldesc->rd_rel->relnatts;
        for (i = 0; i < numattr; i++)
        {
                if (attrtypes[i] == NULL)
index 46c610923d70e12a2e450d14b2dc51f948ea498b..e997b574ca9eaf93514817464b3a77467d1a5371 100644 (file)
@@ -2043,8 +2043,7 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr,
                                                          is_validated,
                                                          RelationGetRelid(rel),        /* relation */
                                                          attNos,       /* attrs in the constraint */
-                                                         keycount, /* # key attrs in the constraint */
-                                                         keycount, /* # total attrs in the constraint */
+                                                         keycount, /* # attrs in the constraint */
                                                          InvalidOid,           /* not a domain constraint */
                                                          InvalidOid,           /* no associated index */
                                                          InvalidOid,           /* Foreign key fields */
index b00efecfc2975b70737b409899466cac95827d81..31a1438d4aa7aed20e71eb1fbba727b2c1266f99 100644 (file)
@@ -216,7 +216,7 @@ index_check_primary_key(Relation heapRel,
         * null, otherwise attempt to ALTER TABLE .. SET NOT NULL
         */
        cmds = NIL;
-       for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++)
+       for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
        {
                AttrNumber      attnum = indexInfo->ii_KeyAttrNumbers[i];
                HeapTuple       atttuple;
@@ -424,13 +424,6 @@ ConstructTupleDescriptor(Relation heapRelation,
                namestrcpy(&to->attname, (const char *) lfirst(colnames_item));
                colnames_item = lnext(colnames_item);
 
-               /*
-                * Code below is concerned to the opclasses which are not used
-                * with the included columns.
-                */
-               if (i >= indexInfo->ii_NumIndexKeyAttrs)
-                       continue;
-
                /*
                 * Check the opclass and index AM to see if either provides a keytype
                 * (overriding the attribute type).  Opclass takes precedence.
@@ -567,7 +560,7 @@ UpdateIndexRelation(Oid indexoid,
        for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
                indkey->values[i] = indexInfo->ii_KeyAttrNumbers[i];
        indcollation = buildoidvector(collationOids, indexInfo->ii_NumIndexAttrs);
-       indclass = buildoidvector(classOids, indexInfo->ii_NumIndexKeyAttrs);
+       indclass = buildoidvector(classOids, indexInfo->ii_NumIndexAttrs);
        indoption = buildint2vector(coloptions, indexInfo->ii_NumIndexAttrs);
 
        /*
@@ -612,7 +605,6 @@ UpdateIndexRelation(Oid indexoid,
        values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
        values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
        values[Anum_pg_index_indnatts - 1] = Int16GetDatum(indexInfo->ii_NumIndexAttrs);
-       values[Anum_pg_index_indnkeyatts - 1] = Int16GetDatum(indexInfo->ii_NumIndexKeyAttrs);
        values[Anum_pg_index_indisunique - 1] = BoolGetDatum(indexInfo->ii_Unique);
        values[Anum_pg_index_indisprimary - 1] = BoolGetDatum(primary);
        values[Anum_pg_index_indisexclusion - 1] = BoolGetDatum(isexclusion);
@@ -1018,7 +1010,7 @@ index_create(Relation heapRelation,
                }
 
                /* Store dependency on operator classes */
-               for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++)
+               for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
                {
                        referenced.classId = OperatorClassRelationId;
                        referenced.objectId = classObjectId[i];
@@ -1076,8 +1068,6 @@ index_create(Relation heapRelation,
        else
                Assert(indexRelation->rd_indexcxt != NULL);
 
-       indexRelation->rd_index->indnkeyatts = indexInfo->ii_NumIndexKeyAttrs;
-
        /*
         * If this is bootstrap (initdb) time, then we don't actually fill in the
         * index yet.  We'll be creating more indexes and classes later, so we
@@ -1198,7 +1188,6 @@ index_constraint_create(Relation heapRelation,
                                                                   true,
                                                                   RelationGetRelid(heapRelation),
                                                                   indexInfo->ii_KeyAttrNumbers,
-                                                                  indexInfo->ii_NumIndexKeyAttrs,
                                                                   indexInfo->ii_NumIndexAttrs,
                                                                   InvalidOid,  /* no domain */
                                                                   indexRelationId,             /* index OID */
@@ -1639,19 +1628,15 @@ BuildIndexInfo(Relation index)
        IndexInfo  *ii = makeNode(IndexInfo);
        Form_pg_index indexStruct = index->rd_index;
        int                     i;
-       int                     numAtts;
+       int                     numKeys;
 
        /* check the number of keys, and copy attr numbers into the IndexInfo */
-       numAtts = indexStruct->indnatts;
-       if (numAtts < 1 || numAtts > INDEX_MAX_KEYS)
+       numKeys = indexStruct->indnatts;
+       if (numKeys < 1 || numKeys > INDEX_MAX_KEYS)
                elog(ERROR, "invalid indnatts %d for index %u",
-                        numAtts, RelationGetRelid(index));
-       ii->ii_NumIndexAttrs = numAtts;
-       ii->ii_NumIndexKeyAttrs = indexStruct->indnkeyatts;
-       Assert(ii->ii_NumIndexKeyAttrs != 0);
-       Assert(ii->ii_NumIndexKeyAttrs <= ii->ii_NumIndexAttrs);
-
-       for (i = 0; i < numAtts; i++)
+                        numKeys, RelationGetRelid(index));
+       ii->ii_NumIndexAttrs = numKeys;
+       for (i = 0; i < numKeys; i++)
                ii->ii_KeyAttrNumbers[i] = indexStruct->indkey.values[i];
 
        /* fetch any expressions needed for expressional indexes */
@@ -1707,11 +1692,9 @@ BuildIndexInfo(Relation index)
 void
 BuildSpeculativeIndexInfo(Relation index, IndexInfo *ii)
 {
-       int                     indnkeyatts;
+       int                     ncols = index->rd_rel->relnatts;
        int                     i;
 
-       indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index);
-
        /*
         * fetch info for checking unique indexes
         */
@@ -1720,16 +1703,16 @@ BuildSpeculativeIndexInfo(Relation index, IndexInfo *ii)
        if (index->rd_rel->relam != BTREE_AM_OID)
                elog(ERROR, "unexpected non-btree speculative unique index");
 
-       ii->ii_UniqueOps = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
-       ii->ii_UniqueProcs = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
-       ii->ii_UniqueStrats = (uint16 *) palloc(sizeof(uint16) * indnkeyatts);
+       ii->ii_UniqueOps = (Oid *) palloc(sizeof(Oid) * ncols);
+       ii->ii_UniqueProcs = (Oid *) palloc(sizeof(Oid) * ncols);
+       ii->ii_UniqueStrats = (uint16 *) palloc(sizeof(uint16) * ncols);
 
        /*
         * We have to look up the operator's strategy number.  This provides a
         * cross-check that the operator does match the index.
         */
        /* We need the func OIDs and strategy numbers too */
-       for (i = 0; i < indnkeyatts; i++)
+       for (i = 0; i < ncols; i++)
        {
                ii->ii_UniqueStrats[i] = BTEqualStrategyNumber;
                ii->ii_UniqueOps[i] =
index 6096fa5d53394e973840fc0bed744076c609b9bf..b9fe10237bbb88b026bde171e56da3f695b3159f 100644 (file)
@@ -119,7 +119,6 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
                Assert(indexInfo->ii_Predicate == NIL);
                Assert(indexInfo->ii_ExclusionOps == NULL);
                Assert(relationDescs[i]->rd_index->indimmediate);
-               Assert(indexInfo->ii_NumIndexKeyAttrs != 0);
 
                /*
                 * FormIndexDatum fills in its values and isnull parameters with the
index fc0872a9b2d5cc3d5652637b5d3d0790a9091396..8fabe6899f65796e9c4495c6d27dd0ffdc93f7be 100644 (file)
@@ -55,7 +55,6 @@ CreateConstraintEntry(const char *constraintName,
                                          Oid relId,
                                          const int16 *constraintKey,
                                          int constraintNKeys,
-                                         int constraintNTotalKeys,
                                          Oid domainId,
                                          Oid indexRelId,
                                          Oid foreignRelId,
@@ -82,7 +81,6 @@ CreateConstraintEntry(const char *constraintName,
        bool            nulls[Natts_pg_constraint];
        Datum           values[Natts_pg_constraint];
        ArrayType  *conkeyArray;
-       ArrayType  *conincludingArray;
        ArrayType  *confkeyArray;
        ArrayType  *conpfeqopArray;
        ArrayType  *conppeqopArray;
@@ -113,21 +111,6 @@ CreateConstraintEntry(const char *constraintName,
        else
                conkeyArray = NULL;
 
-       if (constraintNTotalKeys > constraintNKeys)
-       {
-               Datum      *conincluding;
-               int j = 0;
-               int constraintNIncludedKeys = constraintNTotalKeys - constraintNKeys;
-
-               conincluding = (Datum *) palloc(constraintNIncludedKeys* sizeof(Datum));
-               for (i = constraintNKeys; i < constraintNTotalKeys; i++)
-                       conincluding[j++] = Int16GetDatum(constraintKey[i]);
-               conincludingArray = construct_array(conincluding, constraintNIncludedKeys,
-                                                                         INT2OID, 2, true, 's');
-       }
-       else
-               conincludingArray = NULL;
-
        if (foreignNKeys > 0)
        {
                Datum      *fkdatums;
@@ -200,11 +183,6 @@ CreateConstraintEntry(const char *constraintName,
        else
                nulls[Anum_pg_constraint_conkey - 1] = true;
 
-       if (conincludingArray)
-               values[Anum_pg_constraint_conincluding - 1] = PointerGetDatum(conincludingArray);
-       else
-               nulls[Anum_pg_constraint_conincluding - 1] = true;
-
        if (confkeyArray)
                values[Anum_pg_constraint_confkey - 1] = PointerGetDatum(confkeyArray);
        else
@@ -269,9 +247,9 @@ CreateConstraintEntry(const char *constraintName,
 
                relobject.classId = RelationRelationId;
                relobject.objectId = relId;
-               if (constraintNTotalKeys > 0)
+               if (constraintNKeys > 0)
                {
-                       for (i = 0; i < constraintNTotalKeys; i++)
+                       for (i = 0; i < constraintNKeys; i++)
                        {
                                relobject.objectSubId = constraintKey[i];
 
index e09c825fdc19a0a730d3219134094bf832fda617..f40a005f2254b284e13db07afd50e48465599285 100644 (file)
@@ -314,7 +314,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
 
        indexInfo = makeNode(IndexInfo);
        indexInfo->ii_NumIndexAttrs = 2;
-       indexInfo->ii_NumIndexKeyAttrs = 2;
        indexInfo->ii_KeyAttrNumbers[0] = 1;
        indexInfo->ii_KeyAttrNumbers[1] = 2;
        indexInfo->ii_Expressions = NIL;
index 7631cacf348dfec62aeaaec328bd9642b368414e..13b04e68f01dda3a8511ed8ba1556a84109550fa 100644 (file)
@@ -213,7 +213,7 @@ CheckIndexCompatible(Oid oldId,
        }
 
        /* Any change in operator class or collation breaks compatibility. */
-       old_natts = indexForm->indnkeyatts;
+       old_natts = indexForm->indnatts;
        Assert(old_natts == numberOfAttributes);
 
        d = SysCacheGetAttr(INDEXRELID, tuple, Anum_pg_index_indcollation, &isnull);
@@ -327,7 +327,6 @@ DefineIndex(Oid relationId,
        int16      *coloptions;
        IndexInfo  *indexInfo;
        int                     numberOfAttributes;
-       int                     numberOfKeyAttributes;
        TransactionId limitXmin;
        VirtualTransactionId *old_snapshots;
        ObjectAddress address;
@@ -338,27 +337,14 @@ DefineIndex(Oid relationId,
        Snapshot        snapshot;
        int                     i;
 
-       if(list_intersection(stmt->indexParams, stmt->indexIncludingParams) != NIL)
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                                errmsg("included columns must not intersect with key columns")));
-       /*
-        * count key attributes in index
-        */
-       numberOfKeyAttributes = list_length(stmt->indexParams);
-
        /*
-        * We append any INCLUDING columns onto the indexParams list so that
-        * we have one list with all columns. Later we can determine which of these
-        * are key columns, and which are just part of the INCLUDING list by check
-        * the list position. A list item in a position less than
-        * ii_NumIndexKeyAttrs is part of the key columns, and anything equal to
-        * and over is part of the INCLUDING columns.
+        * count attributes in index
         */
-       stmt->indexParams = list_concat(stmt->indexParams,
-                                                                       stmt->indexIncludingParams);
        numberOfAttributes = list_length(stmt->indexParams);
-
+       if (numberOfAttributes <= 0)
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                                errmsg("must specify at least one column")));
        if (numberOfAttributes > INDEX_MAX_KEYS)
                ereport(ERROR,
                                (errcode(ERRCODE_TOO_MANY_COLUMNS),
@@ -521,11 +507,6 @@ DefineIndex(Oid relationId,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                           errmsg("access method \"%s\" does not support unique indexes",
                                          accessMethodName)));
-       if (list_length(stmt->indexIncludingParams) > 0 && !amRoutine->amcaninclude)
-               ereport(ERROR,
-                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                               errmsg("access method \"%s\" does not support included columns",
-                                               accessMethodName)));
        if (numberOfAttributes > 1 && !amRoutine->amcanmulticol)
                ereport(ERROR,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -563,7 +544,6 @@ DefineIndex(Oid relationId,
         */
        indexInfo = makeNode(IndexInfo);
        indexInfo->ii_NumIndexAttrs = numberOfAttributes;
-       indexInfo->ii_NumIndexKeyAttrs = numberOfKeyAttributes;
        indexInfo->ii_Expressions = NIL;        /* for now */
        indexInfo->ii_ExpressionsState = NIL;
        indexInfo->ii_Predicate = make_ands_implicit((Expr *) stmt->whereClause);
@@ -579,7 +559,7 @@ DefineIndex(Oid relationId,
 
        typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
        collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
-       classObjectId = (Oid *) palloc(numberOfKeyAttributes * sizeof(Oid));
+       classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
        coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
        ComputeIndexAttrs(indexInfo,
                                          typeObjectId, collationObjectId, classObjectId,
@@ -986,15 +966,16 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
        ListCell   *nextExclOp;
        ListCell   *lc;
        int                     attn;
-       int             nkeycols = indexInfo->ii_NumIndexKeyAttrs;
 
        /* Allocate space for exclusion operator info, if needed */
        if (exclusionOpNames)
        {
-               Assert(list_length(exclusionOpNames) == nkeycols);
-               indexInfo->ii_ExclusionOps = (Oid *) palloc(sizeof(Oid) * nkeycols);
-               indexInfo->ii_ExclusionProcs = (Oid *) palloc(sizeof(Oid) * nkeycols);
-               indexInfo->ii_ExclusionStrats = (uint16 *) palloc(sizeof(uint16) * nkeycols);
+               int                     ncols = list_length(attList);
+
+               Assert(list_length(exclusionOpNames) == ncols);
+               indexInfo->ii_ExclusionOps = (Oid *) palloc(sizeof(Oid) * ncols);
+               indexInfo->ii_ExclusionProcs = (Oid *) palloc(sizeof(Oid) * ncols);
+               indexInfo->ii_ExclusionStrats = (uint16 *) palloc(sizeof(uint16) * ncols);
                nextExclOp = list_head(exclusionOpNames);
        }
        else
@@ -1047,11 +1028,6 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
                        Node       *expr = attribute->expr;
 
                        Assert(expr != NULL);
-
-                       if (attn >= nkeycols)
-                               ereport(ERROR,
-                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                               errmsg("expressions are not supported in included columns")));
                        atttype = exprType(expr);
                        attcollation = exprCollation(expr);
 
@@ -1129,16 +1105,6 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
 
                collationOidP[attn] = attcollation;
 
-               /*
-                * Skip opclass and ordering options for included columns.
-                */
-               if (attn >= nkeycols)
-               {
-                       colOptionP[attn] = 0;
-                       attn++;
-                       continue;
-               }
-
                /*
                 * Identify the opclass to use.
                 */
index 59d5aa44426cb012b31af6ec386c5d29177e04f3..f00aab39e7bd297e89a2cc1a23ceb93bdd9500c6 100644 (file)
@@ -612,7 +612,7 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
                                                                                  RelationGetRelationName(tempRel));
        diffname = make_temptable_name_n(tempname, 2);
 
-       relnatts = RelationGetNumberOfAttributes(matviewRel);
+       relnatts = matviewRel->rd_rel->relnatts;
        usedForQual = (bool *) palloc0(sizeof(bool) * relnatts);
 
        /* Open SPI context. */
@@ -698,11 +698,11 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
                        RelationGetIndexExpressions(indexRel) == NIL &&
                        RelationGetIndexPredicate(indexRel) == NIL)
                {
-                       int                     indnkeyatts = indexStruct->indnkeyatts;
+                       int                     numatts = indexStruct->indnatts;
                        int                     i;
 
                        /* Add quals for all columns from this index. */
-                       for (i = 0; i < indnkeyatts; i++)
+                       for (i = 0; i < numatts; i++)
                        {
                                int                     attnum = indexStruct->indkey.values[i];
                                Oid                     type;
index a9880e99171627d8e8072174188e51d85c0b8f46..96dc923bcdf493b3eca87218801bd411df54d872 100644 (file)
@@ -5234,7 +5234,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
                         * Loop over each attribute in the primary key and see if it
                         * matches the to-be-altered attribute
                         */
-                       for (i = 0; i < indexStruct->indnkeyatts; i++)
+                       for (i = 0; i < indexStruct->indnatts; i++)
                        {
                                if (indexStruct->indkey.values[i] == attnum)
                                        ereport(ERROR,
@@ -6576,7 +6576,6 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
                                                                          RelationGetRelid(rel),
                                                                          fkattnum,
                                                                          numfks,
-                                                                         numfks,
                                                                          InvalidOid,           /* not a domain
                                                                                                                 * constraint */
                                                                          indexOid,
@@ -7084,7 +7083,7 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
         * assume a primary key cannot have expressional elements)
         */
        *attnamelist = NIL;
-       for (i = 0; i < indexStruct->indnkeyatts; i++)
+       for (i = 0; i < indexStruct->indnatts; i++)
        {
                int                     pkattno = indexStruct->indkey.values[i];
 
@@ -7162,7 +7161,7 @@ transformFkeyCheckAttrs(Relation pkrel,
                 * partial index; forget it if there are any expressions, too. Invalid
                 * indexes are out as well.
                 */
-               if (indexStruct->indnkeyatts == numattrs &&
+               if (indexStruct->indnatts == numattrs &&
                        indexStruct->indisunique &&
                        IndexIsValid(indexStruct) &&
                        heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
@@ -11046,7 +11045,7 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode
                                                RelationGetRelationName(indexRel))));
 
        /* Check index for nullable columns. */
-       for (key = 0; key < IndexRelationGetNumberOfKeyAttributes(indexRel); key++)
+       for (key = 0; key < indexRel->rd_index->indnatts; key++)
        {
                int16           attno = indexRel->rd_index->indkey.values[key];
                Form_pg_attribute attr;
index 8fb3d76d1788e68c13dc8b96df3412f9389e5282..6f728ff0fc9cd70ca963c8b8783d5f9a032ca75f 100644 (file)
@@ -479,7 +479,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
                                                                                          RelationGetRelid(rel),
                                                                                          NULL,         /* no conkey */
                                                                                          0,
-                                                                                         0,
                                                                                          InvalidOid,           /* no domain */
                                                                                          InvalidOid,           /* no index */
                                                                                          InvalidOid,           /* no foreign key */
index 63d07174d7e9e90140bdc59cb78ad97956527655..71d4df9c7977bbf1b9820a6dacd628de97366068 100644 (file)
@@ -3078,7 +3078,6 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
                                                          InvalidOid,           /* not a relation constraint */
                                                          NULL,
                                                          0,
-                                                         0,
                                                          domainOid,            /* domain constraint */
                                                          InvalidOid,           /* no associated index */
                                                          InvalidOid,           /* Foreign key fields */
index ecd2723f0b60cc56c32a4d60f0be1ee3783757ff..5d553d51d213352af8cecac316e057f987d25205 100644 (file)
@@ -646,7 +646,7 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index,
        Oid                *constr_procs;
        uint16     *constr_strats;
        Oid                *index_collations = index->rd_indcollation;
-       int                     indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index);
+       int                     index_natts = index->rd_index->indnatts;
        IndexScanDesc index_scan;
        HeapTuple       tup;
        ScanKeyData scankeys[INDEX_MAX_KEYS];
@@ -673,7 +673,7 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index,
         * If any of the input values are NULL, the constraint check is assumed to
         * pass (i.e., we assume the operators are strict).
         */
-       for (i = 0; i < indnkeyatts; i++)
+       for (i = 0; i < index_natts; i++)
        {
                if (isnull[i])
                        return true;
@@ -685,7 +685,7 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index,
         */
        InitDirtySnapshot(DirtySnapshot);
 
-       for (i = 0; i < indnkeyatts; i++)
+       for (i = 0; i < index_natts; i++)
        {
                ScanKeyEntryInitialize(&scankeys[i],
                                                           0,
@@ -717,8 +717,8 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index,
 retry:
        conflict = false;
        found_self = false;
-       index_scan = index_beginscan(heap, index, &DirtySnapshot, indnkeyatts, 0);
-       index_rescan(index_scan, scankeys, indnkeyatts, NULL, 0);
+       index_scan = index_beginscan(heap, index, &DirtySnapshot, index_natts, 0);
+       index_rescan(index_scan, scankeys, index_natts, NULL, 0);
 
        while ((tup = index_getnext(index_scan,
                                                                ForwardScanDirection)) != NULL)
@@ -879,10 +879,10 @@ index_recheck_constraint(Relation index, Oid *constr_procs,
                                                 Datum *existing_values, bool *existing_isnull,
                                                 Datum *new_values)
 {
-       int                     indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index);
+       int                     index_natts = index->rd_index->indnatts;
        int                     i;
 
-       for (i = 0; i < indnkeyatts; i++)
+       for (i = 0; i < index_natts; i++)
        {
                /* Assume the exclusion operators are strict */
                if (existing_isnull[i])
index 69e82cbe7a57c28e1d84d5165a2f5c57b673f542..bf16cb1b57e5617fea681f20d8f0671e520a5d7a 100644 (file)
@@ -1144,9 +1144,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
                Expr       *leftop;             /* expr on lhs of operator */
                Expr       *rightop;    /* expr on rhs ... */
                AttrNumber      varattno;       /* att number used in scan */
-               int                     indnkeyatts;
 
-               indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index);
                if (IsA(clause, OpExpr))
                {
                        /* indexkey op const or indexkey op expression */
@@ -1171,7 +1169,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
                                elog(ERROR, "indexqual doesn't have key on left side");
 
                        varattno = ((Var *) leftop)->varattno;
-                       if (varattno < 1 || varattno > indnkeyatts)
+                       if (varattno < 1 || varattno > index->rd_index->indnatts)
                                elog(ERROR, "bogus index qualification");
 
                        /*
@@ -1294,7 +1292,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
                                opnos_cell = lnext(opnos_cell);
 
                                if (index->rd_rel->relam != BTREE_AM_OID ||
-                                       varattno < 1 || varattno > indnkeyatts)
+                                       varattno < 1 || varattno > index->rd_index->indnatts)
                                        elog(ERROR, "bogus RowCompare index qualification");
                                opfamily = index->rd_opfamily[varattno - 1];
 
@@ -1415,7 +1413,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
                                elog(ERROR, "indexqual doesn't have key on left side");
 
                        varattno = ((Var *) leftop)->varattno;
-                       if (varattno < 1 || varattno > indnkeyatts)
+                       if (varattno < 1 || varattno > index->rd_index->indnatts)
                                elog(ERROR, "bogus index qualification");
 
                        /*
index 613922001ef66e762c526fc15942071a4467d832..a21928bebe9c8bd9af4efc477dc5ed2f12801fc2 100644 (file)
@@ -2630,7 +2630,6 @@ _copyConstraint(const Constraint *from)
        COPY_NODE_FIELD(raw_expr);
        COPY_STRING_FIELD(cooked_expr);
        COPY_NODE_FIELD(keys);
-       COPY_NODE_FIELD(including);
        COPY_NODE_FIELD(exclusions);
        COPY_NODE_FIELD(options);
        COPY_STRING_FIELD(indexname);
@@ -3120,7 +3119,6 @@ _copyIndexStmt(const IndexStmt *from)
        COPY_STRING_FIELD(accessMethod);
        COPY_STRING_FIELD(tableSpace);
        COPY_NODE_FIELD(indexParams);
-       COPY_NODE_FIELD(indexIncludingParams);
        COPY_NODE_FIELD(options);
        COPY_NODE_FIELD(whereClause);
        COPY_NODE_FIELD(excludeOpNames);
index feaffaec89bb232b52a7250afa9eeafced0cc1dd..3c6c5679b16b17c4794d8b9675122bbb2f267488 100644 (file)
@@ -1250,7 +1250,6 @@ _equalIndexStmt(const IndexStmt *a, const IndexStmt *b)
        COMPARE_STRING_FIELD(accessMethod);
        COMPARE_STRING_FIELD(tableSpace);
        COMPARE_NODE_FIELD(indexParams);
-       COMPARE_NODE_FIELD(indexIncludingParams);
        COMPARE_NODE_FIELD(options);
        COMPARE_NODE_FIELD(whereClause);
        COMPARE_NODE_FIELD(excludeOpNames);
@@ -2385,7 +2384,6 @@ _equalConstraint(const Constraint *a, const Constraint *b)
        COMPARE_NODE_FIELD(raw_expr);
        COMPARE_STRING_FIELD(cooked_expr);
        COMPARE_NODE_FIELD(keys);
-       COMPARE_NODE_FIELD(including);
        COMPARE_NODE_FIELD(exclusions);
        COMPARE_NODE_FIELD(options);
        COMPARE_STRING_FIELD(indexname);
index 804e39eadc46c274b4cd87255ca132c6e86ccaba..f783a49ebac2129b364f8059f5a61c046e809a5e 100644 (file)
@@ -2419,7 +2419,6 @@ _outIndexStmt(StringInfo str, const IndexStmt *node)
        WRITE_STRING_FIELD(accessMethod);
        WRITE_STRING_FIELD(tableSpace);
        WRITE_NODE_FIELD(indexParams);
-       WRITE_NODE_FIELD(indexIncludingParams);
        WRITE_NODE_FIELD(options);
        WRITE_NODE_FIELD(whereClause);
        WRITE_NODE_FIELD(excludeOpNames);
@@ -3156,7 +3155,6 @@ _outConstraint(StringInfo str, const Constraint *node)
                case CONSTR_PRIMARY:
                        appendStringInfoString(str, "PRIMARY_KEY");
                        WRITE_NODE_FIELD(keys);
-                       WRITE_NODE_FIELD(including);
                        WRITE_NODE_FIELD(options);
                        WRITE_STRING_FIELD(indexname);
                        WRITE_STRING_FIELD(indexspace);
@@ -3166,7 +3164,6 @@ _outConstraint(StringInfo str, const Constraint *node)
                case CONSTR_UNIQUE:
                        appendStringInfoString(str, "UNIQUE");
                        WRITE_NODE_FIELD(keys);
-                       WRITE_NODE_FIELD(including);
                        WRITE_NODE_FIELD(options);
                        WRITE_STRING_FIELD(indexname);
                        WRITE_STRING_FIELD(indexspace);
index 69dda34fbae1aa55bfb847a0cc6ce0ff18fd9246..2952bfb7c226507ffa7b9dcf15c77831983ca549 100644 (file)
@@ -2143,7 +2143,7 @@ match_clause_to_index(IndexOptInfo *index,
 {
        int                     indexcol;
 
-       for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
+       for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
        {
                if (match_clause_to_indexcol(index,
                                                                         indexcol,
index 440024a11d6ebe5fcd6c77206bb1a30d66c8a850..4436ac111d17e9203e6d35fe6cf90204377a624e 100644 (file)
@@ -450,13 +450,6 @@ build_index_pathkeys(PlannerInfo *root,
                bool            nulls_first;
                PathKey    *cpathkey;
 
-               /*
-                * INCLUDING columns are stored in index unordered,
-                * so they don't support ordered index scan.
-                */
-               if(i >= index->nkeycolumns)
-                       break;
-
                /* We assume we don't need to make a copy of the tlist item */
                indexkey = indextle->expr;
 
index cbdc30fbea4b85cfdc42d2ce45df5734e151c9b0..86cc640cf267c81f947fc9db4c0cc129e0a021c9 100644 (file)
@@ -173,7 +173,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
                        Form_pg_index index;
                        IndexAmRoutine *amroutine;
                        IndexOptInfo *info;
-                       int                     ncolumns, nkeycolumns;
+                       int                     ncolumns;
                        int                     i;
 
                        /*
@@ -216,25 +216,19 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
                                RelationGetForm(indexRelation)->reltablespace;
                        info->rel = rel;
                        info->ncolumns = ncolumns = index->indnatts;
-                       info->nkeycolumns = nkeycolumns = index->indnkeyatts;
-
                        info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
                        info->indexcollations = (Oid *) palloc(sizeof(Oid) * ncolumns);
-                       info->opfamily = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
-                       info->opcintype = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
+                       info->opfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
+                       info->opcintype = (Oid *) palloc(sizeof(Oid) * ncolumns);
                        info->canreturn = (bool *) palloc(sizeof(bool) * ncolumns);
 
                        for (i = 0; i < ncolumns; i++)
                        {
                                info->indexkeys[i] = index->indkey.values[i];
                                info->indexcollations[i] = indexRelation->rd_indcollation[i];
-                               info->canreturn[i] = index_can_return(indexRelation, i + 1);
-                       }
-
-                       for (i = 0; i < nkeycolumns; i++)
-                       {
                                info->opfamily[i] = indexRelation->rd_opfamily[i];
                                info->opcintype[i] = indexRelation->rd_opcintype[i];
+                               info->canreturn[i] = index_can_return(indexRelation, i + 1);
                        }
 
                        info->relam = indexRelation->rd_rel->relam;
@@ -262,10 +256,10 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
                                Assert(amroutine->amcanorder);
 
                                info->sortopfamily = info->opfamily;
-                               info->reverse_sort = (bool *) palloc(sizeof(bool) * nkeycolumns);
-                               info->nulls_first = (bool *) palloc(sizeof(bool) * nkeycolumns);
+                               info->reverse_sort = (bool *) palloc(sizeof(bool) * ncolumns);
+                               info->nulls_first = (bool *) palloc(sizeof(bool) * ncolumns);
 
-                               for (i = 0; i < nkeycolumns; i++)
+                               for (i = 0; i < ncolumns; i++)
                                {
                                        int16           opt = indexRelation->rd_indoption[i];
 
@@ -289,11 +283,11 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
                                 * of current or foreseeable amcanorder index types, it's not
                                 * worth expending more effort on now.
                                 */
-                               info->sortopfamily = (Oid *) palloc(sizeof(Oid) * nkeycolumns);
-                               info->reverse_sort = (bool *) palloc(sizeof(bool) * nkeycolumns);
-                               info->nulls_first = (bool *) palloc(sizeof(bool) * nkeycolumns);
+                               info->sortopfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);
+                               info->reverse_sort = (bool *) palloc(sizeof(bool) * ncolumns);
+                               info->nulls_first = (bool *) palloc(sizeof(bool) * ncolumns);
 
-                               for (i = 0; i < nkeycolumns; i++)
+                               for (i = 0; i < ncolumns; i++)
                                {
                                        int16           opt = indexRelation->rd_indoption[i];
                                        Oid                     ltopr;
@@ -687,7 +681,7 @@ infer_arbiter_indexes(PlannerInfo *root)
                        goto next;
 
                /* Build BMS representation of cataloged index attributes */
-               for (natt = 0; natt < idxForm->indnkeyatts; natt++)
+               for (natt = 0; natt < idxForm->indnatts; natt++)
                {
                        int                     attno = idxRel->rd_index->indkey.values[natt];
 
@@ -1626,7 +1620,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno)
                 * just the specified attr is unique.
                 */
                if (index->unique &&
-                       index->nkeycolumns == 1 &&
+                       index->ncolumns == 1 &&
                        index->indexkeys[0] == attno &&
                        (index->indpred == NIL || index->predOK))
                        return true;
index faf83092b7af0aa68924943ac80b0d15601fc5bf..7d2fedfaadf3194e891f76dd2eecdbd5e301d76c 100644 (file)
@@ -920,7 +920,7 @@ transformOnConflictClause(ParseState *pstate,
                 * relation.
                 */
                Assert(pstate->p_next_resno == 1);
-               for (attno = 0; attno < RelationGetNumberOfAttributes(targetrel); attno++)
+               for (attno = 0; attno < targetrel->rd_rel->relnatts; attno++)
                {
                        Form_pg_attribute attr = targetrel->rd_att->attrs[attno];
                        char       *name;
@@ -2122,8 +2122,8 @@ transformUpdateTargetList(ParseState *pstate, List *origTlist)
                                                                EXPR_KIND_UPDATE_SOURCE);
 
        /* Prepare to assign non-conflicting resnos to resjunk attributes */
-       if (pstate->p_next_resno <= RelationGetNumberOfAttributes(pstate->p_target_relation))
-               pstate->p_next_resno = RelationGetNumberOfAttributes(pstate->p_target_relation) + 1;
+       if (pstate->p_next_resno <= pstate->p_target_relation->rd_rel->relnatts)
+               pstate->p_next_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
 
        /* Prepare non-junk columns for assignment to target table */
        target_rte = pstate->p_target_rangetblentry;
index 7166d6f8bbd18a9806b822f3774d9f4aec35575a..18ec5f03d81c6226eadf49d6184dc293d80f06cb 100644 (file)
@@ -356,7 +356,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
                                oper_argtypes RuleActionList RuleActionMulti
                                opt_column_list columnList opt_name_list
                                sort_clause opt_sort_clause sortby_list index_params
-                               optincluding opt_including index_including_params
                                name_list role_list from_clause from_list opt_array_bounds
                                qualified_name_list any_name any_name_list type_name_list
                                any_operator expr_list attrs
@@ -373,7 +372,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
                                create_generic_options alter_generic_options
                                relation_expr_list dostmt_opt_list
                                transform_element_list transform_type_list
-                               optcincluding opt_c_including
 
 %type <list>   group_by_list
 %type <node>   group_by_item empty_grouping_set rollup_clause cube_clause
@@ -3219,18 +3217,17 @@ ConstraintElem:
                                        n->initially_valid = !n->skip_validation;
                                        $$ = (Node *)n;
                                }
-                       | UNIQUE '(' columnList ')' opt_c_including opt_definition OptConsTableSpace
+                       | UNIQUE '(' columnList ')' opt_definition OptConsTableSpace
                                ConstraintAttributeSpec
                                {
                                        Constraint *n = makeNode(Constraint);
                                        n->contype = CONSTR_UNIQUE;
                                        n->location = @1;
                                        n->keys = $3;
-                                       n->including = $5;
-                                       n->options = $6;
+                                       n->options = $5;
                                        n->indexname = NULL;
-                                       n->indexspace = $7;
-                                       processCASbits($8, @8, "UNIQUE",
+                                       n->indexspace = $6;
+                                       processCASbits($7, @7, "UNIQUE",
                                                                   &n->deferrable, &n->initdeferred, NULL,
                                                                   NULL, yyscanner);
                                        $$ = (Node *)n;
@@ -3241,7 +3238,6 @@ ConstraintElem:
                                        n->contype = CONSTR_UNIQUE;
                                        n->location = @1;
                                        n->keys = NIL;
-                                       n->including = NIL;
                                        n->options = NIL;
                                        n->indexname = $2;
                                        n->indexspace = NULL;
@@ -3250,18 +3246,17 @@ ConstraintElem:
                                                                   NULL, yyscanner);
                                        $$ = (Node *)n;
                                }
-                       | PRIMARY KEY '(' columnList ')' opt_c_including opt_definition OptConsTableSpace
+                       | PRIMARY KEY '(' columnList ')' opt_definition OptConsTableSpace
                                ConstraintAttributeSpec
                                {
                                        Constraint *n = makeNode(Constraint);
                                        n->contype = CONSTR_PRIMARY;
                                        n->location = @1;
                                        n->keys = $4;
-                                       n->including = $6;
-                                       n->options = $7;
+                                       n->options = $6;
                                        n->indexname = NULL;
-                                       n->indexspace = $8;
-                                       processCASbits($9, @9, "PRIMARY KEY",
+                                       n->indexspace = $7;
+                                       processCASbits($8, @8, "PRIMARY KEY",
                                                                   &n->deferrable, &n->initdeferred, NULL,
                                                                   NULL, yyscanner);
                                        $$ = (Node *)n;
@@ -3272,7 +3267,6 @@ ConstraintElem:
                                        n->contype = CONSTR_PRIMARY;
                                        n->location = @1;
                                        n->keys = NIL;
-                                       n->including = NIL;
                                        n->options = NIL;
                                        n->indexname = $3;
                                        n->indexspace = NULL;
@@ -3340,13 +3334,6 @@ columnElem: ColId
                                }
                ;
 
-opt_c_including:       INCLUDING optcincluding                 { $$ = $2; }
-                        |              /* EMPTY */                                             { $$ = NIL; }
-               ;
-
-optcincluding : '(' columnList ')'             { $$ = $2; }
-               ;
-
 key_match:  MATCH FULL
                        {
                                $$ = FKCONSTR_MATCH_FULL;
@@ -6639,7 +6626,7 @@ defacl_privilege_target:
 
 IndexStmt:     CREATE opt_unique INDEX opt_concurrently opt_index_name
                        ON qualified_name access_method_clause '(' index_params ')'
-                       opt_including opt_reloptions OptTableSpace where_clause
+                       opt_reloptions OptTableSpace where_clause
                                {
                                        IndexStmt *n = makeNode(IndexStmt);
                                        n->unique = $2;
@@ -6648,10 +6635,9 @@ IndexStmt:       CREATE opt_unique INDEX opt_concurrently opt_index_name
                                        n->relation = $7;
                                        n->accessMethod = $8;
                                        n->indexParams = $10;
-                                       n->indexIncludingParams = $12;
-                                       n->options = $13;
-                                       n->tableSpace = $14;
-                                       n->whereClause = $15;
+                                       n->options = $12;
+                                       n->tableSpace = $13;
+                                       n->whereClause = $14;
                                        n->excludeOpNames = NIL;
                                        n->idxcomment = NULL;
                                        n->indexOid = InvalidOid;
@@ -6666,7 +6652,7 @@ IndexStmt:        CREATE opt_unique INDEX opt_concurrently opt_index_name
                                }
                        | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS index_name
                        ON qualified_name access_method_clause '(' index_params ')'
-                       opt_including opt_reloptions OptTableSpace where_clause
+                       opt_reloptions OptTableSpace where_clause
                                {
                                        IndexStmt *n = makeNode(IndexStmt);
                                        n->unique = $2;
@@ -6675,10 +6661,9 @@ IndexStmt:       CREATE opt_unique INDEX opt_concurrently opt_index_name
                                        n->relation = $10;
                                        n->accessMethod = $11;
                                        n->indexParams = $13;
-                                       n->indexIncludingParams = $15;
-                                       n->options = $16;
-                                       n->tableSpace = $17;
-                                       n->whereClause = $18;
+                                       n->options = $15;
+                                       n->tableSpace = $16;
+                                       n->whereClause = $17;
                                        n->excludeOpNames = NIL;
                                        n->idxcomment = NULL;
                                        n->indexOid = InvalidOid;
@@ -6757,16 +6742,6 @@ index_elem:      ColId opt_collate opt_class opt_asc_desc opt_nulls_order
                                }
                ;
 
-optincluding : '(' index_including_params ')'          { $$ = $2; }
-               ;
-opt_including:         INCLUDING optincluding                  { $$ = $2; }
-                        |              /* EMPTY */                                             { $$ = NIL; }
-               ;
-
-index_including_params:        index_elem                                              { $$ = list_make1($1); }
-                       | index_including_params ',' index_elem         { $$ = lappend($1, $3); }
-               ;
-
 opt_collate: COLLATE any_name                                          { $$ = $2; }
                        | /*EMPTY*/                                                             { $$ = NIL; }
                ;
index 0f5d796c7fd643e54b655f9fde795f5b071eb4b2..81332b57d9311c2a04afe2200fe842f179850576 100644 (file)
@@ -2875,7 +2875,7 @@ attnameAttNum(Relation rd, const char *attname, bool sysColOK)
 {
        int                     i;
 
-       for (i = 0; i < RelationGetNumberOfAttributes(rd); i++)
+       for (i = 0; i < rd->rd_rel->relnatts; i++)
        {
                Form_pg_attribute att = rd->rd_att->attrs[i];
 
index b5ec2bd371b30abc2f99658834ea5175331697b3..fc93063ed0b48cbc0922bc27c52ef0f2c50633b5 100644 (file)
@@ -898,7 +898,7 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
                 * Generate default column list for INSERT.
                 */
                Form_pg_attribute *attr = pstate->p_target_relation->rd_att->attrs;
-               int                     numcol = RelationGetNumberOfAttributes(pstate->p_target_relation);
+               int                     numcol = pstate->p_target_relation->rd_rel->relnatts;
                int                     i;
 
                for (i = 0; i < numcol; i++)
index 707106f10c2da004b7044815fcaab9fbcb4be6de..65284941ed98e6367277fd68a6ac5a9a942ee2e7 100644 (file)
@@ -1242,14 +1242,14 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
 
        /* Build the list of IndexElem */
        index->indexParams = NIL;
-       index->indexIncludingParams = NIL;
 
        indexpr_item = list_head(indexprs);
-       for (keyno = 0; keyno < idxrec->indnkeyatts; keyno++)
+       for (keyno = 0; keyno < idxrec->indnatts; keyno++)
        {
                IndexElem  *iparam;
                AttrNumber      attnum = idxrec->indkey.values[keyno];
                int16           opt = source_idx->rd_indoption[keyno];
+
                iparam = makeNode(IndexElem);
 
                if (AttributeNumberIsValid(attnum))
@@ -1331,38 +1331,6 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
                index->indexParams = lappend(index->indexParams, iparam);
        }
 
-       /* Handle included columns separately */
-       for (keyno = idxrec->indnkeyatts; keyno < idxrec->indnatts; keyno++)
-       {
-               IndexElem  *iparam;
-               AttrNumber      attnum = idxrec->indkey.values[keyno];
-
-               iparam = makeNode(IndexElem);
-
-               if (AttributeNumberIsValid(attnum))
-               {
-                       /* Simple index column */
-                       char       *attname;
-
-                       attname = get_relid_attribute_name(indrelid, attnum);
-                       keycoltype = get_atttype(indrelid, attnum);
-
-                       iparam->name = attname;
-                       iparam->expr = NULL;
-               }
-               else
-                       ereport(ERROR,
-                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("expressions are not supported in included columns")));
-
-               /* Copy the original index column name */
-               iparam->indexcolname = pstrdup(NameStr(attrs[keyno]->attname));
-
-               /* Add the collation name, if non-default */
-               iparam->collation = get_collation(indcollation->values[keyno], keycoltype);
-
-               index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
-       }
        /* Copy reloptions if any */
        datum = SysCacheGetAttr(RELOID, ht_idxrel,
                                                        Anum_pg_class_reloptions, &isnull);
@@ -1555,7 +1523,6 @@ transformIndexConstraints(CreateStmtContext *cxt)
                        IndexStmt  *priorindex = lfirst(k);
 
                        if (equal(index->indexParams, priorindex->indexParams) &&
-                               equal(index->indexIncludingParams, priorindex->indexIncludingParams) &&
                                equal(index->whereClause, priorindex->whereClause) &&
                                equal(index->excludeOpNames, priorindex->excludeOpNames) &&
                                strcmp(index->accessMethod, priorindex->accessMethod) == 0 &&
@@ -1627,7 +1594,6 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
        index->tableSpace = constraint->indexspace;
        index->whereClause = constraint->where_clause;
        index->indexParams = NIL;
-       index->indexIncludingParams = NIL;
        index->excludeOpNames = NIL;
        index->idxcomment = NULL;
        index->indexOid = InvalidOid;
@@ -1777,30 +1743,24 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
                                                                                           heap_rel->rd_rel->relhasoids);
                        attname = pstrdup(NameStr(attform->attname));
 
-                       if (i < index_form->indnkeyatts)
-                       {
-                               /*
-                               * Insist on default opclass and sort options.  While the index
-                               * would still work as a constraint with non-default settings, it
-                               * might not provide exactly the same uniqueness semantics as
-                               * you'd get from a normally-created constraint; and there's also
-                               * the dump/reload problem mentioned above.
-                               */
-                               defopclass = GetDefaultOpClass(attform->atttypid,
-                                                                                       index_rel->rd_rel->relam);
-                               if (indclass->values[i] != defopclass ||
-                                       index_rel->rd_indoption[i] != 0)
-                                       ereport(ERROR,
-                                                       (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                                                       errmsg("index \"%s\" does not have default sorting behavior", index_name),
-                                                       errdetail("Cannot create a primary key or unique constraint using such an index."),
-                                               parser_errposition(cxt->pstate, constraint->location)));
-
-                               constraint->keys = lappend(constraint->keys, makeString(attname));
-                       }
-                       else
-                               constraint->including = lappend(constraint->including, makeString(attname));
+                       /*
+                        * Insist on default opclass and sort options.  While the index
+                        * would still work as a constraint with non-default settings, it
+                        * might not provide exactly the same uniqueness semantics as
+                        * you'd get from a normally-created constraint; and there's also
+                        * the dump/reload problem mentioned above.
+                        */
+                       defopclass = GetDefaultOpClass(attform->atttypid,
+                                                                                  index_rel->rd_rel->relam);
+                       if (indclass->values[i] != defopclass ||
+                               index_rel->rd_indoption[i] != 0)
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+                                                errmsg("index \"%s\" does not have default sorting behavior", index_name),
+                                                errdetail("Cannot create a primary key or unique constraint using such an index."),
+                                        parser_errposition(cxt->pstate, constraint->location)));
 
+                       constraint->keys = lappend(constraint->keys, makeString(attname));
                }
 
                /* Close the index relation but keep the lock */
@@ -1813,7 +1773,6 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
         * If it's an EXCLUDE constraint, the grammar returns a list of pairs of
         * IndexElems and operator names.  We have to break that apart into
         * separate lists.
-        * NOTE that exclusion constraints don't support included nonkey attributes
         */
        if (constraint->contype == CONSTR_EXCLUSION)
        {
@@ -1968,48 +1927,6 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
                index->indexParams = lappend(index->indexParams, iparam);
        }
 
-       /* Here is some ugly code duplication. But we do need it. */
-       foreach(lc, constraint->including)
-       {
-               char       *key = strVal(lfirst(lc));
-               bool            found = false;
-               ColumnDef  *column = NULL;
-               ListCell   *columns;
-               IndexElem  *iparam;
-
-               foreach(columns, cxt->columns)
-               {
-                       column = (ColumnDef *) lfirst(columns);
-                       Assert(IsA(column, ColumnDef));
-                       if (strcmp(column->colname, key) == 0)
-                       {
-                               found = true;
-                               break;
-                       }
-               }
-
-               /*
-                * In the ALTER TABLE case, don't complain about index keys not
-                * created in the command; they may well exist already. DefineIndex
-                * will complain about them if not, and will also take care of marking
-                * them NOT NULL.
-                */
-               if (!found && !cxt->isalter)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_UNDEFINED_COLUMN),
-                                        errmsg("column \"%s\" named in key does not exist", key),
-                                        parser_errposition(cxt->pstate, constraint->location)));
-
-               /* OK, add it to the index definition */
-               iparam = makeNode(IndexElem);
-               iparam->name = pstrdup(key);
-               iparam->expr = NULL;
-               iparam->indexcolname = NULL;
-               iparam->collation = NIL;
-               iparam->opclass = NIL;
-               index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
-       }
-
        return index;
 }
 
index 0e1eefd8dac871312239f12a19d22652d254a6b5..2b47e95a687a601e0a51529087f8194a487889ac 100644 (file)
@@ -1140,21 +1140,6 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
                Oid                     keycoltype;
                Oid                     keycolcollation;
 
-               /*
-                * attrsOnly flag is used for building unique-constraint and
-                * exclusion-constraint error messages. Included attrs are
-                * meaningless there, so do not include them into the message.
-                */
-               if (attrsOnly && keyno >= idxrec->indnkeyatts)
-                       break;
-
-               /* Report the INCLUDED attributes, if any. */
-               if ((!attrsOnly) && keyno == idxrec->indnkeyatts)
-               {
-                               appendStringInfoString(&buf, ") INCLUDING (");
-                               sep = "";
-               }
-
                if (!colno)
                        appendStringInfoString(&buf, sep);
                sep = ", ";
@@ -1168,7 +1153,6 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
                        attname = get_relid_attribute_name(indrelid, attnum);
                        if (!colno || colno == keyno + 1)
                                appendStringInfoString(&buf, quote_identifier(attname));
-
                        get_atttypetypmodcoll(indrelid, attnum,
                                                                  &keycoltype, &keycoltypmod,
                                                                  &keycolcollation);
@@ -1208,9 +1192,6 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
                                appendStringInfo(&buf, " COLLATE %s",
                                                                 generate_collation_name((indcoll)));
 
-                       if(keyno >= idxrec->indnkeyatts)
-                               continue;
-
                        /* Add the operator class name, if not default */
                        get_opclass_name(indclass->values[keyno], keycoltype, &buf);
 
@@ -1539,19 +1520,6 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
 
                                appendStringInfoChar(&buf, ')');
 
-                               /* Fetch and build including column list */
-                               isnull = true;
-                               val = SysCacheGetAttr(CONSTROID, tup,
-                                                                         Anum_pg_constraint_conincluding, &isnull);
-                               if (!isnull)
-                               {
-                                       appendStringInfoString(&buf, " INCLUDING (");
-
-                                       decompile_column_index_array(val, conForm->conrelid, &buf);
-
-                                       appendStringInfoChar(&buf, ')');
-                               }
-
                                indexId = get_constraint_index(constraintId);
 
                                /* XXX why do we only print these bits if fullCommand? */
index 7b52a92a89ab667f581c5826fd77173cfe32fad9..cc2a9a1b6c50515dc7b9cd2538c2506ffe5b3b27 100644 (file)
@@ -4520,7 +4520,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
                                                 * should match has_unique_index().
                                                 */
                                                if (index->unique &&
-                                                       index->nkeycolumns == 1 &&
+                                                       index->ncolumns == 1 &&
                                                        (index->indpred == NIL || index->predOK))
                                                        vardata->isunique = true;
 
@@ -6563,7 +6563,7 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
         * NullTest invalidates that theory, even though it sets eqQualHere.
         */
        if (index->unique &&
-               indexcol == index->nkeycolumns - 1 &&
+               indexcol == index->ncolumns - 1 &&
                eqQualHere &&
                !found_saop &&
                !found_is_null_op)
index b171ddb8cc6025937a8db9fc8412208371ea33a8..432feefa6094593ba934a7da68f24e959748b90f 100644 (file)
@@ -521,7 +521,7 @@ RelationBuildTupleDesc(Relation relation)
        /*
         * add attribute data to relation->rd_att
         */
-       need = RelationGetNumberOfAttributes(relation);
+       need = relation->rd_rel->relnatts;
 
        while (HeapTupleIsValid(pg_attribute_tuple = systable_getnext(pg_attribute_scan)))
        {
@@ -530,7 +530,7 @@ RelationBuildTupleDesc(Relation relation)
                attp = (Form_pg_attribute) GETSTRUCT(pg_attribute_tuple);
 
                if (attp->attnum <= 0 ||
-                       attp->attnum > RelationGetNumberOfAttributes(relation))
+                       attp->attnum > relation->rd_rel->relnatts)
                        elog(ERROR, "invalid attribute number %d for %s",
                                 attp->attnum, RelationGetRelationName(relation));
 
@@ -547,7 +547,7 @@ RelationBuildTupleDesc(Relation relation)
                        if (attrdef == NULL)
                                attrdef = (AttrDefault *)
                                        MemoryContextAllocZero(CacheMemoryContext,
-                                                                                  RelationGetNumberOfAttributes(relation) *
+                                                                                  relation->rd_rel->relnatts *
                                                                                   sizeof(AttrDefault));
                        attrdef[ndef].adnum = attp->attnum;
                        attrdef[ndef].adbin = NULL;
@@ -577,7 +577,7 @@ RelationBuildTupleDesc(Relation relation)
        {
                int                     i;
 
-               for (i = 0; i < RelationGetNumberOfAttributes(relation); i++)
+               for (i = 0; i < relation->rd_rel->relnatts; i++)
                        Assert(relation->rd_att->attrs[i]->attcacheoff == -1);
        }
 #endif
@@ -587,7 +587,7 @@ RelationBuildTupleDesc(Relation relation)
         * attribute: it must be zero.  This eliminates the need for special cases
         * for attnum=1 that used to exist in fastgetattr() and index_getattr().
         */
-       if (RelationGetNumberOfAttributes(relation) > 0)
+       if (relation->rd_rel->relnatts > 0)
                relation->rd_att->attrs[0]->attcacheoff = 0;
 
        /*
@@ -599,7 +599,7 @@ RelationBuildTupleDesc(Relation relation)
 
                if (ndef > 0)                   /* DEFAULTs */
                {
-                       if (ndef < RelationGetNumberOfAttributes(relation))
+                       if (ndef < relation->rd_rel->relnatts)
                                constr->defval = (AttrDefault *)
                                        repalloc(attrdef, ndef * sizeof(AttrDefault));
                        else
@@ -1205,8 +1205,7 @@ RelationInitIndexAccessInfo(Relation relation)
        int2vector *indoption;
        MemoryContext indexcxt;
        MemoryContext oldcontext;
-       int                     indnatts;
-       int                     indnkeyatts;
+       int                     natts;
        uint16          amsupport;
 
        /*
@@ -1236,11 +1235,10 @@ RelationInitIndexAccessInfo(Relation relation)
        relation->rd_amhandler = aform->amhandler;
        ReleaseSysCache(tuple);
 
-       indnatts = RelationGetNumberOfAttributes(relation);
-       if (indnatts != IndexRelationGetNumberOfAttributes(relation))
+       natts = relation->rd_rel->relnatts;
+       if (natts != relation->rd_index->indnatts)
                elog(ERROR, "relnatts disagrees with indnatts for index %u",
                         RelationGetRelid(relation));
-       indnkeyatts = IndexRelationGetNumberOfKeyAttributes(relation);
 
        /*
         * Make the private context to hold index access info.  The reason we need
@@ -1266,14 +1264,14 @@ RelationInitIndexAccessInfo(Relation relation)
         * Allocate arrays to hold data
         */
        relation->rd_opfamily = (Oid *)
-               MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(Oid));
+               MemoryContextAllocZero(indexcxt, natts * sizeof(Oid));
        relation->rd_opcintype = (Oid *)
-               MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(Oid));
+               MemoryContextAllocZero(indexcxt, natts * sizeof(Oid));
 
        amsupport = relation->rd_amroutine->amsupport;
        if (amsupport > 0)
        {
-               int                     nsupport = indnatts * amsupport;
+               int                     nsupport = natts * amsupport;
 
                relation->rd_support = (RegProcedure *)
                        MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure));
@@ -1287,10 +1285,10 @@ RelationInitIndexAccessInfo(Relation relation)
        }
 
        relation->rd_indcollation = (Oid *)
-               MemoryContextAllocZero(indexcxt, indnatts * sizeof(Oid));
+               MemoryContextAllocZero(indexcxt, natts * sizeof(Oid));
 
        relation->rd_indoption = (int16 *)
-               MemoryContextAllocZero(indexcxt, indnatts * sizeof(int16));
+               MemoryContextAllocZero(indexcxt, natts * sizeof(int16));
 
        /*
         * indcollation cannot be referenced directly through the C struct,
@@ -1303,7 +1301,7 @@ RelationInitIndexAccessInfo(Relation relation)
                                                           &isnull);
        Assert(!isnull);
        indcoll = (oidvector *) DatumGetPointer(indcollDatum);
-       memcpy(relation->rd_indcollation, indcoll->values, indnatts * sizeof(Oid));
+       memcpy(relation->rd_indcollation, indcoll->values, natts * sizeof(Oid));
 
        /*
         * indclass cannot be referenced directly through the C struct, because it
@@ -1324,7 +1322,7 @@ RelationInitIndexAccessInfo(Relation relation)
         */
        IndexSupportInitialize(indclass, relation->rd_support,
                                                   relation->rd_opfamily, relation->rd_opcintype,
-                                                  amsupport, indnkeyatts);
+                                                  amsupport, natts);
 
        /*
         * Similarly extract indoption and copy it to the cache entry
@@ -1335,7 +1333,7 @@ RelationInitIndexAccessInfo(Relation relation)
                                                                 &isnull);
        Assert(!isnull);
        indoption = (int2vector *) DatumGetPointer(indoptionDatum);
-       memcpy(relation->rd_indoption, indoption->values, indnatts * sizeof(int16));
+       memcpy(relation->rd_indoption, indoption->values, natts * sizeof(int16));
 
        /*
         * expressions, predicate, exclusion caches will be filled later
@@ -4396,25 +4394,16 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
                {
                        int                     attrnum = indexInfo->ii_KeyAttrNumbers[i];
 
-                       /*
-                        * Since we have covering indexes with non-key columns,
-                        * we must handle them accurately here. non-key columns
-                        * must be added into indexattrs, since they are in index,
-                        * and HOT-update shouldn't miss them.
-                        * Obviously, non-key columns couldn't be referenced by
-                        * foreign key or identity key. Hence we do not include
-                        * them into uindexattrs and idindexattrs bitmaps.
-                        */
                        if (attrnum != 0)
                        {
                                indexattrs = bms_add_member(indexattrs,
                                                           attrnum - FirstLowInvalidHeapAttributeNumber);
 
-                               if (isKey && i < indexInfo->ii_NumIndexKeyAttrs)
+                               if (isKey)
                                        uindexattrs = bms_add_member(uindexattrs,
                                                           attrnum - FirstLowInvalidHeapAttributeNumber);
 
-                               if (isIDKey && i < indexInfo->ii_NumIndexKeyAttrs)
+                               if (isIDKey)
                                        idindexattrs = bms_add_member(idindexattrs,
                                                           attrnum - FirstLowInvalidHeapAttributeNumber);
                        }
@@ -4482,7 +4471,7 @@ RelationGetExclusionInfo(Relation indexRelation,
                                                 Oid **procs,
                                                 uint16 **strategies)
 {
-       int                     indnkeyatts;
+       int                     ncols = indexRelation->rd_rel->relnatts;
        Oid                *ops;
        Oid                *funcs;
        uint16     *strats;
@@ -4494,19 +4483,17 @@ RelationGetExclusionInfo(Relation indexRelation,
        MemoryContext oldcxt;
        int                     i;
 
-       indnkeyatts = IndexRelationGetNumberOfKeyAttributes(indexRelation);
-
        /* Allocate result space in caller context */
-       *operators = ops = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
-       *procs = funcs = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
-       *strategies = strats = (uint16 *) palloc(sizeof(uint16) * indnkeyatts);
+       *operators = ops = (Oid *) palloc(sizeof(Oid) * ncols);
+       *procs = funcs = (Oid *) palloc(sizeof(Oid) * ncols);
+       *strategies = strats = (uint16 *) palloc(sizeof(uint16) * ncols);
 
        /* Quick exit if we have the data cached already */
        if (indexRelation->rd_exclstrats != NULL)
        {
-               memcpy(ops, indexRelation->rd_exclops, sizeof(Oid) * indnkeyatts);
-               memcpy(funcs, indexRelation->rd_exclprocs, sizeof(Oid) * indnkeyatts);
-               memcpy(strats, indexRelation->rd_exclstrats, sizeof(uint16) * indnkeyatts);
+               memcpy(ops, indexRelation->rd_exclops, sizeof(Oid) * ncols);
+               memcpy(funcs, indexRelation->rd_exclprocs, sizeof(Oid) * ncols);
+               memcpy(strats, indexRelation->rd_exclstrats, sizeof(uint16) * ncols);
                return;
        }
 
@@ -4555,12 +4542,12 @@ RelationGetExclusionInfo(Relation indexRelation,
                arr = DatumGetArrayTypeP(val);  /* ensure not toasted */
                nelem = ARR_DIMS(arr)[0];
                if (ARR_NDIM(arr) != 1 ||
-                       nelem != indnkeyatts ||
+                       nelem != ncols ||
                        ARR_HASNULL(arr) ||
                        ARR_ELEMTYPE(arr) != OIDOID)
                        elog(ERROR, "conexclop is not a 1-D Oid array");
 
-               memcpy(ops, ARR_DATA_PTR(arr), sizeof(Oid) * indnkeyatts);
+               memcpy(ops, ARR_DATA_PTR(arr), sizeof(Oid) * ncols);
        }
 
        systable_endscan(conscan);
@@ -4571,7 +4558,7 @@ RelationGetExclusionInfo(Relation indexRelation,
                         RelationGetRelationName(indexRelation));
 
        /* We need the func OIDs and strategy numbers too */
-       for (i = 0; i < indnkeyatts; i++)
+       for (i = 0; i < ncols; i++)
        {
                funcs[i] = get_opcode(ops[i]);
                strats[i] = get_op_opfamily_strategy(ops[i],
@@ -4584,12 +4571,12 @@ RelationGetExclusionInfo(Relation indexRelation,
 
        /* Save a copy of the results in the relcache entry. */
        oldcxt = MemoryContextSwitchTo(indexRelation->rd_indexcxt);
-       indexRelation->rd_exclops = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
-       indexRelation->rd_exclprocs = (Oid *) palloc(sizeof(Oid) * indnkeyatts);
-       indexRelation->rd_exclstrats = (uint16 *) palloc(sizeof(uint16) * indnkeyatts);
-       memcpy(indexRelation->rd_exclops, ops, sizeof(Oid) * indnkeyatts);
-       memcpy(indexRelation->rd_exclprocs, funcs, sizeof(Oid) * indnkeyatts);
-       memcpy(indexRelation->rd_exclstrats, strats, sizeof(uint16) * indnkeyatts);
+       indexRelation->rd_exclops = (Oid *) palloc(sizeof(Oid) * ncols);
+       indexRelation->rd_exclprocs = (Oid *) palloc(sizeof(Oid) * ncols);
+       indexRelation->rd_exclstrats = (uint16 *) palloc(sizeof(uint16) * ncols);
+       memcpy(indexRelation->rd_exclops, ops, sizeof(Oid) * ncols);
+       memcpy(indexRelation->rd_exclprocs, funcs, sizeof(Oid) * ncols);
+       memcpy(indexRelation->rd_exclstrats, strats, sizeof(uint16) * ncols);
        MemoryContextSwitchTo(oldcxt);
 }
 
index e189b55fa296c5b3512caa1dd189f1b9c356ddf9..4cc5be92a2a0978d460f1339b699fa5a8044630c 100644 (file)
@@ -809,7 +809,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc,
                         workMem, randomAccess ? 't' : 'f');
 #endif
 
-       state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel); //FIXME
+       state->nKeys = RelationGetNumberOfAttributes(indexRel);
 
        TRACE_POSTGRESQL_SORT_START(CLUSTER_SORT,
                                                                false,  /* no unique check */
@@ -900,7 +900,7 @@ tuplesort_begin_index_btree(Relation heapRel,
                         workMem, randomAccess ? 't' : 'f');
 #endif
 
-       state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
+       state->nKeys = RelationGetNumberOfAttributes(indexRel);
 
        TRACE_POSTGRESQL_SORT_START(INDEX_SORT,
                                                                enforceUnique,
@@ -919,6 +919,7 @@ tuplesort_begin_index_btree(Relation heapRel,
        state->enforceUnique = enforceUnique;
 
        indexScanKey = _bt_mkscankey_nodata(indexRel);
+       state->nKeys = RelationGetNumberOfAttributes(indexRel);
 
        /* Prepare SortSupport data for each column */
        state->sortKeys = (SortSupport) palloc0(state->nKeys *
index 7e6abd762c2cbbd1a2fbfc1662360ce459703164..33cd6651d124af78ad257e2d4c4619cad734b9de 100644 (file)
@@ -5991,8 +5991,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                                i_oid,
                                i_indexname,
                                i_indexdef,
-                               i_indnnkeyatts,
-                               i_indnatts,
+                               i_indnkeys,
                                i_indkey,
                                i_indisclustered,
                                i_indisreplident,
@@ -6043,42 +6042,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                 * is not.
                 */
                resetPQExpBuffer(query);
-               if (fout->remoteVersion >= 90600)
-               {
-                       /*
-                        * In 9.6 we add INCLUDING columns functionality
-                        * that requires new fields to be added.
-                        * i.indnkeyattrs is new, and besides we should use
-                        * i.indnatts instead of t.relnatts for index relations.
-                        *
-                        */
-                       appendPQExpBuffer(query,
-                                                         "SELECT t.tableoid, t.oid, "
-                                                         "t.relname AS indexname, "
-                                        "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
-                                                         "i.indnkeyatts AS indnkeyatts, "
-                                                         "i.indnatts AS indnatts, "
-                                                         "i.indkey, i.indisclustered, "
-                                                         "i.indisreplident, t.relpages, "
-                                                         "c.contype, c.conname, "
-                                                         "c.condeferrable, c.condeferred, "
-                                                         "c.tableoid AS contableoid, "
-                                                         "c.oid AS conoid, "
-                                 "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
-                                                         "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
-                                                         "t.reloptions AS indreloptions "
-                                                         "FROM pg_catalog.pg_index i "
-                                         "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
-                                                         "LEFT JOIN pg_catalog.pg_constraint c "
-                                                         "ON (i.indrelid = c.conrelid AND "
-                                                         "i.indexrelid = c.conindid AND "
-                                                         "c.contype IN ('p','u','x')) "
-                                                         "WHERE i.indrelid = '%u'::pg_catalog.oid "
-                                                         "AND i.indisvalid AND i.indisready "
-                                                         "ORDER BY indexname",
-                                                         tbinfo->dobj.catId.oid);
-               }
-               else if (fout->remoteVersion >= 90400)
+               if (fout->remoteVersion >= 90400)
                {
                        /*
                         * the test on indisready is necessary in 9.2, and harmless in
@@ -6289,8 +6253,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                i_oid = PQfnumber(res, "oid");
                i_indexname = PQfnumber(res, "indexname");
                i_indexdef = PQfnumber(res, "indexdef");
-               i_indnnkeyatts = PQfnumber(res, "indnkeyatts");
-               i_indnatts = PQfnumber(res, "indnatts");
+               i_indnkeys = PQfnumber(res, "indnkeys");
                i_indkey = PQfnumber(res, "indkey");
                i_indisclustered = PQfnumber(res, "indisclustered");
                i_indisreplident = PQfnumber(res, "indisreplident");
@@ -6320,8 +6283,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                        indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                        indxinfo[j].indextable = tbinfo;
                        indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
-                       indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnnkeyatts));
-                       indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
+                       indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
                        indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
                        indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
 
@@ -15944,7 +15906,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                {
                        appendPQExpBuffer(q, "%s (",
                                                 coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
-                       for (k = 0; k < indxinfo->indnkeyattrs; k++)
+                       for (k = 0; k < indxinfo->indnkeys; k++)
                        {
                                int                     indkey = (int) indxinfo->indkeys[k];
                                const char *attname;
@@ -15958,23 +15920,6 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                                                  fmtId(attname));
                        }
 
-                       if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
-                               appendPQExpBuffer(q, ") INCLUDING (");
-
-                       for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
-                       {
-                               int                     indkey = (int) indxinfo->indkeys[k];
-                               const char *attname;
-
-                               if (indkey == InvalidAttrNumber)
-                                       break;
-                               attname = getAttrName(indkey, tbinfo);
-
-                               appendPQExpBuffer(q, "%s%s",
-                                                                 (k == indxinfo->indnkeyattrs) ? "" : ", ",
-                                                                 fmtId(attname));
-                       }
-
                        appendPQExpBufferChar(q, ')');
 
                        if (nonemptyReloptions(indxinfo->indreloptions))
index 95fa76d95a6c6ad8498e87ad2c9ce3ecdf163da1..7314cbeec80a375d735ff9219f0cdd614fb6c23a 100644 (file)
@@ -318,10 +318,8 @@ typedef struct _indxInfo
        char       *indexdef;
        char       *tablespace;         /* tablespace in which index is stored */
        char       *indreloptions;      /* options specified by WITH (...) */
-       int                     indnkeyattrs;   /* number of index key attributes*/
-       int                     indnattrs;              /* total number of index attributes*/
-       Oid                *indkeys;            /* In spite of the name 'indkeys' this field
-                                                                * contains both key and nonkey attributes*/
+       int                     indnkeys;
+       Oid                *indkeys;
        bool            indisclustered;
        bool            indisreplident;
        /* if there is an associated constraint object, its dumpId: */
index 17e652c61b0b96939ed519c8ab642f528c0f3f4b..35f1061b3a19ae4f2543b94d69ff4dae1fe21b0b 100644 (file)
@@ -142,8 +142,6 @@ typedef struct IndexAmRoutine
        bool            amclusterable;
        /* does AM handle predicate locks? */
        bool            ampredlocks;
-       /* does AM support columns included with clause INCLUDING? */
-       bool            amcaninclude;
        /* type of data stored in index, or InvalidOid if variable */
        Oid                     amkeytype;
 
index b5424c396add0817e410d75e98f28b82fa60a520..8350fa00849f1d26b2898edf0e332401f226fbce 100644 (file)
@@ -18,7 +18,6 @@
 #include "access/tupmacs.h"
 #include "storage/bufpage.h"
 #include "storage/itemptr.h"
-#include "utils/rel.h"
 
 /*
  * Index tuple header structure
@@ -148,6 +147,5 @@ extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
 extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
                                   Datum *values, bool *isnull);
 extern IndexTuple CopyIndexTuple(IndexTuple source);
-extern IndexTuple index_truncate_tuple(Relation idxrel, IndexTuple olditup);
 
 #endif   /* ITUP_H */
index 79039df40a8905d751df13a43d105ed4375582c1..9046b166bd9a56262f9cd02fd22b5a365307b64b 100644 (file)
@@ -683,8 +683,7 @@ extern bool _bt_doinsert(Relation rel, IndexTuple itup,
                         IndexUniqueCheck checkUnique, Relation heapRel);
 extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access);
 extern void _bt_finish_split(Relation rel, Buffer bbuf, BTStack stack);
-extern bool _bt_pgaddtup(Page page, Size itemsize, IndexTuple itup,
-                        OffsetNumber itup_off);
+
 /*
  * prototypes for functions in nbtpage.c
  */
index d8556cedf0ea6627721f65bfca84fc0572fe81b4..6d254ba133cf42e225cd75e9daf03afa5774c37c 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201604081
+#define CATALOG_VERSION_NO     201604071
 
 #endif
index bff2fd175b6a5d0510ea8767e78b72c6327ceebd..666b2304bf8b2a27653ad786a39cf09edb1d06ca 100644 (file)
@@ -98,12 +98,6 @@ CATALOG(pg_constraint,2606)
         */
        int16           conkey[1];
 
-       /*
-        * Columns of conrelid that the constraint does not apply to,
-        * but included into the same index with key columns.
-        */
-       int16           conincluding[1];
-
        /*
         * If a foreign key, the referenced columns of confrelid
         */
@@ -156,7 +150,7 @@ typedef FormData_pg_constraint *Form_pg_constraint;
  *             compiler constants for pg_constraint
  * ----------------
  */
-#define Natts_pg_constraint                                    25
+#define Natts_pg_constraint                                    24
 #define Anum_pg_constraint_conname                     1
 #define Anum_pg_constraint_connamespace                2
 #define Anum_pg_constraint_contype                     3
@@ -174,14 +168,13 @@ typedef FormData_pg_constraint *Form_pg_constraint;
 #define Anum_pg_constraint_coninhcount         15
 #define Anum_pg_constraint_connoinherit                16
 #define Anum_pg_constraint_conkey                      17
-#define Anum_pg_constraint_conincluding                18
-#define Anum_pg_constraint_confkey                     19
-#define Anum_pg_constraint_conpfeqop           20
-#define Anum_pg_constraint_conppeqop           21
-#define Anum_pg_constraint_conffeqop           22
-#define Anum_pg_constraint_conexclop           23
-#define Anum_pg_constraint_conbin                      24
-#define Anum_pg_constraint_consrc                      25
+#define Anum_pg_constraint_confkey                     18
+#define Anum_pg_constraint_conpfeqop           19
+#define Anum_pg_constraint_conppeqop           20
+#define Anum_pg_constraint_conffeqop           21
+#define Anum_pg_constraint_conexclop           22
+#define Anum_pg_constraint_conbin                      23
+#define Anum_pg_constraint_consrc                      24
 
 /* ----------------
  *             initial contents of pg_constraint
index 72f4502f990cb00fbd5a8743e7ab8897da723f17..1f1117421022f4e3629e492af9164650b7e30312 100644 (file)
@@ -27,31 +27,30 @@ typedef enum ConstraintCategory
        CONSTRAINT_ASSERTION            /* for future expansion */
 } ConstraintCategory;
 
-extern Oid CreateConstraintEntry(const charconstraintName,
+extern Oid CreateConstraintEntry(const char *constraintName,
                                          Oid constraintNamespace,
                                          char constraintType,
                                          bool isDeferrable,
                                          bool isDeferred,
                                          bool isValidated,
                                          Oid relId,
-                                         const int16constraintKey,
+                                         const int16 *constraintKey,
                                          int constraintNKeys,
-                                         int constraintNTotalKeys,
                                          Oid domainId,
                                          Oid indexRelId,
                                          Oid foreignRelId,
-                                         const int16foreignKey,
-                                         const OidpfEqOp,
-                                         const OidppEqOp,
-                                         const OidffEqOp,
+                                         const int16 *foreignKey,
+                                         const Oid *pfEqOp,
+                                         const Oid *ppEqOp,
+                                         const Oid *ffEqOp,
                                          int foreignNKeys,
                                          char foreignUpdateType,
                                          char foreignDeleteType,
                                          char foreignMatchType,
-                                         const OidexclOp,
-                                         NodeconExpr,
-                                         const charconBin,
-                                         const charconSrc,
+                                         const Oid *exclOp,
+                                         Node *conExpr,
+                                         const char *conBin,
+                                         const char *conSrc,
                                          bool conIsLocal,
                                          int conInhCount,
                                          bool conNoInherit,
index fcbd18ab5890e72b67d6322d771eeea651e2083e..ee97c5dec836ad82c5b75440fcba51d4c106fc33 100644 (file)
@@ -32,8 +32,7 @@ CATALOG(pg_index,2610) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO
 {
        Oid                     indexrelid;             /* OID of the index */
        Oid                     indrelid;               /* OID of the relation it indexes */
-       int16           indnatts;               /* total number of columns in index */
-       int16           indnkeyatts;    /* number of key columns in index */
+       int16           indnatts;               /* number of columns in index */
        bool            indisunique;    /* is this a unique index? */
        bool            indisprimary;   /* is this index for primary key? */
        bool            indisexclusion; /* is this index for exclusion constraint? */
@@ -71,27 +70,26 @@ typedef FormData_pg_index *Form_pg_index;
  *             compiler constants for pg_index
  * ----------------
  */
-#define Natts_pg_index                                 20
+#define Natts_pg_index                                 19
 #define Anum_pg_index_indexrelid               1
 #define Anum_pg_index_indrelid                 2
 #define Anum_pg_index_indnatts                 3
-#define Anum_pg_index_indnkeyatts              4
-#define Anum_pg_index_indisunique              5
-#define Anum_pg_index_indisprimary             6
-#define Anum_pg_index_indisexclusion   7
-#define Anum_pg_index_indimmediate             8
-#define Anum_pg_index_indisclustered   9
-#define Anum_pg_index_indisvalid               10
-#define Anum_pg_index_indcheckxmin             11
-#define Anum_pg_index_indisready               12
-#define Anum_pg_index_indislive                        13
-#define Anum_pg_index_indisreplident   14
-#define Anum_pg_index_indkey                   15
-#define Anum_pg_index_indcollation             16
-#define Anum_pg_index_indclass                 17
-#define Anum_pg_index_indoption                        18
-#define Anum_pg_index_indexprs                 19
-#define Anum_pg_index_indpred                  20
+#define Anum_pg_index_indisunique              4
+#define Anum_pg_index_indisprimary             5
+#define Anum_pg_index_indisexclusion   6
+#define Anum_pg_index_indimmediate             7
+#define Anum_pg_index_indisclustered   8
+#define Anum_pg_index_indisvalid               9
+#define Anum_pg_index_indcheckxmin             10
+#define Anum_pg_index_indisready               11
+#define Anum_pg_index_indislive                        12
+#define Anum_pg_index_indisreplident   13
+#define Anum_pg_index_indkey                   14
+#define Anum_pg_index_indcollation             15
+#define Anum_pg_index_indclass                 16
+#define Anum_pg_index_indoption                        17
+#define Anum_pg_index_indexprs                 18
+#define Anum_pg_index_indpred                  19
 
 /*
  * Index AMs that support ordered scans must support these two indoption
index e5df6da6585596aecfc7ae2dc9e688128cb76d78..dbec07e5a375cbf235feddf5dc6c8120f23bb53f 100644 (file)
  *             entries for a particular index.  Used for both index_build and
  *             retail creation of index entries.
  *
- *             NumIndexAttrs           total number of columns in this index
- *             NumIndexKeyAttrs        number of key columns in index
+ *             NumIndexAttrs           number of columns in this index
  *             KeyAttrNumbers          underlying-rel attribute numbers used as keys
- *                                                     (zeroes indicate expressions). It also contains
- *                                                     info about included columns.
+ *                                                     (zeroes indicate expressions)
  *             Expressions                     expr trees for expression entries, or NIL if none
  *             ExpressionsState        exec state for expressions, or NIL if none
  *             Predicate                       partial-index predicate, or NIL if none
@@ -60,8 +58,7 @@
 typedef struct IndexInfo
 {
        NodeTag         type;
-       int                     ii_NumIndexAttrs; /* total number of columns in index */
-       int                     ii_NumIndexKeyAttrs; /* number of key columns in index */
+       int                     ii_NumIndexAttrs;
        AttrNumber      ii_KeyAttrNumbers[INDEX_MAX_KEYS];
        List       *ii_Expressions; /* list of Expr */
        List       *ii_ExpressionsState;        /* list of ExprState */
index 7038ebb804a953fb32e608499adb467823d12b47..714cf1550fd1e158cd88786c2e8576dccd18eeb4 100644 (file)
@@ -1835,8 +1835,7 @@ typedef struct Constraint
        char       *cooked_expr;        /* expr, as nodeToString representation */
 
        /* Fields used for unique constraints (UNIQUE and PRIMARY KEY): */
-       List       *keys;                       /* String nodes naming referenced key column(s) */
-       List       *including;          /* String nodes naming referenced nonkey column(s) */
+       List       *keys;                       /* String nodes naming referenced column(s) */
 
        /* Fields used for EXCLUSION constraints: */
        List       *exclusions;         /* list of (IndexElem, operator name) pairs */
@@ -2440,8 +2439,6 @@ typedef struct IndexStmt
        char       *accessMethod;       /* name of access method (eg. btree) */
        char       *tableSpace;         /* tablespace, or NULL for default */
        List       *indexParams;        /* columns to index: a list of IndexElem */
-       List       *indexIncludingParams;       /* additional columns to index:
-                                                                                * a list of IndexElem */
        List       *options;            /* WITH clause options: a list of DefElem */
        Node       *whereClause;        /* qualification (partial-index predicate) */
        List       *excludeOpNames; /* exclusion operator names, or NIL if none */
index 9bfeedaf5715e5d4d0b20f35622da24949aeeea0..e9dfb663c203a5938d5de7d2f8e3fc86d78f2cc7 100644 (file)
@@ -545,12 +545,11 @@ typedef struct RelOptInfo
  * IndexOptInfo
  *             Per-index information for planning/optimization
  *
- *             indexkeys[], indexcollations[] each have ncolumns entries.
- *             opfamily[], and opcintype[]     each have nkeycolumns entries. They do
- *             not contain any information about included attributes.
+ *             indexkeys[], indexcollations[], opfamily[], and opcintype[]
+ *             each have ncolumns entries.
  *
- *             sortopfamily[], reverse_sort[], and nulls_first[] have
- *             nkeycolumns entries, if the index is ordered; but if it is unordered,
+ *             sortopfamily[], reverse_sort[], and nulls_first[] likewise have
+ *             ncolumns entries, if the index is ordered; but if it is unordered,
  *             those pointers are NULL.
  *
  *             Zeroes in the indexkeys[] array indicate index columns that are
@@ -587,9 +586,7 @@ typedef struct IndexOptInfo
 
        /* index descriptor information */
        int                     ncolumns;               /* number of columns in index */
-       int                     nkeycolumns;    /* number of key columns in index */
-       int                *indexkeys;          /* column numbers of index's attributes
-                                                                * both key and included columns, or 0 */
+       int                *indexkeys;          /* column numbers of index's keys, or 0 */
        Oid                *indexcollations;    /* OIDs of collations of index columns */
        Oid                *opfamily;           /* OIDs of operator families for columns */
        Oid                *opcintype;          /* OIDs of opclass declared input data types */
index 6ff4b2c5eae56438e823272c6595109b3106b7e3..c7582c2a11ca27ab476a2f652e8a6bf3c8b366dc 100644 (file)
@@ -341,24 +341,10 @@ typedef struct ViewOptions
 
 /*
  * RelationGetNumberOfAttributes
- *             Returns the total number of attributes in a relation.
+ *             Returns the number of attributes in a relation.
  */
 #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts)
 
-/*
- * IndexRelationGetNumberOfAttributes
- *             Returns the number of attributes in an index.
- */
-#define IndexRelationGetNumberOfAttributes(relation) \
-               ((relation)->rd_index->indnatts)
-
-/*
- * IndexRelationGetNumberOfKeyAttributes
- *             Returns the number of key attributes in an index.
- */
-#define IndexRelationGetNumberOfKeyAttributes(relation) \
-               ((relation)->rd_index->indnkeyatts)
-
 /*
  * RelationGetDescr
  *             Returns tuple descriptor for a relation.
index 02488df2d9dcfa1f06f8c9c8ceaf58db663271a9..b72e65d1bd086baac657414f4e71aa9bf7fa6b48 100644 (file)
@@ -2376,25 +2376,6 @@ DETAIL:  Key ((f1 || f2))=(ABCDEF) already exists.
 -- but this shouldn't:
 INSERT INTO func_index_heap VALUES('QWERTY');
 --
--- Test unique index with included columns
---
-CREATE TABLE covering_index_heap (f1 int, f2 int, f3 text);
-CREATE UNIQUE INDEX covering_index_index on covering_index_heap (f1,f2) INCLUDING(f3);
-INSERT INTO covering_index_heap VALUES(1,1,'AAA');
-INSERT INTO covering_index_heap VALUES(1,2,'AAA');
--- this should fail because of unique index on f1,f2:
-INSERT INTO covering_index_heap VALUES(1,2,'BBB');
-ERROR:  duplicate key value violates unique constraint "covering_index_index"
-DETAIL:  Key (f1, f2)=(1, 2) already exists.
--- and this shouldn't:
-INSERT INTO covering_index_heap VALUES(1,4,'AAA');
--- Try to build index on table that already contains data
-CREATE UNIQUE INDEX covering_pkey on covering_index_heap (f1,f2) INCLUDING(f3);
--- Try to use existing covering index as primary key
-ALTER TABLE covering_index_heap ADD CONSTRAINT covering_pkey PRIMARY KEY USING INDEX
-covering_pkey;
-DROP TABLE covering_index_heap;
---
 -- Also try building functional, expressional, and partial indexes on
 -- tables that already contain data.
 --
diff --git a/src/test/regress/expected/index_including.out b/src/test/regress/expected/index_including.out
deleted file mode 100644 (file)
index 1199671..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * 1.test CREATE INDEX
- */
- -- Regular index with included columns
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDING (c3,c4);
--- must fail because of intersection of key and included columns
-CREATE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDING (c1,c3);
-ERROR:  included columns must not intersect with key columns
-DROP TABLE tbl;
--- Unique index and unique constraint
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDING (c3,c4);
-ALTER TABLE tbl add UNIQUE USING INDEX tbl_idx_unique;
-ALTER TABLE tbl add UNIQUE(c1, c2) INCLUDING (c3, c4);
-DROP TABLE tbl;
--- Unique index and unique constraint. Both must fail.
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDING (c3,c4);
-ERROR:  could not create unique index "tbl_idx_unique"
-DETAIL:  Key (c1, c2)=(1, 2) is duplicated.
-ALTER TABLE tbl add UNIQUE(c1, c2) INCLUDING (c3, c4);
-ERROR:  could not create unique index "tbl_c1_c2_c3_c4_key"
-DETAIL:  Key (c1, c2)=(1, 2) is duplicated.
-DROP TABLE tbl;
--- PK constraint
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ALTER TABLE tbl add PRIMARY KEY(c1, c2) INCLUDING (c3, c4);
-ERROR:  could not create unique index "tbl_pkey"
-DETAIL:  Key (c1, c2)=(1, 2) is duplicated.
-DROP TABLE tbl;
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDING (c3,c4);
-ERROR:  could not create unique index "tbl_idx_unique"
-DETAIL:  Key (c1, c2)=(1, 2) is duplicated.
-ALTER TABLE tbl add PRIMARY KEY USING INDEX tbl_idx_unique;
-ERROR:  index "tbl_idx_unique" does not exist
-LINE 1: ALTER TABLE tbl add PRIMARY KEY USING INDEX tbl_idx_unique;
-                            ^
-DROP TABLE tbl;
--- PK constraint. Must fail.
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ALTER TABLE tbl add PRIMARY KEY(c1, c2) INCLUDING (c3, c4);
-ERROR:  could not create unique index "tbl_pkey"
-DETAIL:  Key (c1, c2)=(1, 2) is duplicated.
-DROP TABLE tbl;
-/*
- * 2. Test CREATE TABLE with constraint
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
-                               CONSTRAINT covering UNIQUE(c1,c2) INCLUDING(c3,c4));
-select indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass from pg_index where indrelid = 'tbl'::regclass::oid;
- indexrelid | indnatts | indnkeyatts | indisunique | indisprimary | indkey  | indclass  
-------------+----------+-------------+-------------+--------------+---------+-----------
- covering   |        4 |           2 | t           | f            | 1 2 3 4 | 1978 1978
-(1 row)
-
-select pg_get_constraintdef(oid), conname, conkey, conincluding from pg_constraint where conrelid = 'tbl'::regclass::oid;
-        pg_get_constraintdef        | conname  | conkey | conincluding 
-------------------------------------+----------+--------+--------------
- UNIQUE (c1, c2) INCLUDING (c3, c4) | covering | {1,2}  | {3,4}
-(1 row)
-
--- ensure that constraint works
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ERROR:  duplicate key value violates unique constraint "covering"
-DETAIL:  Key (c1, c2)=(1, 2) already exists.
-DROP TABLE tbl;
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
-                               CONSTRAINT covering PRIMARY KEY(c1,c2) INCLUDING(c3,c4));
-select indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass from pg_index where indrelid = 'tbl'::regclass::oid;
- indexrelid | indnatts | indnkeyatts | indisunique | indisprimary | indkey  | indclass  
-------------+----------+-------------+-------------+--------------+---------+-----------
- covering   |        4 |           2 | t           | t            | 1 2 3 4 | 1978 1978
-(1 row)
-
-select pg_get_constraintdef(oid), conname, conkey, conincluding from pg_constraint where conrelid = 'tbl'::regclass::oid;
-          pg_get_constraintdef           | conname  | conkey | conincluding 
------------------------------------------+----------+--------+--------------
- PRIMARY KEY (c1, c2) INCLUDING (c3, c4) | covering | {1,2}  | {3,4}
-(1 row)
-
--- ensure that constraint works
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ERROR:  duplicate key value violates unique constraint "covering"
-DETAIL:  Key (c1, c2)=(1, 2) already exists.
-INSERT INTO tbl select 1, NULL, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ERROR:  null value in column "c2" violates not-null constraint
-DETAIL:  Failing row contains (1, null, 3, (4,4),(4,4)).
-INSERT INTO tbl select x, 2*x, NULL, NULL from generate_series(1,10) as x;
-DROP TABLE tbl;
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
-                               UNIQUE(c1,c2) INCLUDING(c3,c4));
-select indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass from pg_index where indrelid = 'tbl'::regclass::oid;
-     indexrelid      | indnatts | indnkeyatts | indisunique | indisprimary | indkey  | indclass  
----------------------+----------+-------------+-------------+--------------+---------+-----------
- tbl_c1_c2_c3_c4_key |        4 |           2 | t           | f            | 1 2 3 4 | 1978 1978
-(1 row)
-
-select pg_get_constraintdef(oid), conname, conkey, conincluding from pg_constraint where conrelid = 'tbl'::regclass::oid;
-        pg_get_constraintdef        |       conname       | conkey | conincluding 
-------------------------------------+---------------------+--------+--------------
- UNIQUE (c1, c2) INCLUDING (c3, c4) | tbl_c1_c2_c3_c4_key | {1,2}  | {3,4}
-(1 row)
-
--- ensure that constraint works
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ERROR:  duplicate key value violates unique constraint "tbl_c1_c2_c3_c4_key"
-DETAIL:  Key (c1, c2)=(1, 2) already exists.
-DROP TABLE tbl;
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
-                               PRIMARY KEY(c1,c2) INCLUDING(c3,c4));
-select indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass from pg_index where indrelid = 'tbl'::regclass::oid;
- indexrelid | indnatts | indnkeyatts | indisunique | indisprimary | indkey  | indclass  
-------------+----------+-------------+-------------+--------------+---------+-----------
- tbl_pkey   |        4 |           2 | t           | t            | 1 2 3 4 | 1978 1978
-(1 row)
-
-select pg_get_constraintdef(oid), conname, conkey, conincluding from pg_constraint where conrelid = 'tbl'::regclass::oid;
-          pg_get_constraintdef           | conname  | conkey | conincluding 
------------------------------------------+----------+--------+--------------
- PRIMARY KEY (c1, c2) INCLUDING (c3, c4) | tbl_pkey | {1,2}  | {3,4}
-(1 row)
-
--- ensure that constraint works
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ERROR:  duplicate key value violates unique constraint "tbl_pkey"
-DETAIL:  Key (c1, c2)=(1, 2) already exists.
-INSERT INTO tbl select 1, NULL, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ERROR:  null value in column "c2" violates not-null constraint
-DETAIL:  Failing row contains (1, null, 3, (4,4),(4,4)).
-INSERT INTO tbl select x, 2*x, NULL, NULL from generate_series(1,10) as x;
-DROP TABLE tbl;
-/*
- * 3.0 Test ALTER TABLE DROP COLUMN.
- * Any column deletion leads to index deletion.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 int);
-CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2, c3, c4);
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-                            indexdef                             
------------------------------------------------------------------
- CREATE UNIQUE INDEX tbl_idx ON tbl USING btree (c1, c2, c3, c4)
-(1 row)
-
-ALTER TABLE tbl DROP COLUMN c3;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
- indexdef 
-----------
-(0 rows)
-
-DROP TABLE tbl;
-/*
- * 3.1 Test ALTER TABLE DROP COLUMN.
- * Included column deletion leads to the index deletion,
- * as well as key columns deletion. It's explained in documentation.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box);
-CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDING(c3,c4);
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-                                  indexdef                                  
-----------------------------------------------------------------------------
- CREATE UNIQUE INDEX tbl_idx ON tbl USING btree (c1, c2) INCLUDING (c3, c4)
-(1 row)
-
-ALTER TABLE tbl DROP COLUMN c3;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
- indexdef 
-----------
-(0 rows)
-
-DROP TABLE tbl;
-/*
- * 3.2 Test ALTER TABLE DROP COLUMN.
- * Included column deletion leads to the index deletion.
- * as well as key columns deletion. It's explained in documentation.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDING(c3,c4));
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-                                        indexdef                                        
-----------------------------------------------------------------------------------------
- CREATE UNIQUE INDEX tbl_c1_c2_c3_c4_key ON tbl USING btree (c1, c2) INCLUDING (c3, c4)
-(1 row)
-
-ALTER TABLE tbl DROP COLUMN c3;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
- indexdef 
-----------
-(0 rows)
-
-ALTER TABLE tbl DROP COLUMN c1;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
- indexdef 
-----------
-(0 rows)
-
-DROP TABLE tbl;
-/*
- * 4. CREATE INDEX CONCURRENTLY
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDING(c3,c4));
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,1000) as x;
-CREATE UNIQUE INDEX CONCURRENTLY on tbl (c1, c2) INCLUDING (c3, c4);
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-                                        indexdef                                        
-----------------------------------------------------------------------------------------
- CREATE UNIQUE INDEX tbl_c1_c2_c3_c4_idx ON tbl USING btree (c1, c2) INCLUDING (c3, c4)
- CREATE UNIQUE INDEX tbl_c1_c2_c3_c4_key ON tbl USING btree (c1, c2) INCLUDING (c3, c4)
-(2 rows)
-
-DROP TABLE tbl;
-/*
- * 5. REINDEX
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDING(c3,c4));
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-                                        indexdef                                        
-----------------------------------------------------------------------------------------
- CREATE UNIQUE INDEX tbl_c1_c2_c3_c4_key ON tbl USING btree (c1, c2) INCLUDING (c3, c4)
-(1 row)
-
-ALTER TABLE tbl DROP COLUMN c3;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
- indexdef 
-----------
-(0 rows)
-
-REINDEX INDEX tbl_c1_c2_c3_c4_key;
-ERROR:  relation "tbl_c1_c2_c3_c4_key" does not exist
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
- indexdef 
-----------
-(0 rows)
-
-ALTER TABLE tbl DROP COLUMN c1;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
- indexdef 
-----------
-(0 rows)
-
-DROP TABLE tbl;
-/*
- * 7. Check various AMs. All but brtee must fail.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 box, c4 box);
-CREATE INDEX on tbl USING brin(c1, c2) INCLUDING (c3, c4);
-ERROR:  access method "brin" does not support included columns
-CREATE INDEX on tbl USING gist(c3) INCLUDING (c4);
-ERROR:  access method "gist" does not support included columns
-CREATE INDEX on tbl USING spgist(c3) INCLUDING (c4);
-ERROR:  access method "spgist" does not support included columns
-CREATE INDEX on tbl USING gin(c1, c2) INCLUDING (c3, c4);
-ERROR:  access method "gin" does not support included columns
-CREATE INDEX on tbl USING hash(c1, c2) INCLUDING (c3, c4);
-WARNING:  hash indexes are not WAL-logged and their use is discouraged
-ERROR:  access method "hash" does not support included columns
-CREATE INDEX on tbl USING rtree(c1, c2) INCLUDING (c3, c4);
-NOTICE:  substituting access method "gist" for obsolete method "rtree"
-ERROR:  access method "gist" does not support included columns
-CREATE INDEX on tbl USING btree(c1, c2) INCLUDING (c3, c4);
-DROP TABLE tbl;
-/*
- * 8. Update, delete values in indexed table.
- */
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDING (c3,c4);
-UPDATE tbl SET c1 = 100 WHERE c1 = 2;
-UPDATE tbl SET c1 = 1 WHERE c1 = 3;
--- should fail
-UPDATE tbl SET c2 = 2 WHERE c1 = 1;
-ERROR:  duplicate key value violates unique constraint "tbl_idx_unique"
-DETAIL:  Key (c1, c2)=(1, 2) already exists.
-UPDATE tbl SET c3 = 1;
-DELETE FROM tbl WHERE c1 = 5 OR c3 = 12;
-DROP TABLE tbl;
-/*
- * 9. Alter column type.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDING(c3,c4));
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ALTER TABLE tbl ALTER c1 TYPE bigint;
-ALTER TABLE tbl ALTER c3 TYPE bigint;
-\d tbl
-      Table "public.tbl"
- Column |  Type   | Modifiers 
---------+---------+-----------
- c1     | bigint  | 
- c2     | integer | 
- c3     | bigint  | 
- c4     | box     | 
-Indexes:
-    "tbl_c1_c2_c3_c4_key" UNIQUE CONSTRAINT, btree (c1, c2) INCLUDING (c3, c4)
-
-DROP TABLE tbl;
index e6726b84bf0240f79495bb7c7d644a3a518044aa..6c1f21bb6273eaed424c28d59c146445820c23b6 100644 (file)
@@ -55,7 +55,7 @@ test: copy copyselect copydml
 # ----------
 test: create_misc create_operator
 # These depend on the above two
-test: create_index create_view index_including
+test: create_index create_view
 
 # ----------
 # Another group of parallel tests
index 109c37de8e8b41f63e8fe82d5f8e4af343151872..8269c524dc618077738109c44afe778b3873dcc7 100644 (file)
@@ -61,7 +61,6 @@ test: copydml
 test: create_misc
 test: create_operator
 test: create_index
-test: index_including
 test: create_view
 test: create_aggregate
 test: create_function_3
index 37371575634c87bdc7a6b9a65d099192e9f7f23a..ff8695361ce65a79855a9a4fa7313584886eb911 100644 (file)
@@ -721,26 +721,6 @@ INSERT INTO func_index_heap VALUES('ABCD', 'EF');
 -- but this shouldn't:
 INSERT INTO func_index_heap VALUES('QWERTY');
 
---
--- Test unique index with included columns
---
-CREATE TABLE covering_index_heap (f1 int, f2 int, f3 text);
-CREATE UNIQUE INDEX covering_index_index on covering_index_heap (f1,f2) INCLUDING(f3);
-
-INSERT INTO covering_index_heap VALUES(1,1,'AAA');
-INSERT INTO covering_index_heap VALUES(1,2,'AAA');
--- this should fail because of unique index on f1,f2:
-INSERT INTO covering_index_heap VALUES(1,2,'BBB');
--- and this shouldn't:
-INSERT INTO covering_index_heap VALUES(1,4,'AAA');
--- Try to build index on table that already contains data
-CREATE UNIQUE INDEX covering_pkey on covering_index_heap (f1,f2) INCLUDING(f3);
--- Try to use existing covering index as primary key
-ALTER TABLE covering_index_heap ADD CONSTRAINT covering_pkey PRIMARY KEY USING INDEX
-covering_pkey;
-DROP TABLE covering_index_heap;
-
-
 --
 -- Also try building functional, expressional, and partial indexes on
 -- tables that already contain data.
diff --git a/src/test/regress/sql/index_including.sql b/src/test/regress/sql/index_including.sql
deleted file mode 100644 (file)
index c4c61c5..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 1.test CREATE INDEX
- */
- -- Regular index with included columns
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDING (c3,c4);
--- must fail because of intersection of key and included columns
-CREATE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDING (c1,c3);
-DROP TABLE tbl;
-
--- Unique index and unique constraint
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDING (c3,c4);
-ALTER TABLE tbl add UNIQUE USING INDEX tbl_idx_unique;
-ALTER TABLE tbl add UNIQUE(c1, c2) INCLUDING (c3, c4);
-DROP TABLE tbl;
-
--- Unique index and unique constraint. Both must fail.
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDING (c3,c4);
-ALTER TABLE tbl add UNIQUE(c1, c2) INCLUDING (c3, c4);
-DROP TABLE tbl;
-
--- PK constraint
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ALTER TABLE tbl add PRIMARY KEY(c1, c2) INCLUDING (c3, c4);
-DROP TABLE tbl;
-
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDING (c3,c4);
-ALTER TABLE tbl add PRIMARY KEY USING INDEX tbl_idx_unique;
-DROP TABLE tbl;
--- PK constraint. Must fail.
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ALTER TABLE tbl add PRIMARY KEY(c1, c2) INCLUDING (c3, c4);
-DROP TABLE tbl;
-
-
-/*
- * 2. Test CREATE TABLE with constraint
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
-                               CONSTRAINT covering UNIQUE(c1,c2) INCLUDING(c3,c4));
-select indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass from pg_index where indrelid = 'tbl'::regclass::oid;
-select pg_get_constraintdef(oid), conname, conkey, conincluding from pg_constraint where conrelid = 'tbl'::regclass::oid;
--- ensure that constraint works
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-DROP TABLE tbl;
-
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
-                               CONSTRAINT covering PRIMARY KEY(c1,c2) INCLUDING(c3,c4));
-select indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass from pg_index where indrelid = 'tbl'::regclass::oid;
-select pg_get_constraintdef(oid), conname, conkey, conincluding from pg_constraint where conrelid = 'tbl'::regclass::oid;
--- ensure that constraint works
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-INSERT INTO tbl select 1, NULL, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-INSERT INTO tbl select x, 2*x, NULL, NULL from generate_series(1,10) as x;
-DROP TABLE tbl;
-
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
-                               UNIQUE(c1,c2) INCLUDING(c3,c4));
-select indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass from pg_index where indrelid = 'tbl'::regclass::oid;
-select pg_get_constraintdef(oid), conname, conkey, conincluding from pg_constraint where conrelid = 'tbl'::regclass::oid;
--- ensure that constraint works
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-DROP TABLE tbl;
-
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
-                               PRIMARY KEY(c1,c2) INCLUDING(c3,c4));
-select indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass from pg_index where indrelid = 'tbl'::regclass::oid;
-select pg_get_constraintdef(oid), conname, conkey, conincluding from pg_constraint where conrelid = 'tbl'::regclass::oid;
--- ensure that constraint works
-INSERT INTO tbl select 1, 2, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-INSERT INTO tbl select 1, NULL, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-INSERT INTO tbl select x, 2*x, NULL, NULL from generate_series(1,10) as x;
-DROP TABLE tbl;
-
-
-/*
- * 3.0 Test ALTER TABLE DROP COLUMN.
- * Any column deletion leads to index deletion.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 int);
-CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2, c3, c4);
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-ALTER TABLE tbl DROP COLUMN c3;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-DROP TABLE tbl;
-
-/*
- * 3.1 Test ALTER TABLE DROP COLUMN.
- * Included column deletion leads to the index deletion,
- * as well as key columns deletion. It's explained in documentation.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box);
-CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDING(c3,c4);
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-ALTER TABLE tbl DROP COLUMN c3;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-DROP TABLE tbl;
-
-/*
- * 3.2 Test ALTER TABLE DROP COLUMN.
- * Included column deletion leads to the index deletion.
- * as well as key columns deletion. It's explained in documentation.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDING(c3,c4));
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-ALTER TABLE tbl DROP COLUMN c3;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-ALTER TABLE tbl DROP COLUMN c1;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-DROP TABLE tbl;
-
-
-/*
- * 4. CREATE INDEX CONCURRENTLY
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDING(c3,c4));
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,1000) as x;
-CREATE UNIQUE INDEX CONCURRENTLY on tbl (c1, c2) INCLUDING (c3, c4);
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-DROP TABLE tbl;
-
-
-/*
- * 5. REINDEX
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDING(c3,c4));
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-ALTER TABLE tbl DROP COLUMN c3;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-REINDEX INDEX tbl_c1_c2_c3_c4_key;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-ALTER TABLE tbl DROP COLUMN c1;
-select indexdef from pg_indexes where tablename = 'tbl' order by indexname;
-DROP TABLE tbl;
-
-/*
- * 7. Check various AMs. All but brtee must fail.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 box, c4 box);
-CREATE INDEX on tbl USING brin(c1, c2) INCLUDING (c3, c4);
-CREATE INDEX on tbl USING gist(c3) INCLUDING (c4);
-CREATE INDEX on tbl USING spgist(c3) INCLUDING (c4);
-CREATE INDEX on tbl USING gin(c1, c2) INCLUDING (c3, c4);
-CREATE INDEX on tbl USING hash(c1, c2) INCLUDING (c3, c4);
-CREATE INDEX on tbl USING rtree(c1, c2) INCLUDING (c3, c4);
-CREATE INDEX on tbl USING btree(c1, c2) INCLUDING (c3, c4);
-DROP TABLE tbl;
-
-/*
- * 8. Update, delete values in indexed table.
- */
-CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box);
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDING (c3,c4);
-UPDATE tbl SET c1 = 100 WHERE c1 = 2;
-UPDATE tbl SET c1 = 1 WHERE c1 = 3;
--- should fail
-UPDATE tbl SET c2 = 2 WHERE c1 = 1;
-UPDATE tbl SET c3 = 1;
-DELETE FROM tbl WHERE c1 = 5 OR c3 = 12;
-DROP TABLE tbl;
-
-/*
- * 9. Alter column type.
- */
-CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDING(c3,c4));
-INSERT INTO tbl select x, 2*x, 3*x, box('4,4,4,4') from generate_series(1,10) as x;
-ALTER TABLE tbl ALTER c1 TYPE bigint;
-ALTER TABLE tbl ALTER c3 TYPE bigint;
-\d tbl
-DROP TABLE tbl;
-