77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.18 1997/08/21 04:09:51 vadim Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.19 1997/08/22 03:35:44 vadim Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
8282#include "catalog/pg_log.h"
8383#include "catalog/pg_time.h"
8484#include "catalog/pg_attrdef.h"
85+ #include "catalog/pg_relcheck.h"
8586#include "catalog/indexing.h"
8687#include "catalog/index.h"
8788#include "fmgr.h"
@@ -260,6 +261,7 @@ static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
260261static Relation RelationBuildDesc (RelationBuildDescInfo buildinfo );
261262static void IndexedAccessMethodInitialize (Relation relation );
262263static void AttrDefaultFetch (Relation relation );
264+ static void RelCheckFetch (Relation relation );
263265
264266/*
265267 * newlyCreatedRelns -
@@ -482,7 +484,7 @@ AllocateRelationDesc(u_int natts, Form_pg_class relp)
482484 *RelationBuildTupleDesc
483485 *
484486 *Form the relation's tuple descriptor from information in
485- *the pg_attribute systemcatalog .
487+ *the pg_attribute, pg_attrdef & pg_relcheck systemcataloges .
486488 * --------------------------------
487489 */
488490static void
@@ -499,13 +501,7 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
499501if (IsBootstrapProcessingMode ())
500502build_tupdesc_seq (buildinfo ,relation ,natts );
501503else
502- {
503- relation -> rd_att -> constr = (TupleConstr * )palloc (sizeof (TupleConstr ));
504- relation -> rd_att -> constr -> num_check = 0 ;
505- relation -> rd_att -> constr -> num_defval = 0 ;
506- relation -> rd_att -> constr -> has_not_null = false;
507504build_tupdesc_ind (buildinfo ,relation ,natts );
508- }
509505}
510506
511507static void
@@ -580,10 +576,13 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
580576Relation attrel ;
581577HeapTuple atttup ;
582578AttributeTupleForm attp ;
579+ TupleConstr * constr = (TupleConstr * )palloc (sizeof (TupleConstr ));
583580AttrDefault * attrdef = NULL ;
584581int ndef = 0 ;
585582int i ;
586-
583+
584+ constr -> has_not_null = false;
585+
587586attrel = heap_openr (AttributeRelationName );
588587
589588for (i = 1 ;i <=relation -> rd_rel -> relnatts ;i ++ ) {
@@ -604,7 +603,7 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
604603
605604/* Update if this attribute have a constraint */
606605if (attp -> attnotnull )
607- relation -> rd_att -> constr -> has_not_null = true;
606+ constr -> has_not_null = true;
608607
609608if (attp -> atthasdef )
610609{
@@ -619,16 +618,39 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
619618 }
620619
621620heap_close (attrel );
622-
623- if (ndef > 0 )
621+
622+ if (constr -> has_not_null || ndef > 0 || relation -> rd_rel -> relchecks )
624623 {
625- if (ndef > relation -> rd_rel -> relnatts )
626- relation -> rd_att -> constr -> defval = (AttrDefault * )
624+ relation -> rd_att -> constr = constr ;
625+
626+ if (ndef > 0 )/* DEFAULTs */
627+ {
628+ if (ndef < relation -> rd_rel -> relnatts )
629+ constr -> defval = (AttrDefault * )
627630repalloc (attrdef ,ndef * sizeof (AttrDefault ));
631+ else
632+ constr -> defval = attrdef ;
633+ constr -> num_defval = ndef ;
634+ AttrDefaultFetch (relation );
635+ }
628636else
629- relation -> rd_att -> constr -> defval = attrdef ;
630- relation -> rd_att -> constr -> num_defval = ndef ;
631- AttrDefaultFetch (relation );
637+ constr -> num_defval = 0 ;
638+
639+ if (relation -> rd_rel -> relchecks > 0 )/* CHECKs */
640+ {
641+ constr -> num_check = relation -> rd_rel -> relchecks ;
642+ constr -> check = (ConstrCheck * )palloc (constr -> num_check *
643+ sizeof (ConstrCheck ));
644+ memset (constr -> check ,0 ,constr -> num_check * sizeof (ConstrCheck ));
645+ RelCheckFetch (relation );
646+ }
647+ else
648+ constr -> num_check = 0 ;
649+ }
650+ else
651+ {
652+ pfree (constr );
653+ relation -> rd_att -> constr = NULL ;
632654 }
633655
634656}
@@ -1252,8 +1274,6 @@ static void
12521274RelationFlushRelation (Relation * relationPtr ,
12531275bool onlyFlushReferenceCountZero )
12541276{
1255- int i ;
1256- AttributeTupleForm * p ;
12571277MemoryContext oldcxt ;
12581278Relation relation = * relationPtr ;
12591279
@@ -1268,14 +1288,8 @@ RelationFlushRelation(Relation *relationPtr,
12681288oldcxt = MemoryContextSwitchTo ((MemoryContext )CacheCxt );
12691289
12701290RelationCacheDelete (relation );
1271-
1272- p = relation -> rd_att -> attrs ;
1273- for (i = 0 ;i < relation -> rd_rel -> relnatts ;i ++ ,p ++ )
1274- pfree (* p );
1275- pfree (relation -> rd_att -> attrs );
1276- if (relation -> rd_att -> constr )
1277- pfree (relation -> rd_att -> constr );
1278- pfree (relation -> rd_att );
1291+
1292+ FreeTupleDesc (relation -> rd_att );
12791293
12801294#if 0
12811295if (relation -> rd_rules ) {
@@ -1641,8 +1655,9 @@ AttrDefaultFetch (Relation relation)
16411655pfree (indexRes );
16421656if (!HeapTupleIsValid (tuple ))
16431657continue ;
1658+ found ++ ;
16441659adform = (Form_pg_attrdef )GETSTRUCT (tuple );
1645- for (i = 1 ;i <= ndef ;i ++ )
1660+ for (i = 0 ;i < ndef ;i ++ )
16461661 {
16471662if (adform -> adnum != attrdef [i ].adnum )
16481663continue ;
@@ -1667,10 +1682,10 @@ AttrDefaultFetch (Relation relation)
16671682NAMEDATALEN ,relation -> rd_att -> attrs [adform -> adnum - 1 ]-> attname .data ,
16681683NAMEDATALEN ,relation -> rd_rel -> relname .data );
16691684attrdef [i ].adsrc = textout (val );
1670- found ++ ;
1685+ break ;
16711686 }
16721687
1673- if (i > ndef )
1688+ if (i >= ndef )
16741689elog (WARN ,"AttrDefaultFetch: unexpected record found for attr %d in rel %.*s" ,
16751690adform -> adnum ,
16761691NAMEDATALEN ,relation -> rd_rel -> relname .data );
@@ -1689,6 +1704,88 @@ AttrDefaultFetch (Relation relation)
16891704
16901705}
16911706
1707+ static void
1708+ RelCheckFetch (Relation relation )
1709+ {
1710+ ConstrCheck * check = relation -> rd_att -> constr -> check ;
1711+ int ncheck = relation -> rd_att -> constr -> num_check ;
1712+ Relation rcrel ;
1713+ Relation irel ;
1714+ ScanKeyData skey ;
1715+ HeapTuple tuple ;
1716+ IndexScanDesc sd ;
1717+ RetrieveIndexResult indexRes ;
1718+ Buffer buffer ;
1719+ ItemPointer iptr ;
1720+ Name rcname ;
1721+ struct varlena * val ;
1722+ bool isnull ;
1723+ int found ;
1724+
1725+ ScanKeyEntryInitialize (& skey ,
1726+ (bits16 )0x0 ,
1727+ (AttrNumber )1 ,
1728+ (RegProcedure )ObjectIdEqualRegProcedure ,
1729+ ObjectIdGetDatum (relation -> rd_id ));
1730+
1731+ rcrel = heap_openr (RelCheckRelationName );
1732+ irel = index_openr (RelCheckIndex );
1733+ sd = index_beginscan (irel , false,1 ,& skey );
1734+ tuple = (HeapTuple )NULL ;
1735+
1736+ for (found = 0 ; ; )
1737+ {
1738+ indexRes = index_getnext (sd ,ForwardScanDirection );
1739+ if (!indexRes )
1740+ break ;
1741+
1742+ iptr = & indexRes -> heap_iptr ;
1743+ tuple = heap_fetch (rcrel ,NowTimeQual ,iptr ,& buffer );
1744+ pfree (indexRes );
1745+ if (!HeapTupleIsValid (tuple ))
1746+ continue ;
1747+ if (found == ncheck )
1748+ elog (WARN ,"RelCheckFetch: unexpected record found for rel %.*s" ,
1749+ NAMEDATALEN ,relation -> rd_rel -> relname .data );
1750+
1751+ rcname = (Name )fastgetattr (tuple ,
1752+ Anum_pg_relcheck_rcname ,
1753+ rcrel -> rd_att ,& isnull );
1754+ if (isnull )
1755+ elog (WARN ,"RelCheckFetch: rcname IS NULL for rel %.*s" ,
1756+ NAMEDATALEN ,relation -> rd_rel -> relname .data );
1757+ check [found ].ccname = nameout (rcname );
1758+ val = (struct varlena * )fastgetattr (tuple ,
1759+ Anum_pg_relcheck_rcbin ,
1760+ rcrel -> rd_att ,& isnull );
1761+ if (isnull )
1762+ elog (WARN ,"RelCheckFetch: rcbin IS NULL for rel %.*s" ,
1763+ NAMEDATALEN ,relation -> rd_rel -> relname .data );
1764+ check [found ].ccbin = textout (val );
1765+ val = (struct varlena * )fastgetattr (tuple ,
1766+ Anum_pg_relcheck_rcsrc ,
1767+ rcrel -> rd_att ,& isnull );
1768+ if (isnull )
1769+ elog (WARN ,"RelCheckFetch: rcsrc IS NULL for rel %.*s" ,
1770+ NAMEDATALEN ,relation -> rd_rel -> relname .data );
1771+ check [found ].ccsrc = textout (val );
1772+ found ++ ;
1773+
1774+ ReleaseBuffer (buffer );
1775+ }
1776+
1777+ if (found < ncheck )
1778+ elog (WARN ,"RelCheckFetch: %d record not found for rel %.*s" ,
1779+ ncheck - found ,
1780+ NAMEDATALEN ,relation -> rd_rel -> relname .data );
1781+
1782+ index_endscan (sd );
1783+ pfree (sd );
1784+ index_close (irel );
1785+ heap_close (rcrel );
1786+
1787+ }
1788+
16921789/*
16931790 * init_irels(), write_irels() -- handle special-case initialization of
16941791 * index relation descriptors.