8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
* NOTES
14
14
* The PerformAddAttribute() code, like most of the relation
@@ -1347,9 +1347,7 @@ AlterTableAddConstraint(char *relationName,
1347
1347
bool istemp = is_temp_rel_name (relationName );
1348
1348
List * indexoidlist ;
1349
1349
List * indexoidscan ;
1350
- Form_pg_attribute * rel_attrs ;
1351
- int num_keys = 0 ;
1352
- int keys_matched = 0 ;
1350
+ int num_keys ;
1353
1351
bool index_found = false;
1354
1352
bool index_found_unique = false;
1355
1353
bool index_found_primary = false;
@@ -1394,15 +1392,9 @@ AlterTableAddConstraint(char *relationName,
1394
1392
* constraint
1395
1393
*/
1396
1394
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 */
1400
1396
indexoidlist = RelationGetIndexList (rel );
1401
- index_found = false;
1402
- index_found_unique = false;
1403
- index_found_primary = false;
1404
1397
1405
- /* Loop over all indices on the relation */
1406
1398
foreach (indexoidscan , indexoidlist )
1407
1399
{
1408
1400
Oid indexoid = lfirsti (indexoidscan );
@@ -1424,43 +1416,41 @@ AlterTableAddConstraint(char *relationName,
1424
1416
* Make sure this index has the same number of
1425
1417
* keys as the constraint -- It obviously won't match otherwise.
1426
1418
*/
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
+ ;
1428
1421
num_keys = length (constr -> keys );
1429
- keys_matched = 0 ;
1430
1422
1431
1423
if (i == num_keys )
1432
1424
{
1433
1425
/* Loop over each key in the constraint and check that there is a
1434
1426
corresponding key in the index. */
1427
+ int keys_matched = 0 ;
1428
+
1435
1429
i = 0 ;
1436
1430
foreach (keyl , constr -> keys )
1437
1431
{
1438
1432
Ident * key = lfirst (keyl );
1433
+ int keyno = indexStruct -> indkey [i ];
1439
1434
1440
1435
/* Look at key[i] in the index and check that it is over the same column
1441
1436
as key[i] in the constraint. This is to differentiate between (a,b)
1442
1437
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 ;
1454
1443
i ++ ;
1455
1444
}
1456
1445
if (keys_matched == num_keys ) {
1457
1446
index_found = true;
1458
1447
index_found_unique = indexStruct -> indisunique ;
1459
1448
index_found_primary = indexStruct -> indisprimary ;
1460
- if (index_found_unique || index_found_primary ) break ;
1461
1449
}
1462
1450
}
1463
1451
ReleaseSysCache (indexTuple );
1452
+ if (index_found_unique || index_found_primary )
1453
+ break ;
1464
1454
}
1465
1455
1466
1456
freeList (indexoidlist );
@@ -1504,19 +1494,7 @@ AlterTableAddConstraint(char *relationName,
1504
1494
Trigger trig ;
1505
1495
List * list ;
1506
1496
int 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 ;
1516
1497
1517
- for (i = 0 ; i < INDEX_MAX_KEYS ; i ++ )
1518
- fktypoid [i ]= pktypoid [i ]= 0 ;
1519
-
1520
1498
if (is_temp_rel_name (fkconstraint -> pktable_name ) &&
1521
1499
!is_temp_rel_name (relationName ))
1522
1500
elog (ERROR , "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint." );
@@ -1530,140 +1508,21 @@ AlterTableAddConstraint(char *relationName,
1530
1508
if (pkrel -> rd_rel -> relkind != RELKIND_RELATION )
1531
1509
elog (ERROR , "referenced table \"%s\" not a relation" ,
1532
1510
fkconstraint -> pktable_name );
1511
+ heap_close (pkrel , NoLock );
1533
1512
1534
1513
/*
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
+ *
1535
1520
* Scan through each tuple, calling the RI_FKey_Match_Ins
1536
1521
* (insert trigger) as if that tuple had just been
1537
1522
* inserted. If any of those fail, it should elog(ERROR)
1538
1523
* and that's that.
1539
1524
*/
1540
1525
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
-
1667
1526
trig .tgoid = 0 ;
1668
1527
if (fkconstraint -> constr_name )
1669
1528
trig .tgname = fkconstraint -> constr_name ;
@@ -1706,7 +1565,6 @@ AlterTableAddConstraint(char *relationName,
1706
1565
trig .tgnargs = count - 1 ;
1707
1566
1708
1567
scan = heap_beginscan (rel , false, SnapshotNow , 0 , NULL );
1709
- AssertState (scan != NULL );
1710
1568
1711
1569
while (HeapTupleIsValid (tuple = heap_getnext (scan , 0 )))
1712
1570
{
0 commit comments