Revert CREATE INDEX ... INCLUDING ...
authorTeodor Sigaev
Fri, 8 Apr 2016 18:52:13 +0000 (21:52 +0300)
committerTeodor Sigaev
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)
       pg_class.relnatts)
      
 
-      
-      indnkeyatts
-      int2
-      
-      The number of key columns in the index. "Key columns" are ordinary
-      index columns in contrast with "included" columns.
-     
-
      
       indisunique
       bool
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 unique indexes, which are indexes that disallow
    multiple entries with identical keys.  An access method that supports this
    feature sets amcanunique true.
-   (At present, only B-tree supports it.) Columns which are present in the
-   INCLUDING clause are not used to enforce uniqueness.
+   (At present, only b-tree supports it.)
   
 
   
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.
 
-CREATE UNIQUE INDEX name ON table (column , ...)
-INCLUDING (column , ...);
+CREATE UNIQUE INDEX name ON table (column , ...);
 
    Currently, only B-tree indexes can be declared unique.
   
@@ -653,9 +652,7 @@ CREATE UNIQUE INDEX name ON table
    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
-   INCLUDING aren't used to enforce constraints (UNIQUE,
-   PRIMARY KEY, etc).
+   indexed columns are equal in multiple rows.
   
 
   
index 25b3c26f551195c387935939b12c7143325bbdeb..7dee4055dbc0bbcc468891bc54d269c212aa0621 100644 (file)
@@ -23,7 +23,6 @@ PostgreSQL documentation
 
 CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON table_name [ USING method ]
     ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
-    [ INCLUDING ( column_name [, ...] ) ]
     [ WITH ( storage_parameter = value [, ... ] ) ]
     [ TABLESPACE tablespace_name ]
     [ WHERE predicate ]
@@ -139,35 +138,6 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] 
       
      
 
-     
-      INCLUDING
-      
-       
-        An optional 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
-        INCLUDING columns exist solely to allow more queries to
-        benefit from 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 INCLUDING
-        clause in some cases allows PostgreSQL to skip the heap
-        read completely. This also allows UNIQUE indexes to be
-        defined on one set of columns, which can include another set of column
-        in the 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 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.
-       
-      
-     
-
      
       name
       
@@ -629,22 +599,13 @@ Indexes:
   Examples
 
   
-   To create a unique B-tree index on the column title in
+   To create a B-tree index on the column title in
    the table films:
 
 CREATE UNIQUE INDEX title_idx ON films (title);
 
   
 
-  
-   To create a unique B-tree index on the column title
-   and included columns director and rating
-   in the table films:
-
-CREATE UNIQUE INDEX title_idx ON films (title) INCLUDING (director, rating);
-
-  
-
   
    To create an index on the expression 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 constraint_name ]
 { CHECK ( expression ) [ NO INHERIT ] |
-  UNIQUE ( column_name [, ... ] ) index_parameters INCLUDING (column_name [, ...]) |
-  PRIMARY KEY ( column_name [, ... ] ) index_parameters INCLUDING (column_name [, ...]) |
+  UNIQUE ( column_name [, ... ] ) index_parameters |
+  PRIMARY KEY ( column_name [, ... ] ) index_parameters |
   EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] |
   FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
     [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }
@@ -476,8 +476,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
 
    
     UNIQUE (column constraint)
-    UNIQUE ( column_name [, ... ] )
-    INCLUDING ( column_name [, ...]) (table constraint)
+    UNIQUE ( column_name [, ... ] ) (table constraint)
+
     
      
       The UNIQUE 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.)
      
-
-     
-      Adding a unique constraint will automatically create a unique btree
-      index on the column or group of columns used in the constraint.
-      Optional clause INCLUDING 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. DROP COLUMN)
-      can cause cascade constraint and index deletion.
-      See paragraph about INCLUDING in
-       for more information.
-     
-
     
    
 
    
     PRIMARY KEY (column constraint)
-    PRIMARY KEY ( column_name [, ... ] )
-    INCLUDING ( column_name [, ...]) (table constraint)
+    PRIMARY KEY ( column_name [, ... ] ) (table constraint)
     
      
       The 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.
      
-
-     
-      Adding a PRIMARY KEY constraint will automatically create a unique btree
-      index on the column or group of columns used in the constraint.
-      Optional clause INCLUDING 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. DROP COLUMN)
-      can cause cascade constraint and index deletion.
-      See paragraph about INCLUDING in
-       for more information.
-     
     
    
 
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    group_by_list
 %type    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;
-