Skip to content

Commit 3f17781

Browse files
committed
updated to including_columns_8.0, except regression tests
1 parent 6df01ab commit 3f17781

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+482
-212
lines changed

contrib/dblink/dblink.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static remoteConn *getConnectionByName(const char *name);
101101
static HTAB *createConnHash(void);
102102
static void createNewConnection(const char *name, remoteConn *rconn);
103103
static void deleteConnection(const char *name);
104-
static char **get_pkey_attnames(Relation rel, int16 *numatts);
104+
static char **get_pkey_attnames(Relation rel, int16* indnkeyatts);
105105
static char **get_text_array_contents(ArrayType *array, int *numitems);
106106
static char *get_sql_insert(Relation rel, int *pkattnums, int pknumatts, char **src_pkattvals, char **tgt_pkattvals);
107107
static char *get_sql_delete(Relation rel, int *pkattnums, int pknumatts, char **tgt_pkattvals);
@@ -1486,7 +1486,7 @@ PG_FUNCTION_INFO_V1(dblink_get_pkey);
14861486
Datum
14871487
dblink_get_pkey(PG_FUNCTION_ARGS)
14881488
{
1489-
int16 numatts;
1489+
int16 indnkeyatts;
14901490
char **results;
14911491
FuncCallContext *funcctx;
14921492
int32 call_cntr;
@@ -1512,7 +1512,7 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
15121512
rel = get_rel_from_relname(PG_GETARG_TEXT_P(0), AccessShareLock, ACL_SELECT);
15131513

15141514
/* get the array of attnums */
1515-
results = get_pkey_attnames(rel, &numatts);
1515+
results = get_pkey_attnames(rel, &indnkeyatts);
15161516

15171517
relation_close(rel, AccessShareLock);
15181518

@@ -1532,9 +1532,9 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
15321532
attinmeta = TupleDescGetAttInMetadata(tupdesc);
15331533
funcctx->attinmeta = attinmeta;
15341534

1535-
if ((results != NULL) && (numatts > 0))
1535+
if ((results != NULL) && (indnkeyatts > 0))
15361536
{
1537-
funcctx->max_calls = numatts;
1537+
funcctx->max_calls = indnkeyatts;
15381538

15391539
/* got results, keep track of them */
15401540
funcctx->user_fctx = results;
@@ -2024,10 +2024,10 @@ dblink_fdw_validator(PG_FUNCTION_ARGS)
20242024
* get_pkey_attnames
20252025
*
20262026
* Get the primary key attnames for the given relation.
2027-
* Return NULL, and set numatts = 0, if no primary key exists.
2027+
* Return NULL, and set indnkeyatts = 0, if no primary key exists.
20282028
*/
20292029
static char **
2030-
get_pkey_attnames(Relation rel, int16 *numatts)
2030+
get_pkey_attnames(Relation rel, int16 *indnkeyatts)
20312031
{
20322032
Relation indexRelation;
20332033
ScanKeyData skey;
@@ -2037,8 +2037,8 @@ get_pkey_attnames(Relation rel, int16 *numatts)
20372037
char **result = NULL;
20382038
TupleDesc tupdesc;
20392039

2040-
/* initialize numatts to 0 in case no primary key exists */
2041-
*numatts = 0;
2040+
/* initialize indnkeyatts to 0 in case no primary key exists */
2041+
*indnkeyatts = 0;
20422042

20432043
tupdesc = rel->rd_att;
20442044

@@ -2059,12 +2059,12 @@ get_pkey_attnames(Relation rel, int16 *numatts)
20592059
/* we're only interested if it is the primary key */
20602060
if (index->indisprimary)
20612061
{
2062-
*numatts = index->indnkeyatts;
2063-
if (*numatts > 0)
2062+
*indnkeyatts = index->indnkeyatts;
2063+
if (*indnkeyatts > 0)
20642064
{
2065-
result = (char **) palloc(*numatts * sizeof(char *));
2065+
result = (char **) palloc(*indnkeyatts * sizeof(char *));
20662066

2067-
for (i = 0; i < *numatts; i++)
2067+
for (i = 0; i < *indnkeyatts; i++)
20682068
result[i] = SPI_fname(tupdesc, index->indkey.values[i]);
20692069
}
20702070
break;

contrib/tcn/tcn.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ triggered_change_notification(PG_FUNCTION_ARGS)
138138
/* we're only interested if it is the primary key and valid */
139139
if (index->indisprimary && IndexIsValid(index))
140140
{
141-
int numatts = index->indnatts;
141+
int indnkeyatts = index->indnkeyatts;
142142

143-
if (numatts > 0)
143+
if (indnkeyatts > 0)
144144
{
145145
int i;
146146

@@ -150,7 +150,7 @@ triggered_change_notification(PG_FUNCTION_ARGS)
150150
appendStringInfoCharMacro(payload, ',');
151151
appendStringInfoCharMacro(payload, operation);
152152

153-
for (i = 0; i < numatts; i++)
153+
for (i = 0; i < indnkeyatts; i++)
154154
{
155155
int colno = index->indkey.values[i];
156156

doc/src/sgml/catalogs.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3721,7 +3721,7 @@
37213721
<literal>pg_class.relnatts</literal>)</entry>
37223722
</row>
37233723

3724-
<row>
3724+
<row>
37253725
<entry><structfield>indnkeyatts</structfield></entry>
37263726
<entry><type>int2</type></entry>
37273727
<entry></entry>

doc/src/sgml/ref/create_index.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ doc/src/sgml/ref/create_index.sgml
2323
<synopsis>
2424
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> ] ON <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
2525
( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
26-
[ INCLUDING ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
26+
[ INCLUDING ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
2727
[ WITH ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ]
2828
[ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
2929
[ WHERE <replaceable class="parameter">predicate</replaceable> ]

doc/src/sgml/ref/create_table.sgml

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
5959

6060
[ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
6161
{ CHECK ( <replaceable class="PARAMETER">expression</replaceable> ) [ NO INHERIT ] |
62-
UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> |
63-
PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> |
62+
UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> <optional>INCLUDING (<replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional> |
63+
PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> <optional>INCLUDING (<replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional> |
6464
EXCLUDE [ USING <replaceable class="parameter">index_method</replaceable> ] ( <replaceable class="parameter">exclude_element</replaceable> WITH <replaceable class="parameter">operator</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> [ WHERE ( <replaceable class="parameter">predicate</replaceable> ) ] |
6565
FOREIGN KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) REFERENCES <replaceable class="PARAMETER">reftable</replaceable> [ ( <replaceable class="PARAMETER">refcolumn</replaceable> [, ... ] ) ]
6666
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ] }
@@ -476,7 +476,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
476476

477477
<varlistentry>
478478
<term><literal>UNIQUE</> (column constraint)</term>
479-
<term><literal>UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )</> (table constraint)</term>
479+
<term><literal>UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )
480+
<optional>INCLUDING ( <replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional></> (table constraint)</term>
480481

481482
<listitem>
482483
<para>
@@ -498,13 +499,24 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
498499
primary key constraint defined for the table. (Otherwise it
499500
would just be the same constraint listed twice.)
500501
</para>
502+
<para>
503+
Adding a unique constraint will automatically create a unique btree
504+
index on the column or group of columns used in the constraint.
505+
Optional clause <literal>INCLUDING</literal> allows to add into the index
506+
a portion of columns on which the uniqueness is not enforced upon.
507+
Note, that althogh constraint is not enforced upon included columns, it still
508+
depends on them. Consequently, some operations on these columns (e.g. <literal>DROP COLUMN<literal>)
509+
can cause cascade constraint and index deletion.
510+
See paragraph about <literal>INCLUDING</literal> in
511+
<xref linkend="SQL-CREATEINDEX"> for more information.
512+
</para>
501513
</listitem>
502514
</varlistentry>
503515

504516
<varlistentry>
505517
<term><literal>PRIMARY KEY</> (column constraint)</term>
506-
<term><literal>PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )</> (table constraint)</term>
507-
<listitem>
518+
<term><literal>PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )
519+
<optional>INCLUDING ( <replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional></> (table constraint)</term> <listitem>
508520
<para>
509521
The <literal>PRIMARY KEY</> constraint specifies that a column or
510522
columns of a table can contain only unique (non-duplicate), nonnull
@@ -526,6 +538,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
526538
about the design of the schema, since a primary key implies that other
527539
tables can rely on this set of columns as a unique identifier for rows.
528540
</para>
541+
542+
<para>
543+
Adding a <literal>PRIMARY KEY</literal> constraint will automatically create a unique btree
544+
index on the column or group of columns used in the constraint.
545+
Optional clause <literal>INCLUDING</literal> allows to add into the index
546+
a portion of columns on which the constraint is not enforced upon.
547+
Note, that althogh constraint is not enforced upon included columns, it still
548+
depends on them. Consequently, some operations on these columns (e.g. <literal>DROP COLUMN<literal>)
549+
can cause cascade constraint and index deletion.
550+
See paragraph about <literal>INCLUDING</literal> in
551+
<xref linkend="SQL-CREATEINDEX"> for more information.
552+
</para>
529553
</listitem>
530554
</varlistentry>
531555

src/backend/access/index/genam.c

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,15 @@ BuildIndexValueDescription(Relation indexRelation,
175175
StringInfoData buf;
176176
Form_pg_index idxrec;
177177
HeapTuple ht_idx;
178-
int natts = indexRelation->rd_rel->relnatts;
179-
int nkeyatts;
178+
int indnkeyatts;
180179
int i;
181180
int keyno;
182181
Oid indexrelid = RelationGetRelid(indexRelation);
183182
Oid indrelid;
184183
AclResult aclresult;
185184

185+
indnkeyatts = IndexRelationGetNumberOfKeyAttributes(indexRelation);
186+
186187
/*
187188
* Check permissions- if the user does not have access to view all of the
188189
* key columns then return NULL to avoid leaking data.
@@ -220,7 +221,7 @@ BuildIndexValueDescription(Relation indexRelation,
220221
* No table-level access, so step through the columns in the index and
221222
* make sure the user has SELECT rights on all of them.
222223
*/
223-
for (keyno = 0; keyno < idxrec->indnatts; keyno++)
224+
for (keyno = 0; keyno < idxrec->indnkeyatts; keyno++)
224225
{
225226
AttrNumber attnum = idxrec->indkey.values[keyno];
226227

@@ -246,8 +247,7 @@ BuildIndexValueDescription(Relation indexRelation,
246247
appendStringInfo(&buf, "(%s)=(",
247248
pg_get_indexdef_columns(indexrelid, true));
248249

249-
nkeyatts = IndexRelationGetNumberOfKeyAttributes(indexRelation);
250-
for (i = 0; i < natts; i++)
250+
for (i = 0; i < indnkeyatts; i++)
251251
{
252252
char *val;
253253

@@ -257,31 +257,19 @@ BuildIndexValueDescription(Relation indexRelation,
257257
{
258258
Oid foutoid;
259259
bool typisvarlena;
260-
TupleDesc tupdesc = RelationGetDescr(indexRelation);
261260
/*
262-
* For key attributes the provided data is not necessarily of the
263-
* type stored in the index; rather it is of the index opclass's
264-
* input type. So look at rd_opcintype not the index tupdesc.
261+
* The provided data is not necessarily of the type stored in the
262+
* index; rather it is of the index opclass's input type. So look
263+
* at rd_opcintype not the index tupdesc.
265264
*
266265
* Note: this is a bit shaky for opclasses that have pseudotype
267266
* input types such as ANYARRAY or RECORD. Currently, the
268267
* typoutput functions associated with the pseudotypes will work
269268
* okay, but we might have to try harder in future.
270-
*
271-
* For included attributes just use info stored in the index
272-
* tupdesc.
273269
*/
274-
if (i < nkeyatts)
275-
{
276-
getTypeOutputInfo(indexRelation->rd_opcintype[i],
277-
&foutoid, &typisvarlena);
278-
val = OidOutputFunctionCall(foutoid, values[i]);
279-
}
280-
else
281-
{
282-
getTypeOutputInfo(tupdesc->attrs[i]->atttypid, &foutoid, &typisvarlena);
283-
val = OidOutputFunctionCall(foutoid, values[i]);
284-
}
270+
getTypeOutputInfo(indexRelation->rd_opcintype[i],
271+
&foutoid, &typisvarlena);
272+
val = OidOutputFunctionCall(foutoid, values[i]);
285273
}
286274

287275
if (i > 0)
@@ -376,15 +364,15 @@ systable_beginscan(Relation heapRelation,
376364
{
377365
int j;
378366

379-
for (j = 0; j < irel->rd_index->indnatts; j++)
367+
for (j = 0; j < IndexRelationGetNumberOfAttributes(irel); j++)
380368
{
381369
if (key[i].sk_attno == irel->rd_index->indkey.values[j])
382370
{
383371
key[i].sk_attno = j + 1;
384372
break;
385373
}
386374
}
387-
if (j == irel->rd_index->indnatts)
375+
if (j == IndexRelationGetNumberOfAttributes(irel))
388376
elog(ERROR, "column is not in index");
389377
}
390378

@@ -578,15 +566,15 @@ systable_beginscan_ordered(Relation heapRelation,
578566
{
579567
int j;
580568

581-
for (j = 0; j < indexRelation->rd_index->indnatts; j++)
569+
for (j = 0; j < IndexRelationGetNumberOfAttributes(indexRelation); j++)
582570
{
583571
if (key[i].sk_attno == indexRelation->rd_index->indkey.values[j])
584572
{
585573
key[i].sk_attno = j + 1;
586574
break;
587575
}
588576
}
589-
if (j == indexRelation->rd_index->indnatts)
577+
if (j == IndexRelationGetNumberOfAttributes(indexRelation))
590578
elog(ERROR, "column is not in index");
591579
}
592580

0 commit comments

Comments
 (0)