7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.16 1997/08/20 14:54:07 momjian Exp $
10
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.17 1997/08/21 01:36:09 vadim Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
81
81
#include "catalog/pg_variable.h"
82
82
#include "catalog/pg_log.h"
83
83
#include "catalog/pg_time.h"
84
+ #include "catalog/pg_attrdef.h"
84
85
#include "catalog/indexing.h"
85
86
#include "catalog/index.h"
86
87
#include "fmgr.h"
@@ -90,22 +91,6 @@ static void RelationFlushRelation(Relation *relationPtr,
90
91
static Relation RelationNameCacheGetRelation (char * relationName );
91
92
static void init_irels (void );
92
93
static void write_irels (void );
93
- /* non-export function prototypes */
94
- static void formrdesc (char * relationName , u_int natts ,
95
- FormData_pg_attribute att []);
96
- static HeapTuple ScanPgRelation (RelationBuildDescInfo buildinfo );
97
- static HeapTuple scan_pg_rel_seq (RelationBuildDescInfo buildinfo );
98
- static HeapTuple scan_pg_rel_ind (RelationBuildDescInfo buildinfo );
99
- static Relation AllocateRelationDesc (u_int natts , Form_pg_class relp );
100
- static void RelationBuildTupleDesc (RelationBuildDescInfo buildinfo ,
101
- Relation relation , AttributeTupleForm attp , u_int natts );
102
- static void build_tupdesc_seq (RelationBuildDescInfo buildinfo ,
103
- Relation relation , AttributeTupleForm attp , u_int natts );
104
- static void build_tupdesc_ind (RelationBuildDescInfo buildinfo ,
105
- Relation relation , AttributeTupleForm attp , u_int natts );
106
- static Relation RelationBuildDesc (RelationBuildDescInfo buildinfo );
107
- static void IndexedAccessMethodInitialize (Relation relation );
108
-
109
94
110
95
/* ----------------
111
96
* defines
@@ -254,6 +239,28 @@ typedef struct relnamecacheent {
254
239
} \
255
240
}
256
241
242
+ /* non-export function prototypes */
243
+ static void formrdesc (char * relationName , u_int natts ,
244
+ FormData_pg_attribute att []);
245
+
246
+ #if 0 /* See comments at line 1304 */
247
+ static void RelationFlushIndexes (Relation * r , Oid accessMethodId );
248
+ #endif
249
+
250
+ static HeapTuple ScanPgRelation (RelationBuildDescInfo buildinfo );
251
+ static HeapTuple scan_pg_rel_seq (RelationBuildDescInfo buildinfo );
252
+ static HeapTuple scan_pg_rel_ind (RelationBuildDescInfo buildinfo );
253
+ static Relation AllocateRelationDesc (u_int natts , Form_pg_class relp );
254
+ static void RelationBuildTupleDesc (RelationBuildDescInfo buildinfo ,
255
+ Relation relation , u_int natts );
256
+ static void build_tupdesc_seq (RelationBuildDescInfo buildinfo ,
257
+ Relation relation , u_int natts );
258
+ static void build_tupdesc_ind (RelationBuildDescInfo buildinfo ,
259
+ Relation relation , u_int natts );
260
+ static Relation RelationBuildDesc (RelationBuildDescInfo buildinfo );
261
+ static void IndexedAccessMethodInitialize (Relation relation );
262
+ static void AttrDefaultFetch (Relation relation );
263
+
257
264
/*
258
265
* newlyCreatedRelns -
259
266
* relations created during this transaction. We need to keep track of
@@ -268,7 +275,7 @@ static List *newlyCreatedRelns = NULL;
268
275
*/
269
276
270
277
271
- #ifdef NOT_USED /* XXX This doesn't seem to be used anywhere */
278
+ #if NOT_USED /* XXX This doesn't seem to be used anywhere */
272
279
/* --------------------------------
273
280
* BuildDescInfoError returns a string appropriate to
274
281
* the buildinfo passed to it
@@ -481,7 +488,6 @@ AllocateRelationDesc(u_int natts, Form_pg_class relp)
481
488
static void
482
489
RelationBuildTupleDesc (RelationBuildDescInfo buildinfo ,
483
490
Relation relation ,
484
- AttributeTupleForm attp ,
485
491
u_int natts )
486
492
{
487
493
/*
@@ -491,20 +497,26 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
491
497
*/
492
498
493
499
if (IsBootstrapProcessingMode ())
494
- build_tupdesc_seq (buildinfo , relation , attp , natts );
500
+ build_tupdesc_seq (buildinfo , relation , natts );
495
501
else
496
- build_tupdesc_ind (buildinfo , relation , attp , natts );
502
+ {
503
+ relation -> rd_att -> constr = (AttrConstr * ) palloc (sizeof (struct attrConstr ));
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;
507
+ build_tupdesc_ind (buildinfo , relation , natts );
508
+ }
497
509
}
498
510
499
511
static void
500
512
build_tupdesc_seq (RelationBuildDescInfo buildinfo ,
501
513
Relation relation ,
502
- AttributeTupleForm attp ,
503
514
u_int natts )
504
515
{
505
516
HeapTuple pg_attribute_tuple ;
506
517
Relation pg_attribute_desc ;
507
518
HeapScanDesc pg_attribute_scan ;
519
+ AttributeTupleForm attp ;
508
520
ScanKeyData key ;
509
521
int need ;
510
522
@@ -530,9 +542,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
530
542
* ----------------
531
543
*/
532
544
need = natts ;
533
- if (!relation -> rd_att -> constr )
534
- relation -> rd_att -> constr = (AttrConstr * ) palloc (sizeof (struct attrConstr ));
535
- relation -> rd_att -> constr -> has_not_null = false;
536
545
537
546
pg_attribute_tuple = heap_getnext (pg_attribute_scan , 0 , (Buffer * ) NULL );
538
547
while (HeapTupleIsValid (pg_attribute_tuple ) && need > 0 ) {
@@ -545,11 +554,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
545
554
memmove ((char * ) (relation -> rd_att -> attrs [attp -> attnum - 1 ]),
546
555
(char * ) attp ,
547
556
ATTRIBUTE_TUPLE_SIZE );
548
-
549
- /* Update if this attribute have a constraint */
550
- if (attp -> attnotnull )
551
- relation -> rd_att -> constr -> has_not_null = true;
552
-
553
557
need -- ;
554
558
}
555
559
pg_attribute_tuple = heap_getnext (pg_attribute_scan ,
@@ -571,26 +575,24 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
571
575
static void
572
576
build_tupdesc_ind (RelationBuildDescInfo buildinfo ,
573
577
Relation relation ,
574
- AttributeTupleForm attp ,
575
578
u_int natts )
576
579
{
577
580
Relation attrel ;
578
581
HeapTuple atttup ;
582
+ AttributeTupleForm attp ;
583
+ AttrDefault * attrdef = NULL ;
584
+ int ndef = 0 ;
579
585
int i ;
580
586
581
- if (!relation -> rd_att -> constr )
582
- relation -> rd_att -> constr = (AttrConstr * ) palloc (sizeof (struct attrConstr ));
583
- relation -> rd_att -> constr -> has_not_null = false;
584
-
585
587
attrel = heap_openr (AttributeRelationName );
586
588
587
589
for (i = 1 ; i <= relation -> rd_rel -> relnatts ; i ++ ) {
588
590
589
591
atttup = (HeapTuple ) AttributeNumIndexScan (attrel , relation -> rd_id , i );
590
592
591
593
if (!HeapTupleIsValid (atttup ))
592
- elog (WARN , "cannot find attribute %d of relation %.16s " , i ,
593
- & (relation -> rd_rel -> relname .data [0 ]));
594
+ elog (WARN , "cannot find attribute %d of relation %.*s " , i ,
595
+ NAMEDATALEN , & (relation -> rd_rel -> relname .data [0 ]));
594
596
attp = (AttributeTupleForm ) GETSTRUCT (atttup );
595
597
596
598
relation -> rd_att -> attrs [i - 1 ] =
@@ -602,10 +604,33 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
602
604
603
605
/* Update if this attribute have a constraint */
604
606
if (attp -> attnotnull )
605
- relation -> rd_att -> constr -> has_not_null = true;
607
+ relation -> rd_att -> constr -> has_not_null = true;
608
+
609
+ if (attp -> atthasdef )
610
+ {
611
+ if ( attrdef == NULL )
612
+ attrdef = (AttrDefault * ) palloc (relation -> rd_rel -> relnatts *
613
+ sizeof (AttrDefault ));
614
+ attrdef [ndef ].adnum = i ;
615
+ attrdef [ndef ].adbin = NULL ;
616
+ attrdef [ndef ].adsrc = NULL ;
617
+ ndef ++ ;
618
+ }
606
619
}
607
620
608
621
heap_close (attrel );
622
+
623
+ if ( ndef > 0 )
624
+ {
625
+ if ( ndef > relation -> rd_rel -> relnatts )
626
+ relation -> rd_att -> constr -> defval = (AttrDefault * )
627
+ repalloc (attrdef , ndef * sizeof (AttrDefault ));
628
+ else
629
+ relation -> rd_att -> constr -> defval = attrdef ;
630
+ relation -> rd_att -> constr -> num_defval = ndef ;
631
+ AttrDefaultFetch (relation );
632
+ }
633
+
609
634
}
610
635
611
636
/* --------------------------------
@@ -759,7 +784,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo)
759
784
Oid relid ;
760
785
Oid relam ;
761
786
Form_pg_class relp ;
762
- AttributeTupleForm attp = NULL ;
763
787
764
788
MemoryContext oldcxt ;
765
789
@@ -834,7 +858,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo)
834
858
* already allocated for it by AllocateRelationDesc.
835
859
* ----------------
836
860
*/
837
- RelationBuildTupleDesc (buildinfo , relation , attp , natts );
861
+ RelationBuildTupleDesc (buildinfo , relation , natts );
838
862
839
863
/* ----------------
840
864
* initialize rules that affect this relation
@@ -1346,7 +1370,7 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
1346
1370
}
1347
1371
}
1348
1372
1349
- #ifdef NOT_USED /* See comments at line 1304 */
1373
+ #if NOT_USED /* See comments at line 1304 */
1350
1374
/* --------------------------------
1351
1375
* RelationIdInvalidateRelationCacheByAccessMethodId
1352
1376
*
@@ -1576,6 +1600,95 @@ RelationInitialize(void)
1576
1600
MemoryContextSwitchTo (oldcxt );
1577
1601
}
1578
1602
1603
+ static void
1604
+ AttrDefaultFetch (Relation relation )
1605
+ {
1606
+ AttrDefault * attrdef = relation -> rd_att -> constr -> defval ;
1607
+ int ndef = relation -> rd_att -> constr -> num_defval ;
1608
+ Relation adrel ;
1609
+ Relation irel ;
1610
+ ScanKeyData skey ;
1611
+ HeapTuple tuple ;
1612
+ Form_pg_attrdef adform ;
1613
+ IndexScanDesc sd ;
1614
+ RetrieveIndexResult indexRes ;
1615
+ Buffer buffer ;
1616
+ ItemPointer iptr ;
1617
+ struct varlena * val ;
1618
+ bool isnull ;
1619
+ int found ;
1620
+ int i ;
1621
+
1622
+ ScanKeyEntryInitialize (& skey ,
1623
+ (bits16 )0x0 ,
1624
+ (AttrNumber )1 ,
1625
+ (RegProcedure )ObjectIdEqualRegProcedure ,
1626
+ ObjectIdGetDatum (relation -> rd_id ));
1627
+
1628
+ adrel = heap_openr (AttrDefaultRelationName );
1629
+ irel = index_openr (AttrDefaultIndex );
1630
+ sd = index_beginscan (irel , false, 1 , & skey );
1631
+ tuple = (HeapTuple )NULL ;
1632
+
1633
+ for (found = 0 ; ; )
1634
+ {
1635
+ indexRes = index_getnext (sd , ForwardScanDirection );
1636
+ if (!indexRes )
1637
+ break ;
1638
+
1639
+ iptr = & indexRes -> heap_iptr ;
1640
+ tuple = heap_fetch (adrel , NowTimeQual , iptr , & buffer );
1641
+ pfree (indexRes );
1642
+ if (!HeapTupleIsValid (tuple ))
1643
+ continue ;
1644
+ adform = (Form_pg_attrdef ) GETSTRUCT (tuple );
1645
+ for (i = 1 ; i <= ndef ; i ++ )
1646
+ {
1647
+ if ( adform -> adnum != attrdef [i ].adnum )
1648
+ continue ;
1649
+ if ( attrdef [i ].adsrc != NULL )
1650
+ elog (WARN , "AttrDefaultFetch: second record found for attr %.*s in rel %.*s" ,
1651
+ NAMEDATALEN , relation -> rd_att -> attrs [adform -> adnum - 1 ]-> attname .data ,
1652
+ NAMEDATALEN , relation -> rd_rel -> relname .data );
1653
+
1654
+ val = (struct varlena * ) fastgetattr (tuple ,
1655
+ Anum_pg_attrdef_adbin ,
1656
+ adrel -> rd_att , & isnull );
1657
+ if ( isnull )
1658
+ elog (WARN , "AttrDefaultFetch: adbin IS NULL for attr %.*s in rel %.*s" ,
1659
+ NAMEDATALEN , relation -> rd_att -> attrs [adform -> adnum - 1 ]-> attname .data ,
1660
+ NAMEDATALEN , relation -> rd_rel -> relname .data );
1661
+ attrdef [i ].adbin = textout (val );
1662
+ val = (struct varlena * ) fastgetattr (tuple ,
1663
+ Anum_pg_attrdef_adsrc ,
1664
+ adrel -> rd_att , & isnull );
1665
+ if ( isnull )
1666
+ elog (WARN , "AttrDefaultFetch: adsrc IS NULL for attr %.*s in rel %.*s" ,
1667
+ NAMEDATALEN , relation -> rd_att -> attrs [adform -> adnum - 1 ]-> attname .data ,
1668
+ NAMEDATALEN , relation -> rd_rel -> relname .data );
1669
+ attrdef [i ].adsrc = textout (val );
1670
+ found ++ ;
1671
+ }
1672
+
1673
+ if ( i > ndef )
1674
+ elog (WARN , "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s" ,
1675
+ adform -> adnum ,
1676
+ NAMEDATALEN , relation -> rd_rel -> relname .data );
1677
+ ReleaseBuffer (buffer );
1678
+ }
1679
+
1680
+ if ( found < ndef )
1681
+ elog (WARN , "AttrDefaultFetch: %d record not found for rel %.*s" ,
1682
+ ndef - found ,
1683
+ NAMEDATALEN , relation -> rd_rel -> relname .data );
1684
+
1685
+ index_endscan (sd );
1686
+ pfree (sd );
1687
+ index_close (irel );
1688
+ heap_close (adrel );
1689
+
1690
+ }
1691
+
1579
1692
/*
1580
1693
* init_irels(), write_irels() -- handle special-case initialization of
1581
1694
* index relation descriptors.
0 commit comments