@@ -175,11 +175,7 @@ is_infinite(double val)
175
175
176
176
177
177
/*
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
183
179
*/
184
180
Datum
185
181
float4in (PG_FUNCTION_ARGS )
@@ -196,6 +192,10 @@ float4in(PG_FUNCTION_ARGS)
196
192
*/
197
193
orig_num = num ;
198
194
195
+ /* skip leading whitespace */
196
+ while (* num != '\0' && isspace ((unsignedchar )* num ))
197
+ num ++ ;
198
+
199
199
/*
200
200
* Check for an empty-string input to begin with, to avoid the vagaries of
201
201
* strtod() on different platforms.
@@ -206,20 +206,23 @@ float4in(PG_FUNCTION_ARGS)
206
206
errmsg ("invalid input syntax for type real: \"%s\"" ,
207
207
orig_num )));
208
208
209
- /* skip leading whitespace */
210
- while (* num != '\0' && isspace ((unsignedchar )* num ))
211
- num ++ ;
212
-
213
209
errno = 0 ;
214
210
val = strtod (num ,& endptr );
215
211
216
212
/* did we not see anything that looks like a double? */
217
213
if (endptr == num || errno != 0 )
218
214
{
215
+ int save_errno = errno ;
216
+
219
217
/*
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.
223
226
*/
224
227
if (pg_strncasecmp (num ,"NaN" ,3 )== 0 )
225
228
{
@@ -231,12 +234,32 @@ float4in(PG_FUNCTION_ARGS)
231
234
val = get_float4_infinity ();
232
235
endptr = num + 8 ;
233
236
}
237
+ else if (pg_strncasecmp (num ,"+Infinity" ,9 )== 0 )
238
+ {
239
+ val = get_float4_infinity ();
240
+ endptr = num + 9 ;
241
+ }
234
242
else if (pg_strncasecmp (num ,"-Infinity" ,9 )== 0 )
235
243
{
236
244
val = - get_float4_infinity ();
237
245
endptr = num + 9 ;
238
246
}
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 )
240
263
ereport (ERROR ,
241
264
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
242
265
errmsg ("\"%s\" is out of range for type real" ,
@@ -274,6 +297,11 @@ float4in(PG_FUNCTION_ARGS)
274
297
val = get_float4_infinity ();
275
298
endptr = num + 8 ;
276
299
}
300
+ else if (pg_strncasecmp (num ,"+Infinity" ,9 )== 0 )
301
+ {
302
+ val = get_float4_infinity ();
303
+ endptr = num + 9 ;
304
+ }
277
305
else if (pg_strncasecmp (num ,"-Infinity" ,9 )== 0 )
278
306
{
279
307
val = - get_float4_infinity ();
@@ -369,10 +397,6 @@ float4send(PG_FUNCTION_ARGS)
369
397
370
398
/*
371
399
*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.
376
400
*/
377
401
Datum
378
402
float8in (PG_FUNCTION_ARGS )
@@ -389,6 +413,10 @@ float8in(PG_FUNCTION_ARGS)
389
413
*/
390
414
orig_num = num ;
391
415
416
+ /* skip leading whitespace */
417
+ while (* num != '\0' && isspace ((unsignedchar )* num ))
418
+ num ++ ;
419
+
392
420
/*
393
421
* Check for an empty-string input to begin with, to avoid the vagaries of
394
422
* strtod() on different platforms.
@@ -399,20 +427,23 @@ float8in(PG_FUNCTION_ARGS)
399
427
errmsg ("invalid input syntax for type double precision: \"%s\"" ,
400
428
orig_num )));
401
429
402
- /* skip leading whitespace */
403
- while (* num != '\0' && isspace ((unsignedchar )* num ))
404
- num ++ ;
405
-
406
430
errno = 0 ;
407
431
val = strtod (num ,& endptr );
408
432
409
433
/* did we not see anything that looks like a double? */
410
434
if (endptr == num || errno != 0 )
411
435
{
436
+ int save_errno = errno ;
437
+
412
438
/*
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.
416
447
*/
417
448
if (pg_strncasecmp (num ,"NaN" ,3 )== 0 )
418
449
{
@@ -424,12 +455,32 @@ float8in(PG_FUNCTION_ARGS)
424
455
val = get_float8_infinity ();
425
456
endptr = num + 8 ;
426
457
}
458
+ else if (pg_strncasecmp (num ,"+Infinity" ,9 )== 0 )
459
+ {
460
+ val = get_float8_infinity ();
461
+ endptr = num + 9 ;
462
+ }
427
463
else if (pg_strncasecmp (num ,"-Infinity" ,9 )== 0 )
428
464
{
429
465
val = - get_float8_infinity ();
430
466
endptr = num + 9 ;
431
467
}
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 )
433
484
ereport (ERROR ,
434
485
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
435
486
errmsg ("\"%s\" is out of range for type double precision" ,
@@ -467,6 +518,11 @@ float8in(PG_FUNCTION_ARGS)
467
518
val = get_float8_infinity ();
468
519
endptr = num + 8 ;
469
520
}
521
+ else if (pg_strncasecmp (num ,"+Infinity" ,9 )== 0 )
522
+ {
523
+ val = get_float8_infinity ();
524
+ endptr = num + 9 ;
525
+ }
470
526
else if (pg_strncasecmp (num ,"-Infinity" ,9 )== 0 )
471
527
{
472
528
val = - get_float8_infinity ();