Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Remove pg_constraint.conincluding
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 3 Sep 2018 15:58:42 +0000 (12:58 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 3 Sep 2018 15:58:42 +0000 (12:58 -0300)
This column was added in commit 8224de4f42cc ("Indexes with INCLUDE
columns and their support in B-tree") to ease writing the ruleutils.c
supporting code for that feature, but it turns out to be unnecessary --
we can do the same thing with just one more syscache lookup.

Even the documentation for the new column being removed in this commit
is awkward.

Discussion: https://postgr.es/m/20180902165018.33otxftp3olgtu4t@alvherre.pgsql

doc/src/sgml/catalogs.sgml
src/backend/catalog/pg_constraint.c
src/backend/utils/adt/ruleutils.c
src/include/catalog/catversion.h
src/include/catalog/pg_constraint.h
src/test/regress/expected/index_including.out
src/test/regress/sql/index_including.sql

index 07e8b3325f37d580c4b252172d73382ecd08b404..0179deea2e04d5b6a681619a3122efb5e79cbf42 100644 (file)
@@ -2373,14 +2373,6 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
        triggers), list of the constrained columns</entry>
      </row>
 
-     <row>
-      <entry><structfield>conincluding</structfield></entry>
-      <entry><type>int2[]</type></entry>
-      <entry><literal><link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.attnum</literal></entry>
-      <entry>List of the non-constrained columns which are included into
-        the same index as the constrained columns</entry>
-     </row>
-
      <row>
       <entry><structfield>confkey</structfield></entry>
       <entry><type>int2[]</type></entry>
index 7a6d158f898c647291f96e319ccb14a344d660af..ea84441360828e40a8506259f4fcfdc9081a4c78 100644 (file)
@@ -85,7 +85,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;
@@ -116,21 +115,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;
@@ -204,11 +188,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
index 03e9a28a63b7ce390141e2ea2bc5cb629502fe14..5cce3f12420186b38ecee4aff4656fc242118042 100644 (file)
@@ -315,7 +315,7 @@ static char *deparse_expression_pretty(Node *expr, List *dpcontext,
 static char *pg_get_viewdef_worker(Oid viewoid,
                      int prettyFlags, int wrapColumn);
 static char *pg_get_triggerdef_worker(Oid trigid, bool pretty);
-static void decompile_column_index_array(Datum column_index_array, Oid relId,
+static int decompile_column_index_array(Datum column_index_array, Oid relId,
                             StringInfo buf);
 static char *pg_get_ruledef_worker(Oid ruleoid, int prettyFlags);
 static char *pg_get_indexdef_worker(Oid indexrelid, int colno,
@@ -2055,6 +2055,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
                Datum       val;
                bool        isnull;
                Oid         indexId;
+               int         keyatts;
+               HeapTuple   indtup;
 
                /* Start off the constraint definition */
                if (conForm->contype == CONSTRAINT_PRIMARY)
@@ -2069,24 +2071,52 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
                    elog(ERROR, "null conkey for constraint %u",
                         constraintId);
 
-               decompile_column_index_array(val, conForm->conrelid, &buf);
+               keyatts = decompile_column_index_array(val, conForm->conrelid, &buf);
 
                appendStringInfoChar(&buf, ')');
 
-               /* Fetch and build including column list */
-               isnull = true;
-               val = SysCacheGetAttr(CONSTROID, tup,
-                                     Anum_pg_constraint_conincluding, &isnull);
-               if (!isnull)
+               indexId = get_constraint_index(constraintId);
+
+               /* Build including column list (from pg_index.indkeys) */
+               indtup = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId));
+               if (!HeapTupleIsValid(indtup))
+                   elog(ERROR, "cache lookup failed for index %u", indexId);
+               val = SysCacheGetAttr(INDEXRELID, indtup,
+                                     Anum_pg_index_indnatts, &isnull);
+               if (isnull)
+                   elog(ERROR, "null indnatts for index %u", indexId);
+               if (DatumGetInt32(val) > keyatts)
                {
+                   Datum       cols;
+                   Datum      *keys;
+                   int         nKeys;
+                   int         j;
+
                    appendStringInfoString(&buf, " INCLUDE (");
 
-                   decompile_column_index_array(val, conForm->conrelid, &buf);
+                   cols = SysCacheGetAttr(INDEXRELID, indtup,
+                                          Anum_pg_index_indkey, &isnull);
+                   if (isnull)
+                       elog(ERROR, "null indkey for index %u", indexId);
+
+                   deconstruct_array(DatumGetArrayTypeP(cols),
+                                     INT2OID, 2, true, 's',
+                                     &keys, NULL, &nKeys);
+
+                   for (j = keyatts; j < nKeys; j++)
+                   {
+                       char       *colName;
+
+                       colName = get_attname(conForm->conrelid,
+                                             DatumGetInt16(keys[j]), false);
+                       if (j > keyatts)
+                           appendStringInfoString(&buf, ", ");
+                       appendStringInfoString(&buf, quote_identifier(colName));
+                   }
 
                    appendStringInfoChar(&buf, ')');
                }
-
-               indexId = get_constraint_index(constraintId);
+               ReleaseSysCache(indtup);
 
                /* XXX why do we only print these bits if fullCommand? */
                if (fullCommand && OidIsValid(indexId))
@@ -2232,9 +2262,10 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
 
 /*
  * Convert an int16[] Datum into a comma-separated list of column names
- * for the indicated relation; append the list to buf.
+ * for the indicated relation; append the list to buf.  Returns the number
+ * of keys.
  */
-static void
+static int
 decompile_column_index_array(Datum column_index_array, Oid relId,
                             StringInfo buf)
 {
@@ -2258,6 +2289,8 @@ decompile_column_index_array(Datum column_index_array, Oid relId,
        else
            appendStringInfo(buf, ", %s", quote_identifier(colName));
    }
+
+   return nKeys;
 }
 
 
index 505e32109a212f15c5726d51ee384b4ebe1157b8..0585e9b3badd26459ca1400eb6df325021fc9616 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 201806231
+#define CATALOG_VERSION_NO 201809031
 
 #endif
index 7c1c0e1db85dd0915bc7992b0926a704dc6e7a1e..9d209c9d1900919c3edd65e46e0562d58718e0c2 100644 (file)
@@ -105,12 +105,6 @@ CATALOG(pg_constraint,2606,ConstraintRelationId)
     */
    int16       conkey[1];
 
-   /*
-    * Columns of conrelid that the constraint does not apply to, but are
-    * included into the same index as the key columns
-    */
-   int16       conincluding[1];
-
    /*
     * If a foreign key, the referenced columns of confrelid
     */
index 45a1c8d0176904e178e63549edbec9a76fa57455..16b4be34de3a73f6ccdaee56dfbf47fffacf6ee7 100644 (file)
@@ -94,10 +94,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i
  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) INCLUDE (c3, c4) | covering | {1,2}  | {3,4}
+SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid;
+       pg_get_constraintdef       | conname  | conkey 
+----------------------------------+----------+--------
+ UNIQUE (c1, c2) INCLUDE (c3, c4) | covering | {1,2}
 (1 row)
 
 -- ensure that constraint works
@@ -113,10 +113,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i
  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) INCLUDE (c3, c4) | covering | {1,2}  | {3,4}
+SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid;
+         pg_get_constraintdef          | conname  | conkey 
+---------------------------------------+----------+--------
+ PRIMARY KEY (c1, c2) INCLUDE (c3, c4) | covering | {1,2}
 (1 row)
 
 -- ensure that constraint works
@@ -136,10 +136,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i
  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) INCLUDE (c3, c4) | tbl_c1_c2_c3_c4_key | {1,2}  | {3,4}
+SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid;
+       pg_get_constraintdef       |       conname       | conkey 
+----------------------------------+---------------------+--------
+ UNIQUE (c1, c2) INCLUDE (c3, c4) | tbl_c1_c2_c3_c4_key | {1,2}
 (1 row)
 
 -- ensure that constraint works
@@ -155,10 +155,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i
  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) INCLUDE (c3, c4) | tbl_pkey | {1,2}  | {3,4}
+SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid;
+         pg_get_constraintdef          | conname  | conkey 
+---------------------------------------+----------+--------
+ PRIMARY KEY (c1, c2) INCLUDE (c3, c4) | tbl_pkey | {1,2}
 (1 row)
 
 -- ensure that constraint works
@@ -178,10 +178,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i
  tbl_c1_c3_c4_excl |        3 |           1 | f           | f            | 1 3 4  | 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 
---------------------------------------------------+-------------------+--------+--------------
- EXCLUDE USING btree (c1 WITH =) INCLUDE (c3, c4) | tbl_c1_c3_c4_excl | {1}    | {3,4}
+SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid;
+               pg_get_constraintdef               |      conname      | conkey 
+--------------------------------------------------+-------------------+--------
+ EXCLUDE USING btree (c1 WITH =) INCLUDE (c3, c4) | tbl_c1_c3_c4_excl | {1}
 (1 row)
 
 -- ensure that constraint works
index ee9d9f6bae13dc3620cf4e47b5b738f63f764bfb..ef5fd882f539b338d4b0677c56be961e0f809544 100644 (file)
@@ -60,7 +60,7 @@ ALTER TABLE tbl_include_box_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4);
 CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
                CONSTRAINT covering UNIQUE(c1,c2) INCLUDE(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;
+SELECT pg_get_constraintdef(oid), conname, conkey 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;
@@ -68,7 +68,7 @@ DROP TABLE tbl;
 CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
                CONSTRAINT covering PRIMARY KEY(c1,c2) INCLUDE(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;
+SELECT pg_get_constraintdef(oid), conname, conkey 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;
@@ -78,7 +78,7 @@ DROP TABLE tbl;
 CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
                UNIQUE(c1,c2) INCLUDE(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;
+SELECT pg_get_constraintdef(oid), conname, conkey 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;
@@ -86,7 +86,7 @@ DROP TABLE tbl;
 CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
                PRIMARY KEY(c1,c2) INCLUDE(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;
+SELECT pg_get_constraintdef(oid), conname, conkey 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;
@@ -96,7 +96,7 @@ DROP TABLE tbl;
 CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box,
                EXCLUDE USING btree (c1 WITH =) INCLUDE(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;
+SELECT pg_get_constraintdef(oid), conname, conkey 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 x, 2*x, NULL, NULL FROM generate_series(1,10) AS x;