7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.21 1997/08/2202:58:51 vadim Exp $
10
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.22 1997/08/2214:10:24 vadim Exp $
11
11
*
12
12
* INTERFACE ROUTINES
13
13
*heap_creatr()- Create an uncataloged heap relation
50
50
#include <utils/builtins.h>
51
51
#include <utils/mcxt.h>
52
52
#include <utils/relcache.h>
53
+ #include <nodes/plannodes.h>
53
54
#ifndef HAVE_MEMMOVE
54
55
# include <regex/utils.h>
55
56
#else
@@ -68,8 +69,7 @@ static void RelationRemoveInheritance(Relation relation);
68
69
static void RemoveFromTempRelList (Relation r );
69
70
static void addNewRelationType (char * typeName ,Oid new_rel_oid );
70
71
static void StoreConstraints (Relation rel );
71
- static void StoreAttrDefault (Relation rel ,AttrDefault * attrdef );
72
- static void StoreRelCheck (Relation rel ,ConstrCheck * check );
72
+ static void RemoveConstraints (Relation rel );
73
73
74
74
75
75
/* ----------------------------------------------------------------
@@ -371,8 +371,10 @@ heap_creatr(char *name,
371
371
*
372
372
*6) AddPgRelationTuple() is called to register the
373
373
* relation itself in the catalogs.
374
+ *
375
+ *7) StoreConstraints is called ()- vadim 08/22/97
374
376
*
375
- *7 ) the relations are closed and the new relation's oid
377
+ *8 ) the relations are closed and the new relation's oid
376
378
* is returned.
377
379
*
378
380
* old comments:
@@ -847,7 +849,8 @@ heap_create(char relname[],
847
849
*4) remove pg_class tuple
848
850
*5) remove pg_attribute tuples
849
851
*6) remove pg_type tuples
850
- *7) unlink relation
852
+ *7) RemoveConstraints ()
853
+ *8) unlink relation
851
854
*
852
855
* old comments
853
856
*Except for vital relations, removes relation from
@@ -1327,6 +1330,8 @@ heap_destroy(char *relname)
1327
1330
* Does nothing!!! Flushing moved below.- vadim 06/04/97
1328
1331
RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);
1329
1332
*/
1333
+
1334
+ RemoveConstraints (rdesc );
1330
1335
1331
1336
/* ----------------
1332
1337
*unlink the relation and finish up.
@@ -1468,30 +1473,6 @@ DestroyTempRels(void)
1468
1473
tempRels = NULL ;
1469
1474
}
1470
1475
1471
- static void
1472
- StoreConstraints (Relation rel )
1473
- {
1474
- TupleConstr * constr = rel -> rd_att -> constr ;
1475
- int i ;
1476
-
1477
- if ( !constr )
1478
- return ;
1479
-
1480
- if (constr -> num_defval > 0 )
1481
- {
1482
- for (i = 0 ;i < constr -> num_defval ;i ++ )
1483
- StoreAttrDefault (rel ,& (constr -> defval [i ]));
1484
- }
1485
-
1486
- if (constr -> num_check > 0 )
1487
- {
1488
- for (i = 0 ;i < constr -> num_check ;i ++ )
1489
- StoreRelCheck (rel ,& (constr -> check [i ]));
1490
- }
1491
-
1492
- return ;
1493
- }
1494
-
1495
1476
extern List * flatten_tlist (List * tlist );
1496
1477
extern List * pg_plan (char * query_string ,Oid * typev ,int nargs ,
1497
1478
QueryTreeList * * queryListP ,CommandDest dest );
@@ -1520,12 +1501,14 @@ StoreAttrDefault (Relation rel, AttrDefault *attrdef)
1520
1501
start :;
1521
1502
sprintf (str ,"select %s%s from %.*s" ,attrdef -> adsrc ,cast ,
1522
1503
NAMEDATALEN ,rel -> rd_rel -> relname .data );
1504
+ setheapoverride (true);
1523
1505
planTree_list = (List * )pg_plan (str ,NULL ,0 ,& queryTree_list ,None );
1506
+ setheapoverride (false);
1524
1507
query = (Query * ) (queryTree_list -> qtrees [0 ]);
1525
1508
1526
1509
if (length (query -> rtable )> 1 ||
1527
1510
flatten_tlist (query -> targetList )!= NIL )
1528
- elog (WARN ,"AttributeDefault : cannot use attribute(s)" );
1511
+ elog (WARN ,"DEFAULT : cannot use attribute(s)" );
1529
1512
te = (TargetEntry * )lfirst (query -> targetList );
1530
1513
resdom = te -> resdom ;
1531
1514
expr = te -> expr ;
@@ -1535,13 +1518,13 @@ start:;
1535
1518
if ( ((Const * )expr )-> consttype != atp -> atttypid )
1536
1519
{
1537
1520
if (* cast != 0 )
1538
- elog (WARN ,"AttributeDefault: casting failed - const type mismatched" );
1521
+ elog (WARN ,"DEFAULT: const type mismatched" );
1539
1522
sprintf (cast ,":: %s" ,get_id_typname (atp -> atttypid ));
1540
1523
gotostart ;
1541
1524
}
1542
1525
}
1543
1526
else if (exprType (expr )!= atp -> atttypid )
1544
- elog (WARN ,"AttributeDefault : type mismatched" );
1527
+ elog (WARN ,"DEFAULT : type mismatched" );
1545
1528
1546
1529
adbin = nodeToString (expr );
1547
1530
oldcxt = MemoryContextSwitchTo ((MemoryContext )CacheCxt );
@@ -1560,6 +1543,7 @@ start:;
1560
1543
heap_insert (adrel ,tuple );
1561
1544
CatalogIndexInsert (idescs ,Num_pg_attrdef_indices ,adrel ,tuple );
1562
1545
CatalogCloseIndices (Num_pg_attrdef_indices ,idescs );
1546
+ heap_close (adrel );
1563
1547
1564
1548
pfree (DatumGetPointer (values [Anum_pg_attrdef_adbin - 1 ]));
1565
1549
pfree (DatumGetPointer (values [Anum_pg_attrdef_adsrc - 1 ]));
@@ -1570,6 +1554,153 @@ start:;
1570
1554
static void
1571
1555
StoreRelCheck (Relation rel ,ConstrCheck * check )
1572
1556
{
1557
+ char str [MAX_PARSE_BUFFER ];
1558
+ QueryTreeList * queryTree_list ;
1559
+ Query * query ;
1560
+ List * planTree_list ;
1561
+ Plan * plan ;
1562
+ List * qual ;
1563
+ char * ccbin ;
1564
+ MemoryContext oldcxt ;
1565
+ Relation rcrel ;
1566
+ Relation idescs [Num_pg_relcheck_indices ];
1567
+ HeapTuple tuple ;
1568
+ Datum values [4 ];
1569
+ char nulls [4 ]= {' ' ,' ' ,' ' ,' ' };
1570
+ extern GlobalMemory CacheCxt ;
1571
+
1572
+ sprintf (str ,"select 1 from %.*s where %s" ,
1573
+ NAMEDATALEN ,rel -> rd_rel -> relname .data ,check -> ccsrc );
1574
+ setheapoverride (true);
1575
+ planTree_list = (List * )pg_plan (str ,NULL ,0 ,& queryTree_list ,None );
1576
+ setheapoverride (false);
1577
+ query = (Query * ) (queryTree_list -> qtrees [0 ]);
1578
+
1579
+ if (length (query -> rtable )> 1 )
1580
+ elog (WARN ,"CHECK: only relation %.*s can be referenced" ,
1581
+ NAMEDATALEN ,rel -> rd_rel -> relname .data );
1582
+
1583
+ plan = (Plan * )lfirst (planTree_list );
1584
+ qual = plan -> qual ;
1585
+
1586
+ ccbin = nodeToString (qual );
1587
+ oldcxt = MemoryContextSwitchTo ((MemoryContext )CacheCxt );
1588
+ check -> ccbin = (char * )palloc (strlen (ccbin )+ 1 );
1589
+ strcpy (check -> ccbin ,ccbin );
1590
+ (void )MemoryContextSwitchTo (oldcxt );
1591
+ pfree (ccbin );
1592
+
1593
+ values [Anum_pg_relcheck_rcrelid - 1 ]= rel -> rd_id ;
1594
+ values [Anum_pg_relcheck_rcname - 1 ]= PointerGetDatum (namein (check -> ccname ));
1595
+ values [Anum_pg_relcheck_rcbin - 1 ]= PointerGetDatum (textin (check -> ccbin ));
1596
+ values [Anum_pg_relcheck_rcsrc - 1 ]= PointerGetDatum (textin (check -> ccsrc ));
1597
+ rcrel = heap_openr (RelCheckRelationName );
1598
+ tuple = heap_formtuple (rcrel -> rd_att ,values ,nulls );
1599
+ CatalogOpenIndices (Num_pg_relcheck_indices ,Name_pg_relcheck_indices ,idescs );
1600
+ heap_insert (rcrel ,tuple );
1601
+ CatalogIndexInsert (idescs ,Num_pg_relcheck_indices ,rcrel ,tuple );
1602
+ CatalogCloseIndices (Num_pg_relcheck_indices ,idescs );
1603
+ heap_close (rcrel );
1604
+
1605
+ pfree (DatumGetPointer (values [Anum_pg_relcheck_rcname - 1 ]));
1606
+ pfree (DatumGetPointer (values [Anum_pg_relcheck_rcbin - 1 ]));
1607
+ pfree (DatumGetPointer (values [Anum_pg_relcheck_rcsrc - 1 ]));
1608
+ pfree (tuple );
1609
+
1610
+ return ;
1611
+ }
1612
+
1613
+ static void
1614
+ StoreConstraints (Relation rel )
1615
+ {
1616
+ TupleConstr * constr = rel -> rd_att -> constr ;
1617
+ int i ;
1618
+
1619
+ if ( !constr )
1620
+ return ;
1621
+
1622
+ if (constr -> num_defval > 0 )
1623
+ {
1624
+ for (i = 0 ;i < constr -> num_defval ;i ++ )
1625
+ StoreAttrDefault (rel ,& (constr -> defval [i ]));
1626
+ }
1627
+
1628
+ if (constr -> num_check > 0 )
1629
+ {
1630
+ for (i = 0 ;i < constr -> num_check ;i ++ )
1631
+ StoreRelCheck (rel ,& (constr -> check [i ]));
1632
+ }
1633
+
1634
+ return ;
1635
+ }
1636
+
1637
+ static void
1638
+ RemoveAttrDefault (Relation rel )
1639
+ {
1640
+ Relation adrel ;
1641
+ HeapScanDesc adscan ;
1642
+ ScanKeyData key ;
1643
+ HeapTuple tup ;
1644
+
1645
+ adrel = heap_openr (AttrDefaultRelationName );
1646
+
1647
+ ScanKeyEntryInitialize (& key ,0 ,Anum_pg_attrdef_adrelid ,
1648
+ ObjectIdEqualRegProcedure ,rel -> rd_id );
1649
+
1650
+ RelationSetLockForWrite (adrel );
1651
+
1652
+ adscan = heap_beginscan (adrel ,0 ,NowTimeQual ,1 ,& key );
1653
+
1654
+ while (tup = heap_getnext (adscan ,0 , (Buffer * )NULL ),PointerIsValid (tup ))
1655
+ heap_delete (adrel ,& tup -> t_ctid );
1656
+
1657
+ heap_endscan (adscan );
1658
+
1659
+ RelationUnsetLockForWrite (adrel );
1660
+ heap_close (adrel );
1661
+
1662
+ }
1663
+
1664
+ static void
1665
+ RemoveRelCheck (Relation rel )
1666
+ {
1667
+ Relation rcrel ;
1668
+ HeapScanDesc rcscan ;
1669
+ ScanKeyData key ;
1670
+ HeapTuple tup ;
1671
+
1672
+ rcrel = heap_openr (RelCheckRelationName );
1673
+
1674
+ ScanKeyEntryInitialize (& key ,0 ,Anum_pg_relcheck_rcrelid ,
1675
+ ObjectIdEqualRegProcedure ,rel -> rd_id );
1676
+
1677
+ RelationSetLockForWrite (rcrel );
1678
+
1679
+ rcscan = heap_beginscan (rcrel ,0 ,NowTimeQual ,1 ,& key );
1680
+
1681
+ while (tup = heap_getnext (rcscan ,0 , (Buffer * )NULL ),PointerIsValid (tup ))
1682
+ heap_delete (rcrel ,& tup -> t_ctid );
1683
+
1684
+ heap_endscan (rcscan );
1685
+
1686
+ RelationUnsetLockForWrite (rcrel );
1687
+ heap_close (rcrel );
1688
+
1689
+ }
1573
1690
1691
+ static void
1692
+ RemoveConstraints (Relation rel )
1693
+ {
1694
+ TupleConstr * constr = rel -> rd_att -> constr ;
1695
+
1696
+ if ( !constr )
1697
+ return ;
1698
+
1699
+ if (constr -> num_defval > 0 )
1700
+ RemoveAttrDefault (rel );
1701
+
1702
+ if (constr -> num_check > 0 )
1703
+ RemoveRelCheck (rel );
1704
+
1574
1705
return ;
1575
1706
}