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,
13471347bool istemp = is_temp_rel_name (relationName );
13481348List * indexoidlist ;
13491349List * indexoidscan ;
1350- Form_pg_attribute * rel_attrs ;
1351- int num_keys = 0 ;
1352- int keys_matched = 0 ;
1350+ int num_keys ;
13531351bool index_found = false;
13541352bool index_found_unique = false;
13551353bool index_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 */
14001396indexoidlist = 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 */
14061398foreach (indexoidscan ,indexoidlist )
14071399 {
14081400Oid indexoid = 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+ ;
14281421num_keys = length (constr -> keys );
1429- keys_matched = 0 ;
14301422
14311423if (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+ int keys_matched = 0 ;
1428+
14351429i = 0 ;
14361430foreach (keyl ,constr -> keys )
14371431 {
14381432Ident * key = lfirst (keyl );
1433+ int keyno = 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- int keyno = 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- else elog (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 ;
14541443i ++ ;
14551444 }
14561445if (keys_matched == num_keys ) {
14571446index_found = true;
14581447index_found_unique = indexStruct -> indisunique ;
14591448index_found_primary = indexStruct -> indisprimary ;
1460- if (index_found_unique || index_found_primary )break ;
14611449 }
14621450 }
14631451ReleaseSysCache (indexTuple );
1452+ if (index_found_unique || index_found_primary )
1453+ break ;
14641454 }
14651455
14661456freeList (indexoidlist );
@@ -1504,19 +1494,7 @@ AlterTableAddConstraint(char *relationName,
15041494Trigger trig ;
15051495List * list ;
15061496int count ;
1507- List * indexoidlist ,
1508- * indexoidscan ;
1509- Form_pg_attribute * rel_attrs = NULL ;
1510- int i ;
1511- bool found = false;
1512-
1513- Oid fktypoid [INDEX_MAX_KEYS ];
1514- Oid pktypoid [INDEX_MAX_KEYS ];
1515- int attloc ;
15161497
1517- for (i = 0 ;i < INDEX_MAX_KEYS ;i ++ )
1518- fktypoid [i ]= pktypoid [i ]= 0 ;
1519-
15201498if (is_temp_rel_name (fkconstraint -> pktable_name )&&
15211499!is_temp_rel_name (relationName ))
15221500elog (ERROR ,"ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint." );
@@ -1530,140 +1508,21 @@ AlterTableAddConstraint(char *relationName,
15301508if (pkrel -> rd_rel -> relkind != RELKIND_RELATION )
15311509elog (ERROR ,"referenced table \"%s\" not a relation" ,
15321510fkconstraint -> 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- Oid indexoid = lfirsti (indexoidscan );
1552- HeapTuple indexTuple ;
1553- Form_pg_index indexStruct ;
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- int pkattno = 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- int count ;
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- Operator o = oper ("=" ,fktypoid [i ],pktypoid [i ], false);
1664- ReleaseSysCache (o );
1665- }
1666-
16671526trig .tgoid = 0 ;
16681527if (fkconstraint -> constr_name )
16691528trig .tgname = fkconstraint -> constr_name ;
@@ -1706,7 +1565,6 @@ AlterTableAddConstraint(char *relationName,
17061565trig .tgnargs = count - 1 ;
17071566
17081567scan = heap_beginscan (rel , false,SnapshotNow ,0 ,NULL );
1709- AssertState (scan != NULL );
17101568
17111569while (HeapTupleIsValid (tuple = heap_getnext (scan ,0 )))
17121570{