@@ -59,7 +59,7 @@ static void BootstrapModeMain(void);
59
59
static void bootstrap_signals (void );
60
60
static void ShutdownAuxiliaryProcess (int code , Datum arg );
61
61
static Form_pg_attribute AllocateAttribute (void );
62
- static void populate_typ_array (void );
62
+ static void populate_typ_list (void );
63
63
static Oid gettype (char * type );
64
64
static void cleanup (void );
65
65
@@ -160,7 +160,7 @@ struct typmap
160
160
FormData_pg_type am_typ ;
161
161
};
162
162
163
- static struct typmap * * Typ = NULL ;
163
+ static List * Typ = NIL ; /* List of struct typmap* */
164
164
static struct typmap * Ap = NULL ;
165
165
166
166
static Datum values [MAXATTR ]; /* current row's attribute values */
@@ -598,10 +598,10 @@ boot_openrel(char *relname)
598
598
599
599
/*
600
600
* pg_type must be filled before any OPEN command is executed, hence we
601
- * can now populate the Typ array if we haven't yet.
601
+ * can now populate Typ if we haven't yet.
602
602
*/
603
- if (Typ == NULL )
604
- populate_typ_array ();
603
+ if (Typ == NIL )
604
+ populate_typ_list ();
605
605
606
606
if (boot_reldesc != NULL )
607
607
closerel (NULL );
@@ -691,7 +691,7 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
691
691
692
692
typeoid = gettype (type );
693
693
694
- if (Typ != NULL )
694
+ if (Typ != NIL )
695
695
{
696
696
attrtypes [attnum ]-> atttypid = Ap -> am_oid ;
697
697
attrtypes [attnum ]-> attlen = Ap -> am_typ .typlen ;
@@ -873,47 +873,36 @@ cleanup(void)
873
873
}
874
874
875
875
/* ----------------
876
- * populate_typ_array
876
+ * populate_typ_list
877
877
*
878
- * Load the Typ array by reading pg_type.
878
+ * Load the Typ list by reading pg_type.
879
879
* ----------------
880
880
*/
881
881
static void
882
- populate_typ_array (void )
882
+ populate_typ_list (void )
883
883
{
884
884
Relation rel ;
885
885
TableScanDesc scan ;
886
886
HeapTuple tup ;
887
- int nalloc ;
888
- int i ;
889
-
890
- Assert (Typ == NULL );
887
+ MemoryContext old ;
891
888
892
- nalloc = 512 ;
893
- Typ = (struct typmap * * )
894
- MemoryContextAlloc (TopMemoryContext , nalloc * sizeof (struct typmap * ));
889
+ Assert (Typ == NIL );
895
890
896
891
rel = table_open (TypeRelationId , NoLock );
897
892
scan = table_beginscan_catalog (rel , 0 , NULL );
898
- i = 0 ;
893
+ old = MemoryContextSwitchTo ( TopMemoryContext ) ;
899
894
while ((tup = heap_getnext (scan , ForwardScanDirection )) != NULL )
900
895
{
901
896
Form_pg_type typForm = (Form_pg_type ) GETSTRUCT (tup );
897
+ struct typmap * newtyp ;
902
898
903
- /* make sure there will be room for a trailing NULL pointer */
904
- if (i >= nalloc - 1 )
905
- {
906
- nalloc *= 2 ;
907
- Typ = (struct typmap * * )
908
- repalloc (Typ , nalloc * sizeof (struct typmap * ));
909
- }
910
- Typ [i ] = (struct typmap * )
911
- MemoryContextAlloc (TopMemoryContext , sizeof (struct typmap ));
912
- Typ [i ]-> am_oid = typForm -> oid ;
913
- memcpy (& (Typ [i ]-> am_typ ), typForm , sizeof (Typ [i ]-> am_typ ));
914
- i ++ ;
899
+ newtyp = (struct typmap * ) palloc (sizeof (struct typmap ));
900
+ Typ = lappend (Typ , newtyp );
901
+
902
+ newtyp -> am_oid = typForm -> oid ;
903
+ memcpy (& newtyp -> am_typ , typForm , sizeof (newtyp -> am_typ ));
915
904
}
916
- Typ [ i ] = NULL ; /* Fill trailing NULL pointer */
905
+ MemoryContextSwitchTo ( old );
917
906
table_endscan (scan );
918
907
table_close (rel , NoLock );
919
908
}
@@ -923,25 +912,26 @@ populate_typ_array(void)
923
912
*
924
913
* NB: this is really ugly; it will return an integer index into TypInfo[],
925
914
* and not an OID at all, until the first reference to a type not known in
926
- * TypInfo[]. At that point it will read and cache pg_type in the Typ array ,
915
+ * TypInfo[]. At that point it will read and cache pg_type in Typ,
927
916
* and subsequently return a real OID (and set the global pointer Ap to
928
917
* point at the found row in Typ). So caller must check whether Typ is
929
- * still NULL to determine what the return value is!
918
+ * still NIL to determine what the return value is!
930
919
* ----------------
931
920
*/
932
921
static Oid
933
922
gettype (char * type )
934
923
{
935
- if (Typ != NULL )
924
+ if (Typ != NIL )
936
925
{
937
- struct typmap * * app ;
926
+ ListCell * lc ;
938
927
939
- for ( app = Typ ; * app != NULL ; app ++ )
928
+ foreach ( lc , Typ )
940
929
{
941
- if (strncmp (NameStr ((* app )-> am_typ .typname ), type , NAMEDATALEN ) == 0 )
930
+ struct typmap * app = lfirst (lc );
931
+ if (strncmp (NameStr (app -> am_typ .typname ), type , NAMEDATALEN ) == 0 )
942
932
{
943
- Ap = * app ;
944
- return ( * app ) -> am_oid ;
933
+ Ap = app ;
934
+ return app -> am_oid ;
945
935
}
946
936
}
947
937
}
@@ -956,7 +946,7 @@ gettype(char *type)
956
946
}
957
947
/* Not in TypInfo, so we'd better be able to read pg_type now */
958
948
elog (DEBUG4 , "external type: %s" , type );
959
- populate_typ_array ();
949
+ populate_typ_list ();
960
950
return gettype (type );
961
951
}
962
952
elog (ERROR , "unrecognized type \"%s\"" , type );
@@ -984,17 +974,20 @@ boot_get_type_io_data(Oid typid,
984
974
Oid * typinput ,
985
975
Oid * typoutput )
986
976
{
987
- if (Typ != NULL )
977
+ if (Typ != NIL )
988
978
{
989
979
/* We have the boot-time contents of pg_type, so use it */
990
- struct typmap * * app ;
991
- struct typmap * ap ;
992
-
993
- app = Typ ;
994
- while (* app && (* app )-> am_oid != typid )
995
- ++ app ;
996
- ap = * app ;
997
- if (ap == NULL )
980
+ struct typmap * ap = NULL ;
981
+ ListCell * lc ;
982
+
983
+ foreach (lc , Typ )
984
+ {
985
+ ap = lfirst (lc );
986
+ if (ap -> am_oid == typid )
987
+ break ;
988
+ }
989
+
990
+ if (!ap || ap -> am_oid != typid )
998
991
elog (ERROR , "type OID %u not found in Typ list" , typid );
999
992
1000
993
* typlen = ap -> am_typ .typlen ;
0 commit comments