@@ -163,17 +163,35 @@ Datum
163163float4in (PG_FUNCTION_ARGS )
164164{
165165 char * num = PG_GETARG_CSTRING (0 );
166- Node * escontext = fcinfo -> context ;
167- char * orig_num ;
166+
167+ PG_RETURN_FLOAT4 (float4in_internal (num , NULL , "real" , num ,
168+ fcinfo -> context ));
169+ }
170+
171+ /*
172+ * float4in_internal - guts of float4in()
173+ *
174+ * This is exposed for use by functions that want a reasonably
175+ * platform-independent way of inputting floats. The behavior is
176+ * essentially like strtof + ereturn on error.
177+ *
178+ * Uses the same API as float8in_internal below, so most of its
179+ * comments also apply here, except regarding use in geometric types.
180+ */
181+ float4
182+ float4in_internal (char * num , char * * endptr_p ,
183+ const char * type_name , const char * orig_string ,
184+ struct Node * escontext )
185+ {
168186 float val ;
169187 char * endptr ;
170188
171189 /*
172190 * endptr points to the first character _after_ the sequence we recognized
173- * as a valid floating point number. orig_num points to the original input
191+ * as a valid floating point number. orig_string points to the original
192+ * input
174193 * string.
175194 */
176- orig_num = num ;
177195
178196 /* skip leading whitespace */
179197 while (* num != '\0' && isspace ((unsigned char ) * num ))
@@ -184,10 +202,10 @@ float4in(PG_FUNCTION_ARGS)
184202 * strtod() on different platforms.
185203 */
186204 if (* num == '\0' )
187- ereturn (escontext , ( Datum ) 0 ,
205+ ereturn (escontext , 0 ,
188206 (errcode (ERRCODE_INVALID_TEXT_REPRESENTATION ),
189207 errmsg ("invalid input syntax for type %s: \"%s\"" ,
190- "real" , orig_num )));
208+ type_name , orig_string )));
191209
192210 errno = 0 ;
193211 val = strtof (num , & endptr );
@@ -258,30 +276,39 @@ float4in(PG_FUNCTION_ARGS)
258276 (val >= HUGE_VALF || val <= - HUGE_VALF )
259277#endif
260278 )
261- ereturn (escontext , (Datum ) 0 ,
279+ {
280+ /* see comments in float8in_internal for rationale */
281+ char * errnumber = pstrdup (num );
282+
283+ errnumber [endptr - num ] = '\0' ;
284+
285+ ereturn (escontext , 0 ,
262286 (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
263287 errmsg ("\"%s\" is out of range for type real" ,
264- orig_num )));
288+ errnumber )));
289+ }
265290 }
266291 else
267- ereturn (escontext , ( Datum ) 0 ,
292+ ereturn (escontext , 0 ,
268293 (errcode (ERRCODE_INVALID_TEXT_REPRESENTATION ),
269294 errmsg ("invalid input syntax for type %s: \"%s\"" ,
270- "real" , orig_num )));
295+ type_name , orig_string )));
271296 }
272297
273298 /* skip trailing whitespace */
274299 while (* endptr != '\0' && isspace ((unsigned char ) * endptr ))
275300 endptr ++ ;
276301
277- /* if there is any junk left at the end of the string, bail out */
278- if (* endptr != '\0' )
279- ereturn (escontext , (Datum ) 0 ,
302+ /* report stopping point if wanted, else complain if not end of string */
303+ if (endptr_p )
304+ * endptr_p = endptr ;
305+ else if (* endptr != '\0' )
306+ ereturn (escontext , 0 ,
280307 (errcode (ERRCODE_INVALID_TEXT_REPRESENTATION ),
281308 errmsg ("invalid input syntax for type %s: \"%s\"" ,
282- "real" , orig_num )));
309+ type_name , orig_string )));
283310
284- PG_RETURN_FLOAT4 ( val ) ;
311+ return val ;
285312}
286313
287314/*
0 commit comments