77 *
88 *
99 * 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 $
1111 *
1212 * INTERFACE ROUTINES
1313 *heap_creatr()- Create an uncataloged heap relation
5050#include <utils/builtins.h>
5151#include <utils/mcxt.h>
5252#include <utils/relcache.h>
53+ #include <nodes/plannodes.h>
5354#ifndef HAVE_MEMMOVE
5455# include <regex/utils.h>
5556#else
@@ -68,8 +69,7 @@ static void RelationRemoveInheritance(Relation relation);
6869static void RemoveFromTempRelList (Relation r );
6970static void addNewRelationType (char * typeName ,Oid new_rel_oid );
7071static 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 );
7373
7474
7575/* ----------------------------------------------------------------
@@ -371,8 +371,10 @@ heap_creatr(char *name,
371371 *
372372 *6) AddPgRelationTuple() is called to register the
373373 * relation itself in the catalogs.
374+ *
375+ *7) StoreConstraints is called ()- vadim 08/22/97
374376 *
375- *7 ) the relations are closed and the new relation's oid
377+ *8 ) the relations are closed and the new relation's oid
376378 * is returned.
377379 *
378380 * old comments:
@@ -847,7 +849,8 @@ heap_create(char relname[],
847849 *4) remove pg_class tuple
848850 *5) remove pg_attribute tuples
849851 *6) remove pg_type tuples
850- *7) unlink relation
852+ *7) RemoveConstraints ()
853+ *8) unlink relation
851854 *
852855 * old comments
853856 *Except for vital relations, removes relation from
@@ -1327,6 +1330,8 @@ heap_destroy(char *relname)
13271330 * Does nothing!!! Flushing moved below.- vadim 06/04/97
13281331 RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);
13291332 */
1333+
1334+ RemoveConstraints (rdesc );
13301335
13311336/* ----------------
13321337 *unlink the relation and finish up.
@@ -1468,30 +1473,6 @@ DestroyTempRels(void)
14681473tempRels = NULL ;
14691474}
14701475
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-
14951476extern List * flatten_tlist (List * tlist );
14961477extern List * pg_plan (char * query_string ,Oid * typev ,int nargs ,
14971478QueryTreeList * * queryListP ,CommandDest dest );
@@ -1520,12 +1501,14 @@ StoreAttrDefault (Relation rel, AttrDefault *attrdef)
15201501start :;
15211502sprintf (str ,"select %s%s from %.*s" ,attrdef -> adsrc ,cast ,
15221503NAMEDATALEN ,rel -> rd_rel -> relname .data );
1504+ setheapoverride (true);
15231505planTree_list = (List * )pg_plan (str ,NULL ,0 ,& queryTree_list ,None );
1506+ setheapoverride (false);
15241507query = (Query * ) (queryTree_list -> qtrees [0 ]);
15251508
15261509if (length (query -> rtable )> 1 ||
15271510flatten_tlist (query -> targetList )!= NIL )
1528- elog (WARN ,"AttributeDefault : cannot use attribute(s)" );
1511+ elog (WARN ,"DEFAULT : cannot use attribute(s)" );
15291512te = (TargetEntry * )lfirst (query -> targetList );
15301513resdom = te -> resdom ;
15311514expr = te -> expr ;
@@ -1535,13 +1518,13 @@ start:;
15351518if ( ((Const * )expr )-> consttype != atp -> atttypid )
15361519 {
15371520if (* cast != 0 )
1538- elog (WARN ,"AttributeDefault: casting failed - const type mismatched" );
1521+ elog (WARN ,"DEFAULT: const type mismatched" );
15391522sprintf (cast ,":: %s" ,get_id_typname (atp -> atttypid ));
15401523 gotostart ;
15411524 }
15421525 }
15431526else if (exprType (expr )!= atp -> atttypid )
1544- elog (WARN ,"AttributeDefault : type mismatched" );
1527+ elog (WARN ,"DEFAULT : type mismatched" );
15451528
15461529adbin = nodeToString (expr );
15471530oldcxt = MemoryContextSwitchTo ((MemoryContext )CacheCxt );
@@ -1560,6 +1543,7 @@ start:;
15601543heap_insert (adrel ,tuple );
15611544CatalogIndexInsert (idescs ,Num_pg_attrdef_indices ,adrel ,tuple );
15621545CatalogCloseIndices (Num_pg_attrdef_indices ,idescs );
1546+ heap_close (adrel );
15631547
15641548pfree (DatumGetPointer (values [Anum_pg_attrdef_adbin - 1 ]));
15651549pfree (DatumGetPointer (values [Anum_pg_attrdef_adsrc - 1 ]));
@@ -1570,6 +1554,153 @@ start:;
15701554static void
15711555StoreRelCheck (Relation rel ,ConstrCheck * check )
15721556{
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+ }
15731690
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+
15741705return ;
15751706}