77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.20 1997/08/21 03:01:21 momjian Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.21 1997/08/22 02:58:51 vadim Exp $
1111 *
1212 * INTERFACE ROUTINES
1313 *heap_creatr()- Create an uncataloged heap relation
3939#include <catalog/pg_proc.h>
4040#include <catalog/pg_index.h>
4141#include <catalog/pg_type.h>
42+ #include <catalog/pg_attrdef.h>
43+ #include <catalog/pg_relcheck.h>
4244#include <storage/bufmgr.h>
4345#include <storage/lmgr.h>
4446#include <storage/smgr.h>
4547#include <parser/catalog_utils.h>
48+ #include <parser/parse_query.h>
4649#include <rewrite/rewriteRemove.h>
4750#include <utils/builtins.h>
4851#include <utils/mcxt.h>
@@ -64,6 +67,9 @@ static void RelationRemoveIndexes(Relation relation);
6467static void RelationRemoveInheritance (Relation relation );
6568static void RemoveFromTempRelList (Relation r );
6669static void addNewRelationType (char * typeName ,Oid new_rel_oid );
70+ static void StoreConstraints (Relation rel );
71+ static void StoreAttrDefault (Relation rel ,AttrDefault * attrdef );
72+ static void StoreRelCheck (Relation rel ,ConstrCheck * check );
6773
6874
6975/* ----------------------------------------------------------------
@@ -272,7 +278,7 @@ heap_creatr(char *name,
272278/* ----------
273279 create a new tuple descriptor from the one passed in
274280 */
275- rdesc -> rd_att = CreateTupleDescCopy (tupDesc );
281+ rdesc -> rd_att = CreateTupleDescCopyConstr (tupDesc );
276282
277283/* ----------------
278284 *initialize the fields of our new relation descriptor
@@ -298,6 +304,8 @@ heap_creatr(char *name,
298304rdesc -> rd_rel -> relkind = RELKIND_UNCATALOGED ;
299305rdesc -> rd_rel -> relnatts = natts ;
300306rdesc -> rd_rel -> relsmgr = smgr ;
307+ if (tupDesc -> constr )
308+ rdesc -> rd_rel -> relchecks = tupDesc -> constr -> num_check ;
301309
302310for (i = 0 ;i < natts ;i ++ ) {
303311rdesc -> rd_att -> attrs [i ]-> attrelid = relid ;
@@ -814,6 +822,8 @@ heap_create(char relname[],
814822arch ,
815823natts );
816824
825+ StoreConstraints (new_rel_desc );
826+
817827/* ----------------
818828 *ok, the relation has been cataloged, so close our relations
819829 * and return the oid of the newly created relation.
@@ -1458,3 +1468,108 @@ DestroyTempRels(void)
14581468tempRels = NULL ;
14591469}
14601470
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+ extern List * flatten_tlist (List * tlist );
1496+ extern List * pg_plan (char * query_string ,Oid * typev ,int nargs ,
1497+ QueryTreeList * * queryListP ,CommandDest dest );
1498+
1499+ static void
1500+ StoreAttrDefault (Relation rel ,AttrDefault * attrdef )
1501+ {
1502+ char str [MAX_PARSE_BUFFER ];
1503+ char cast [2 * NAMEDATALEN ]= {0 };
1504+ AttributeTupleForm atp = rel -> rd_att -> attrs [attrdef -> adnum - 1 ];
1505+ QueryTreeList * queryTree_list ;
1506+ Query * query ;
1507+ List * planTree_list ;
1508+ TargetEntry * te ;
1509+ Resdom * resdom ;
1510+ Node * expr ;
1511+ char * adbin ;
1512+ MemoryContext oldcxt ;
1513+ Relation adrel ;
1514+ Relation idescs [Num_pg_attrdef_indices ];
1515+ HeapTuple tuple ;
1516+ Datum values [4 ];
1517+ char nulls [4 ]= {' ' ,' ' ,' ' ,' ' };
1518+ extern GlobalMemory CacheCxt ;
1519+
1520+ start :;
1521+ sprintf (str ,"select %s%s from %.*s" ,attrdef -> adsrc ,cast ,
1522+ NAMEDATALEN ,rel -> rd_rel -> relname .data );
1523+ planTree_list = (List * )pg_plan (str ,NULL ,0 ,& queryTree_list ,None );
1524+ query = (Query * ) (queryTree_list -> qtrees [0 ]);
1525+
1526+ if (length (query -> rtable )> 1 ||
1527+ flatten_tlist (query -> targetList )!= NIL )
1528+ elog (WARN ,"AttributeDefault: cannot use attribute(s)" );
1529+ te = (TargetEntry * )lfirst (query -> targetList );
1530+ resdom = te -> resdom ;
1531+ expr = te -> expr ;
1532+
1533+ if (IsA (expr ,Const ) )
1534+ {
1535+ if ( ((Const * )expr )-> consttype != atp -> atttypid )
1536+ {
1537+ if (* cast != 0 )
1538+ elog (WARN ,"AttributeDefault: casting failed - const type mismatched" );
1539+ sprintf (cast ,":: %s" ,get_id_typname (atp -> atttypid ));
1540+ gotostart ;
1541+ }
1542+ }
1543+ else if (exprType (expr )!= atp -> atttypid )
1544+ elog (WARN ,"AttributeDefault: type mismatched" );
1545+
1546+ adbin = nodeToString (expr );
1547+ oldcxt = MemoryContextSwitchTo ((MemoryContext )CacheCxt );
1548+ attrdef -> adbin = (char * )palloc (strlen (adbin )+ 1 );
1549+ strcpy (attrdef -> adbin ,adbin );
1550+ (void )MemoryContextSwitchTo (oldcxt );
1551+ pfree (adbin );
1552+
1553+ values [Anum_pg_attrdef_adrelid - 1 ]= rel -> rd_id ;
1554+ values [Anum_pg_attrdef_adnum - 1 ]= attrdef -> adnum ;
1555+ values [Anum_pg_attrdef_adbin - 1 ]= PointerGetDatum (textin (attrdef -> adbin ));
1556+ values [Anum_pg_attrdef_adsrc - 1 ]= PointerGetDatum (textin (attrdef -> adsrc ));
1557+ adrel = heap_openr (AttrDefaultRelationName );
1558+ tuple = heap_formtuple (adrel -> rd_att ,values ,nulls );
1559+ CatalogOpenIndices (Num_pg_attrdef_indices ,Name_pg_attrdef_indices ,idescs );
1560+ heap_insert (adrel ,tuple );
1561+ CatalogIndexInsert (idescs ,Num_pg_attrdef_indices ,adrel ,tuple );
1562+ CatalogCloseIndices (Num_pg_attrdef_indices ,idescs );
1563+
1564+ pfree (DatumGetPointer (values [Anum_pg_attrdef_adbin - 1 ]));
1565+ pfree (DatumGetPointer (values [Anum_pg_attrdef_adsrc - 1 ]));
1566+ pfree (tuple );
1567+
1568+ }
1569+
1570+ static void
1571+ StoreRelCheck (Relation rel ,ConstrCheck * check )
1572+ {
1573+
1574+ return ;
1575+ }