Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit01b73d3

Browse files
committed
Fix foreign keys on system columns.
1 parent57dd2ce commit01b73d3

File tree

4 files changed

+70
-196
lines changed

4 files changed

+70
-196
lines changed

‎src/backend/commands/command.c

Lines changed: 22 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.144 2001/10/12 00:07:14 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.145 2001/10/23 17:39:02 tgl Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -1347,9 +1347,7 @@ AlterTableAddConstraint(char *relationName,
13471347
boolistemp=is_temp_rel_name(relationName);
13481348
List*indexoidlist;
13491349
List*indexoidscan;
1350-
Form_pg_attribute*rel_attrs;
1351-
intnum_keys=0;
1352-
intkeys_matched=0;
1350+
intnum_keys;
13531351
boolindex_found= false;
13541352
boolindex_found_unique= false;
13551353
boolindex_found_primary= false;
@@ -1394,15 +1392,9 @@ AlterTableAddConstraint(char *relationName,
13941392
* constraint
13951393
*/
13961394

1397-
rel_attrs=rel->rd_att->attrs;
1398-
1399-
/* Retrieve the oids of all indices on the relation */
1395+
/* Loop over all indices on the relation */
14001396
indexoidlist=RelationGetIndexList(rel);
1401-
index_found= false;
1402-
index_found_unique= false;
1403-
index_found_primary= false;
14041397

1405-
/* Loop over all indices on the relation */
14061398
foreach(indexoidscan,indexoidlist)
14071399
{
14081400
Oidindexoid=lfirsti(indexoidscan);
@@ -1424,43 +1416,41 @@ AlterTableAddConstraint(char *relationName,
14241416
* Make sure this index has the same number of
14251417
* keys as the constraint -- It obviously won't match otherwise.
14261418
*/
1427-
for (i=0;i<INDEX_MAX_KEYS&&indexStruct->indkey[i]!=0;i++);
1419+
for (i=0;i<INDEX_MAX_KEYS&&indexStruct->indkey[i]!=0;i++)
1420+
;
14281421
num_keys=length(constr->keys);
1429-
keys_matched=0;
14301422

14311423
if (i==num_keys)
14321424
{
14331425
/* Loop over each key in the constraint and check that there is a
14341426
corresponding key in the index. */
1427+
intkeys_matched=0;
1428+
14351429
i=0;
14361430
foreach(keyl,constr->keys)
14371431
{
14381432
Ident*key=lfirst(keyl);
1433+
intkeyno=indexStruct->indkey[i];
14391434

14401435
/* Look at key[i] in the index and check that it is over the same column
14411436
as key[i] in the constraint. This is to differentiate between (a,b)
14421437
and (b,a) */
1443-
if (i<INDEX_MAX_KEYS&&indexStruct->indkey[i]!=0)
1444-
{
1445-
intkeyno=indexStruct->indkey[i];
1446-
1447-
if (keyno>0)
1448-
{
1449-
char*name=NameStr(rel_attrs[keyno-1]->attname);
1450-
if (strcmp(name,key->name)==0)keys_matched++;
1451-
}
1452-
}
1453-
elseelog(ERROR,"ALTER TABLE/ADD CONSTRAINT: Key \"%u[%u]\" not found",indexoid,i);
1438+
if (namestrcmp(attnumAttName(rel,keyno),
1439+
key->name)==0)
1440+
keys_matched++;
1441+
else
1442+
break;
14541443
i++;
14551444
}
14561445
if (keys_matched==num_keys) {
14571446
index_found= true;
14581447
index_found_unique=indexStruct->indisunique;
14591448
index_found_primary=indexStruct->indisprimary;
1460-
if (index_found_unique||index_found_primary)break;
14611449
}
14621450
}
14631451
ReleaseSysCache(indexTuple);
1452+
if (index_found_unique||index_found_primary)
1453+
break;
14641454
}
14651455

14661456
freeList(indexoidlist);
@@ -1504,19 +1494,7 @@ AlterTableAddConstraint(char *relationName,
15041494
Triggertrig;
15051495
List*list;
15061496
intcount;
1507-
List*indexoidlist,
1508-
*indexoidscan;
1509-
Form_pg_attribute*rel_attrs=NULL;
1510-
inti;
1511-
boolfound= false;
1512-
1513-
Oidfktypoid[INDEX_MAX_KEYS];
1514-
Oidpktypoid[INDEX_MAX_KEYS];
1515-
intattloc;
15161497

1517-
for (i=0;i<INDEX_MAX_KEYS;i++)
1518-
fktypoid[i]=pktypoid[i]=0;
1519-
15201498
if (is_temp_rel_name(fkconstraint->pktable_name)&&
15211499
!is_temp_rel_name(relationName))
15221500
elog(ERROR,"ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint.");
@@ -1530,140 +1508,21 @@ AlterTableAddConstraint(char *relationName,
15301508
if (pkrel->rd_rel->relkind!=RELKIND_RELATION)
15311509
elog(ERROR,"referenced table \"%s\" not a relation",
15321510
fkconstraint->pktable_name);
1511+
heap_close(pkrel,NoLock);
15331512

15341513
/*
1514+
* First we check for limited correctness of the constraint.
1515+
*
1516+
* NOTE: we assume parser has already checked for existence
1517+
* of an appropriate unique index on the referenced relation,
1518+
* and that the column datatypes are comparable.
1519+
*
15351520
* Scan through each tuple, calling the RI_FKey_Match_Ins
15361521
* (insert trigger) as if that tuple had just been
15371522
* inserted. If any of those fail, it should elog(ERROR)
15381523
* and that's that.
15391524
*/
15401525

1541-
/*
1542-
* First we check for limited correctness of the
1543-
* constraint
1544-
*/
1545-
1546-
rel_attrs=pkrel->rd_att->attrs;
1547-
indexoidlist=RelationGetIndexList(pkrel);
1548-
1549-
foreach(indexoidscan,indexoidlist)
1550-
{
1551-
Oidindexoid=lfirsti(indexoidscan);
1552-
HeapTupleindexTuple;
1553-
Form_pg_indexindexStruct;
1554-
1555-
indexTuple=SearchSysCache(INDEXRELID,
1556-
ObjectIdGetDatum(indexoid),
1557-
0,0,0);
1558-
if (!HeapTupleIsValid(indexTuple))
1559-
elog(ERROR,"transformFkeyGetPrimaryKey: index %u not found",
1560-
indexoid);
1561-
indexStruct= (Form_pg_index)GETSTRUCT(indexTuple);
1562-
1563-
if (indexStruct->indisunique)
1564-
{
1565-
List*attrl;
1566-
1567-
/*
1568-
* Make sure this index has the same number of
1569-
* keys -- It obviously won't match otherwise.
1570-
*/
1571-
for (i=0;i<INDEX_MAX_KEYS&&indexStruct->indkey[i]!=0;i++);
1572-
if (i!=length(fkconstraint->pk_attrs))
1573-
found= false;
1574-
else
1575-
{
1576-
attloc=0;
1577-
/* go through the fkconstraint->pk_attrs list */
1578-
foreach(attrl,fkconstraint->pk_attrs)
1579-
{
1580-
Ident*attr=lfirst(attrl);
1581-
1582-
found= false;
1583-
for (i=0;i<INDEX_MAX_KEYS&&indexStruct->indkey[i]!=0;i++)
1584-
{
1585-
intpkattno=indexStruct->indkey[i];
1586-
1587-
if (pkattno>0)
1588-
{
1589-
char*name=NameStr(rel_attrs[pkattno-1]->attname);
1590-
1591-
if (strcmp(name,attr->name)==0)
1592-
{
1593-
/* We get the type of this attribute here and
1594-
* store it so we can use it later for making
1595-
* sure the types are comparable.
1596-
*/
1597-
pktypoid[attloc++]=rel_attrs[pkattno-1]->atttypid;
1598-
found= true;
1599-
break;
1600-
}
1601-
}
1602-
}
1603-
if (!found)
1604-
break;
1605-
}
1606-
}
1607-
}
1608-
ReleaseSysCache(indexTuple);
1609-
if (found)
1610-
break;
1611-
}
1612-
1613-
if (!found)
1614-
elog(ERROR,"UNIQUE constraint matching given keys for referenced table \"%s\" not found",
1615-
fkconstraint->pktable_name);
1616-
1617-
freeList(indexoidlist);
1618-
heap_close(pkrel,NoLock);
1619-
1620-
rel_attrs=rel->rd_att->attrs;
1621-
if (fkconstraint->fk_attrs!=NIL)
1622-
{
1623-
List*fkattrs;
1624-
Ident*fkattr;
1625-
1626-
found= false;
1627-
attloc=0;
1628-
foreach(fkattrs,fkconstraint->fk_attrs)
1629-
{
1630-
intcount;
1631-
1632-
found= false;
1633-
fkattr=lfirst(fkattrs);
1634-
for (count=0;count<rel->rd_att->natts;count++)
1635-
{
1636-
char*name=NameStr(rel->rd_att->attrs[count]->attname);
1637-
1638-
if (strcmp(name,fkattr->name)==0)
1639-
{
1640-
/*
1641-
* Here once again we get the types, this
1642-
* time for the fk table's attributes
1643-
*/
1644-
fktypoid[attloc++]=rel->rd_att->attrs[count]->atttypid;
1645-
found= true;
1646-
break;
1647-
}
1648-
}
1649-
if (!found)
1650-
break;
1651-
}
1652-
if (!found)
1653-
elog(ERROR,"columns referenced in foreign key constraint not found.");
1654-
}
1655-
1656-
for (i=0;i<INDEX_MAX_KEYS&&fktypoid[i]!=0;i++) {
1657-
/*
1658-
* fktypoid[i] is the foreign key table's i'th element's type oid
1659-
* pktypoid[i] is the primary key table's i'th element's type oid
1660-
* We let oper() do our work for us, including elog(ERROR) if the
1661-
* types can't compare with =
1662-
*/
1663-
Operatoro=oper("=",fktypoid[i],pktypoid[i], false);
1664-
ReleaseSysCache(o);
1665-
}
1666-
16671526
trig.tgoid=0;
16681527
if (fkconstraint->constr_name)
16691528
trig.tgname=fkconstraint->constr_name;
@@ -1706,7 +1565,6 @@ AlterTableAddConstraint(char *relationName,
17061565
trig.tgnargs=count-1;
17071566

17081567
scan=heap_beginscan(rel, false,SnapshotNow,0,NULL);
1709-
AssertState(scan!=NULL);
17101568

17111569
while (HeapTupleIsValid(tuple=heap_getnext(scan,0)))
17121570
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp