8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.343 2008/11/09 21:24:32 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.344 2008/11/14 01:57:41 alvherre Exp $
12
12
*
13
13
*
14
14
* INTERFACE ROUTINES
@@ -478,6 +478,60 @@ CheckAttributeType(const char *attname, Oid atttypid)
478
478
}
479
479
}
480
480
481
+ /*
482
+ * InsertPgAttributeTuple
483
+ * Construct and insert a new tuple in pg_attribute.
484
+ *
485
+ * Caller has already opened and locked pg_attribute. new_attribute is the
486
+ * attribute to insert.
487
+ *
488
+ * indstate is the index state for CatalogIndexInsert. It can be passed as
489
+ * NULL, in which case we'll fetch the necessary info. (Don't do this when
490
+ * inserting multiple attributes, because it's a tad more expensive.)
491
+ */
492
+ void
493
+ InsertPgAttributeTuple (Relation pg_attribute_rel ,
494
+ Form_pg_attribute new_attribute ,
495
+ CatalogIndexState indstate )
496
+ {
497
+ Datum values [Natts_pg_attribute ];
498
+ bool nulls [Natts_pg_attribute ];
499
+ HeapTuple tup ;
500
+
501
+ /* This is a tad tedious, but way cleaner than what we used to do... */
502
+ memset (values , 0 , sizeof (values ));
503
+ memset (nulls , false, sizeof (nulls ));
504
+
505
+ values [Anum_pg_attribute_attrelid - 1 ] = ObjectIdGetDatum (new_attribute -> attrelid );
506
+ values [Anum_pg_attribute_attname - 1 ] = NameGetDatum (& new_attribute -> attname );
507
+ values [Anum_pg_attribute_atttypid - 1 ] = ObjectIdGetDatum (new_attribute -> atttypid );
508
+ values [Anum_pg_attribute_attstattarget - 1 ] = Int32GetDatum (new_attribute -> attstattarget );
509
+ values [Anum_pg_attribute_attlen - 1 ] = Int16GetDatum (new_attribute -> attlen );
510
+ values [Anum_pg_attribute_attnum - 1 ] = Int16GetDatum (new_attribute -> attnum );
511
+ values [Anum_pg_attribute_attndims - 1 ] = Int32GetDatum (new_attribute -> attndims );
512
+ values [Anum_pg_attribute_attcacheoff - 1 ] = Int32GetDatum (new_attribute -> attcacheoff );
513
+ values [Anum_pg_attribute_atttypmod - 1 ] = Int32GetDatum (new_attribute -> atttypmod );
514
+ values [Anum_pg_attribute_attbyval - 1 ] = BoolGetDatum (new_attribute -> attbyval );
515
+ values [Anum_pg_attribute_attstorage - 1 ] = CharGetDatum (new_attribute -> attstorage );
516
+ values [Anum_pg_attribute_attalign - 1 ] = CharGetDatum (new_attribute -> attalign );
517
+ values [Anum_pg_attribute_attnotnull - 1 ] = BoolGetDatum (new_attribute -> attnotnull );
518
+ values [Anum_pg_attribute_atthasdef - 1 ] = BoolGetDatum (new_attribute -> atthasdef );
519
+ values [Anum_pg_attribute_attisdropped - 1 ] = BoolGetDatum (new_attribute -> attisdropped );
520
+ values [Anum_pg_attribute_attislocal - 1 ] = BoolGetDatum (new_attribute -> attislocal );
521
+ values [Anum_pg_attribute_attinhcount - 1 ] = Int32GetDatum (new_attribute -> attinhcount );
522
+
523
+ tup = heap_form_tuple (RelationGetDescr (pg_attribute_rel ), values , nulls );
524
+
525
+ /* finally insert the new tuple, update the indexes, and clean up */
526
+ simple_heap_insert (pg_attribute_rel , tup );
527
+
528
+ if (indstate != NULL )
529
+ CatalogIndexInsert (indstate , tup );
530
+ else
531
+ CatalogUpdateIndexes (pg_attribute_rel , tup );
532
+
533
+ heap_freetuple (tup );
534
+ }
481
535
/* --------------------------------
482
536
* AddNewAttributeTuples
483
537
*
@@ -492,9 +546,8 @@ AddNewAttributeTuples(Oid new_rel_oid,
492
546
bool oidislocal ,
493
547
int oidinhcount )
494
548
{
495
- const Form_pg_attribute * dpp ;
549
+ Form_pg_attribute attr ;
496
550
int i ;
497
- HeapTuple tup ;
498
551
Relation rel ;
499
552
CatalogIndexState indstate ;
500
553
int natts = tupdesc -> natts ;
@@ -512,35 +565,25 @@ AddNewAttributeTuples(Oid new_rel_oid,
512
565
* First we add the user attributes. This is also a convenient place to
513
566
* add dependencies on their datatypes.
514
567
*/
515
- dpp = tupdesc -> attrs ;
516
568
for (i = 0 ; i < natts ; i ++ )
517
569
{
570
+ attr = tupdesc -> attrs [i ];
518
571
/* Fill in the correct relation OID */
519
- ( * dpp ) -> attrelid = new_rel_oid ;
572
+ attr -> attrelid = new_rel_oid ;
520
573
/* Make sure these are OK, too */
521
- (* dpp )-> attstattarget = -1 ;
522
- (* dpp )-> attcacheoff = -1 ;
523
-
524
- tup = heap_addheader (Natts_pg_attribute ,
525
- false,
526
- ATTRIBUTE_TUPLE_SIZE ,
527
- (void * ) * dpp );
528
-
529
- simple_heap_insert (rel , tup );
530
-
531
- CatalogIndexInsert (indstate , tup );
574
+ attr -> attstattarget = -1 ;
575
+ attr -> attcacheoff = -1 ;
532
576
533
- heap_freetuple ( tup );
577
+ InsertPgAttributeTuple ( rel , attr , indstate );
534
578
579
+ /* Add dependency info */
535
580
myself .classId = RelationRelationId ;
536
581
myself .objectId = new_rel_oid ;
537
582
myself .objectSubId = i + 1 ;
538
583
referenced .classId = TypeRelationId ;
539
- referenced .objectId = ( * dpp ) -> atttypid ;
584
+ referenced .objectId = attr -> atttypid ;
540
585
referenced .objectSubId = 0 ;
541
586
recordDependencyOn (& myself , & referenced , DEPENDENCY_NORMAL );
542
-
543
- dpp ++ ;
544
587
}
545
588
546
589
/*
@@ -550,43 +593,28 @@ AddNewAttributeTuples(Oid new_rel_oid,
550
593
*/
551
594
if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE )
552
595
{
553
- dpp = SysAtt ;
554
- for (i = 0 ; i < (int ) lengthof (SysAtt ); i ++ , dpp ++ )
596
+ for (i = 0 ; i < (int ) lengthof (SysAtt ); i ++ )
555
597
{
556
- if (tupdesc -> tdhasoid ||
557
- (* dpp )-> attnum != ObjectIdAttributeNumber )
558
- {
559
- Form_pg_attribute attStruct ;
560
-
561
- tup = heap_addheader (Natts_pg_attribute ,
562
- false,
563
- ATTRIBUTE_TUPLE_SIZE ,
564
- (void * ) * dpp );
565
- attStruct = (Form_pg_attribute ) GETSTRUCT (tup );
566
-
567
- /* Fill in the correct relation OID in the copied tuple */
568
- attStruct -> attrelid = new_rel_oid ;
598
+ FormData_pg_attribute attStruct ;
569
599
570
- /* Fill in correct inheritance info for the OID column */
571
- if (attStruct -> attnum == ObjectIdAttributeNumber )
572
- {
573
- attStruct -> attislocal = oidislocal ;
574
- attStruct -> attinhcount = oidinhcount ;
575
- }
576
-
577
- /*
578
- * Unneeded since they should be OK in the constant data
579
- * anyway
580
- */
581
- /* attStruct->attstattarget = 0; */
582
- /* attStruct->attcacheoff = -1; */
600
+ /* skip OID where appropriate */
601
+ if (!tupdesc -> tdhasoid &&
602
+ SysAtt [i ]-> attnum == ObjectIdAttributeNumber )
603
+ continue ;
583
604
584
- simple_heap_insert ( rel , tup );
605
+ memcpy ( & attStruct , ( char * ) SysAtt [ i ], sizeof ( FormData_pg_attribute ) );
585
606
586
- CatalogIndexInsert (indstate , tup );
607
+ /* Fill in the correct relation OID in the copied tuple */
608
+ attStruct .attrelid = new_rel_oid ;
587
609
588
- heap_freetuple (tup );
610
+ /* Fill in correct inheritance info for the OID column */
611
+ if (attStruct .attnum == ObjectIdAttributeNumber )
612
+ {
613
+ attStruct .attislocal = oidislocal ;
614
+ attStruct .attinhcount = oidinhcount ;
589
615
}
616
+
617
+ InsertPgAttributeTuple (rel , & attStruct , indstate );
590
618
}
591
619
}
592
620
0 commit comments