@@ -175,11 +175,7 @@ is_infinite(double val)
175175
176176
177177/*
178- *float4in- converts "num" to float
179- * restricted syntax:
180- * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
181- * where <sp> is a space, digit is 0-9,
182- * <exp> is "e" or "E" followed by an integer.
178+ *float4in- converts "num" to float4
183179 */
184180Datum
185181float4in (PG_FUNCTION_ARGS )
@@ -196,6 +192,10 @@ float4in(PG_FUNCTION_ARGS)
196192 */
197193orig_num = num ;
198194
195+ /* skip leading whitespace */
196+ while (* num != '\0' && isspace ((unsignedchar )* num ))
197+ num ++ ;
198+
199199/*
200200 * Check for an empty-string input to begin with, to avoid the vagaries of
201201 * strtod() on different platforms.
@@ -206,20 +206,23 @@ float4in(PG_FUNCTION_ARGS)
206206errmsg ("invalid input syntax for type real: \"%s\"" ,
207207orig_num )));
208208
209- /* skip leading whitespace */
210- while (* num != '\0' && isspace ((unsignedchar )* num ))
211- num ++ ;
212-
213209errno = 0 ;
214210val = strtod (num ,& endptr );
215211
216212/* did we not see anything that looks like a double? */
217213if (endptr == num || errno != 0 )
218214{
215+ int save_errno = errno ;
216+
219217/*
220- * C99 requires that strtod() accept NaN and [-]Infinity, but not all
221- * platforms support that yet (and some accept them but set ERANGE
222- * anyway...) Therefore, we check for these inputs ourselves.
218+ * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
219+ * but not all platforms support all of these (and some accept them
220+ * but set ERANGE anyway...) Therefore, we check for these inputs
221+ * ourselves if strtod() fails.
222+ *
223+ * Note: C99 also requires hexadecimal input as well as some extended
224+ * forms of NaN, but we consider these forms unportable and don't try
225+ * to support them. You can use 'em if your strtod() takes 'em.
223226 */
224227if (pg_strncasecmp (num ,"NaN" ,3 )== 0 )
225228{
@@ -231,12 +234,32 @@ float4in(PG_FUNCTION_ARGS)
231234val = get_float4_infinity ();
232235endptr = num + 8 ;
233236}
237+ else if (pg_strncasecmp (num ,"+Infinity" ,9 )== 0 )
238+ {
239+ val = get_float4_infinity ();
240+ endptr = num + 9 ;
241+ }
234242else if (pg_strncasecmp (num ,"-Infinity" ,9 )== 0 )
235243{
236244val = - get_float4_infinity ();
237245endptr = num + 9 ;
238246}
239- else if (errno == ERANGE )
247+ else if (pg_strncasecmp (num ,"inf" ,3 )== 0 )
248+ {
249+ val = get_float4_infinity ();
250+ endptr = num + 3 ;
251+ }
252+ else if (pg_strncasecmp (num ,"+inf" ,4 )== 0 )
253+ {
254+ val = get_float4_infinity ();
255+ endptr = num + 4 ;
256+ }
257+ else if (pg_strncasecmp (num ,"-inf" ,4 )== 0 )
258+ {
259+ val = - get_float4_infinity ();
260+ endptr = num + 4 ;
261+ }
262+ else if (save_errno == ERANGE )
240263ereport (ERROR ,
241264(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
242265errmsg ("\"%s\" is out of range for type real" ,
@@ -274,6 +297,11 @@ float4in(PG_FUNCTION_ARGS)
274297val = get_float4_infinity ();
275298endptr = num + 8 ;
276299}
300+ else if (pg_strncasecmp (num ,"+Infinity" ,9 )== 0 )
301+ {
302+ val = get_float4_infinity ();
303+ endptr = num + 9 ;
304+ }
277305else if (pg_strncasecmp (num ,"-Infinity" ,9 )== 0 )
278306{
279307val = - get_float4_infinity ();
@@ -369,10 +397,6 @@ float4send(PG_FUNCTION_ARGS)
369397
370398/*
371399 *float8in- converts "num" to float8
372- * restricted syntax:
373- * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
374- * where <sp> is a space, digit is 0-9,
375- * <exp> is "e" or "E" followed by an integer.
376400 */
377401Datum
378402float8in (PG_FUNCTION_ARGS )
@@ -389,6 +413,10 @@ float8in(PG_FUNCTION_ARGS)
389413 */
390414orig_num = num ;
391415
416+ /* skip leading whitespace */
417+ while (* num != '\0' && isspace ((unsignedchar )* num ))
418+ num ++ ;
419+
392420/*
393421 * Check for an empty-string input to begin with, to avoid the vagaries of
394422 * strtod() on different platforms.
@@ -399,20 +427,23 @@ float8in(PG_FUNCTION_ARGS)
399427errmsg ("invalid input syntax for type double precision: \"%s\"" ,
400428orig_num )));
401429
402- /* skip leading whitespace */
403- while (* num != '\0' && isspace ((unsignedchar )* num ))
404- num ++ ;
405-
406430errno = 0 ;
407431val = strtod (num ,& endptr );
408432
409433/* did we not see anything that looks like a double? */
410434if (endptr == num || errno != 0 )
411435{
436+ int save_errno = errno ;
437+
412438/*
413- * C99 requires that strtod() accept NaN and [-]Infinity, but not all
414- * platforms support that yet (and some accept them but set ERANGE
415- * anyway...) Therefore, we check for these inputs ourselves.
439+ * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
440+ * but not all platforms support all of these (and some accept them
441+ * but set ERANGE anyway...) Therefore, we check for these inputs
442+ * ourselves if strtod() fails.
443+ *
444+ * Note: C99 also requires hexadecimal input as well as some extended
445+ * forms of NaN, but we consider these forms unportable and don't try
446+ * to support them. You can use 'em if your strtod() takes 'em.
416447 */
417448if (pg_strncasecmp (num ,"NaN" ,3 )== 0 )
418449{
@@ -424,12 +455,32 @@ float8in(PG_FUNCTION_ARGS)
424455val = get_float8_infinity ();
425456endptr = num + 8 ;
426457}
458+ else if (pg_strncasecmp (num ,"+Infinity" ,9 )== 0 )
459+ {
460+ val = get_float8_infinity ();
461+ endptr = num + 9 ;
462+ }
427463else if (pg_strncasecmp (num ,"-Infinity" ,9 )== 0 )
428464{
429465val = - get_float8_infinity ();
430466endptr = num + 9 ;
431467}
432- else if (errno == ERANGE )
468+ else if (pg_strncasecmp (num ,"inf" ,3 )== 0 )
469+ {
470+ val = get_float8_infinity ();
471+ endptr = num + 3 ;
472+ }
473+ else if (pg_strncasecmp (num ,"+inf" ,4 )== 0 )
474+ {
475+ val = get_float8_infinity ();
476+ endptr = num + 4 ;
477+ }
478+ else if (pg_strncasecmp (num ,"-inf" ,4 )== 0 )
479+ {
480+ val = - get_float8_infinity ();
481+ endptr = num + 4 ;
482+ }
483+ else if (save_errno == ERANGE )
433484ereport (ERROR ,
434485(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
435486errmsg ("\"%s\" is out of range for type double precision" ,
@@ -467,6 +518,11 @@ float8in(PG_FUNCTION_ARGS)
467518val = get_float8_infinity ();
468519endptr = num + 8 ;
469520}
521+ else if (pg_strncasecmp (num ,"+Infinity" ,9 )== 0 )
522+ {
523+ val = get_float8_infinity ();
524+ endptr = num + 9 ;
525+ }
470526else if (pg_strncasecmp (num ,"-Infinity" ,9 )== 0 )
471527{
472528val = - get_float8_infinity ();