@@ -48,55 +48,87 @@ unit_get_definitions(void)
48
48
int i ;
49
49
unit_names_t * unit_name ;
50
50
unit_dimensions_t * unit_dim ;
51
+ static HTAB * tmp_unit_names ;
52
+ static HTAB * tmp_unit_dimensions ;
51
53
52
- /* unit_names : char *name -> Unit unit
54
+ /* tmp_unit_names : char *name -> Unit unit
53
55
* Lookup table that initially contains the base units and will cache all
54
56
* units resolved at run time
55
57
*/
56
58
hinfo .keysize = UNIT_NAME_LENGTH ;
57
59
hinfo .entrysize = sizeof (unit_names_t );
58
60
Assert (UNIT_NAME_LENGTH + sizeof (UnitShift ) == sizeof (unit_names_t ));
59
- unit_names = hash_create ("unit_names" ,
61
+ tmp_unit_names = hash_create ("unit_names" ,
60
62
20 ,
61
63
& hinfo ,
62
64
HASH_ELEM ); /* Set keysize and entrysize */
63
65
64
- for ( i = 0 ; derived_units [ i ]. name ; i ++ )
66
+ PG_TRY ();
65
67
{
66
- if (derived_units [i ].flags & U_DERIVED )
67
- break ; // FIXME: split tables
68
- unit_name = hash_search (unit_names ,
69
- derived_units [i ].name ,
70
- HASH_ENTER ,
71
- NULL );
72
- strlcpy (unit_name -> name , derived_units [i ].name , UNIT_NAME_LENGTH );
73
- unit_name -> unit_shift .unit .value = derived_units [i ].factor ;
74
- memcpy (unit_name -> unit_shift .unit .units , derived_units [i ].units , N_UNITS );
75
- unit_name -> unit_shift .shift = 0.0 ;
68
+ for (i = 0 ; derived_units [i ].name ; i ++ )
69
+ {
70
+ if (derived_units [i ].flags & U_DERIVED )
71
+ break ; // FIXME: split tables
72
+ unit_name = hash_search (tmp_unit_names ,
73
+ derived_units [i ].name ,
74
+ HASH_ENTER ,
75
+ NULL );
76
+ strlcpy (unit_name -> name , derived_units [i ].name , UNIT_NAME_LENGTH );
77
+ unit_name -> unit_shift .unit .value = derived_units [i ].factor ;
78
+ memcpy (unit_name -> unit_shift .unit .units , derived_units [i ].units , N_UNITS );
79
+ unit_name -> unit_shift .shift = 0.0 ;
80
+ }
81
+ }
82
+ PG_CATCH ();
83
+ {
84
+ /* free partially initialized table */
85
+ hash_destroy (tmp_unit_names );
86
+ PG_RE_THROW ();
76
87
}
88
+ PG_END_TRY ();
89
+
90
+ /* No OOM errors were thrown, use the new table */
91
+ if (unit_names )
92
+ hash_destroy (unit_names );
93
+ unit_names = tmp_unit_names ;
77
94
78
- /* unit_dimensions : char dimension[N_UNITS] -> char *name
95
+ /* tmp_unit_dimensions : char dimension[N_UNITS] -> char *name
79
96
* Lookup table for formatting the well-known derived units on output
80
97
*/
81
98
hinfo .keysize = N_UNITS ;
82
99
hinfo .entrysize = sizeof (unit_dimensions_t );
83
100
Assert (N_UNITS + UNIT_NAME_LENGTH == sizeof (unit_dimensions_t ));
84
- unit_dimensions = hash_create ("unit_dimensions" ,
101
+ tmp_unit_dimensions = hash_create ("unit_dimensions" ,
85
102
20 ,
86
103
& hinfo ,
87
104
HASH_ELEM | HASH_BLOBS );
88
105
89
- for ( i = 0 ; derived_units [ i ]. name ; i ++ )
106
+ PG_TRY ();
90
107
{
91
- if (! derived_units [i ].flags & U_DERIVED )
92
- continue ;
93
- unit_dim = hash_search (unit_dimensions ,
94
- derived_units [i ].units ,
95
- HASH_ENTER ,
96
- NULL );
97
- memcpy (unit_dim -> units , derived_units [i ].units , N_UNITS );
98
- strlcpy (unit_dim -> name , derived_units [i ].name , UNIT_NAME_LENGTH );
108
+ for (i = 0 ; derived_units [i ].name ; i ++ )
109
+ {
110
+ if (! derived_units [i ].flags & U_DERIVED )
111
+ continue ;
112
+ unit_dim = hash_search (tmp_unit_dimensions ,
113
+ derived_units [i ].units ,
114
+ HASH_ENTER ,
115
+ NULL );
116
+ memcpy (unit_dim -> units , derived_units [i ].units , N_UNITS );
117
+ strlcpy (unit_dim -> name , derived_units [i ].name , UNIT_NAME_LENGTH );
118
+ }
119
+ }
120
+ PG_CATCH ();
121
+ {
122
+ /* free partially initialized table */
123
+ hash_destroy (tmp_unit_dimensions );
124
+ PG_RE_THROW ();
99
125
}
126
+ PG_END_TRY ();
127
+
128
+ /* No OOM errors were thrown, use the new table */
129
+ if (unit_dimensions )
130
+ hash_destroy (unit_dimensions );
131
+ unit_dimensions = tmp_unit_dimensions ;
100
132
}
101
133
102
134
/* module initialization */
@@ -946,8 +978,6 @@ Datum
946
978
unit_reset (PG_FUNCTION_ARGS )
947
979
{
948
980
/* reinitialize hash tables */
949
- hash_destroy (unit_names );
950
- hash_destroy (unit_dimensions );
951
981
unit_get_definitions ();
952
982
953
983
PG_RETURN_VOID ();
0 commit comments