@@ -174,11 +174,7 @@ is_infinite(double val)
174
174
175
175
176
176
/*
177
- * float4in - converts "num" to float
178
- * restricted syntax:
179
- * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
180
- * where <sp> is a space, digit is 0-9,
181
- * <exp> is "e" or "E" followed by an integer.
177
+ * float4in - converts "num" to float4
182
178
*/
183
179
Datum
184
180
float4in (PG_FUNCTION_ARGS )
@@ -195,6 +191,10 @@ float4in(PG_FUNCTION_ARGS)
195
191
*/
196
192
orig_num = num ;
197
193
194
+ /* skip leading whitespace */
195
+ while (* num != '\0' && isspace ((unsigned char ) * num ))
196
+ num ++ ;
197
+
198
198
/*
199
199
* Check for an empty-string input to begin with, to avoid the vagaries of
200
200
* strtod() on different platforms.
@@ -205,20 +205,23 @@ float4in(PG_FUNCTION_ARGS)
205
205
errmsg ("invalid input syntax for type real: \"%s\"" ,
206
206
orig_num )));
207
207
208
- /* skip leading whitespace */
209
- while (* num != '\0' && isspace ((unsigned char ) * num ))
210
- num ++ ;
211
-
212
208
errno = 0 ;
213
209
val = strtod (num , & endptr );
214
210
215
211
/* did we not see anything that looks like a double? */
216
212
if (endptr == num || errno != 0 )
217
213
{
214
+ int save_errno = errno ;
215
+
218
216
/*
219
- * C99 requires that strtod() accept NaN and [-]Infinity, but not all
220
- * platforms support that yet (and some accept them but set ERANGE
221
- * anyway...) Therefore, we check for these inputs ourselves.
217
+ * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
218
+ * but not all platforms support all of these (and some accept them
219
+ * but set ERANGE anyway...) Therefore, we check for these inputs
220
+ * ourselves if strtod() fails.
221
+ *
222
+ * Note: C99 also requires hexadecimal input as well as some extended
223
+ * forms of NaN, but we consider these forms unportable and don't try
224
+ * to support them. You can use 'em if your strtod() takes 'em.
222
225
*/
223
226
if (pg_strncasecmp (num , "NaN" , 3 ) == 0 )
224
227
{
@@ -230,12 +233,32 @@ float4in(PG_FUNCTION_ARGS)
230
233
val = get_float4_infinity ();
231
234
endptr = num + 8 ;
232
235
}
236
+ else if (pg_strncasecmp (num , "+Infinity" , 9 ) == 0 )
237
+ {
238
+ val = get_float4_infinity ();
239
+ endptr = num + 9 ;
240
+ }
233
241
else if (pg_strncasecmp (num , "-Infinity" , 9 ) == 0 )
234
242
{
235
243
val = - get_float4_infinity ();
236
244
endptr = num + 9 ;
237
245
}
238
- else if (errno == ERANGE )
246
+ else if (pg_strncasecmp (num , "inf" , 3 ) == 0 )
247
+ {
248
+ val = get_float4_infinity ();
249
+ endptr = num + 3 ;
250
+ }
251
+ else if (pg_strncasecmp (num , "+inf" , 4 ) == 0 )
252
+ {
253
+ val = get_float4_infinity ();
254
+ endptr = num + 4 ;
255
+ }
256
+ else if (pg_strncasecmp (num , "-inf" , 4 ) == 0 )
257
+ {
258
+ val = - get_float4_infinity ();
259
+ endptr = num + 4 ;
260
+ }
261
+ else if (save_errno == ERANGE )
239
262
ereport (ERROR ,
240
263
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
241
264
errmsg ("\"%s\" is out of range for type real" ,
@@ -273,6 +296,11 @@ float4in(PG_FUNCTION_ARGS)
273
296
val = get_float4_infinity ();
274
297
endptr = num + 8 ;
275
298
}
299
+ else if (pg_strncasecmp (num , "+Infinity" , 9 ) == 0 )
300
+ {
301
+ val = get_float4_infinity ();
302
+ endptr = num + 9 ;
303
+ }
276
304
else if (pg_strncasecmp (num , "-Infinity" , 9 ) == 0 )
277
305
{
278
306
val = - get_float4_infinity ();
@@ -368,10 +396,6 @@ float4send(PG_FUNCTION_ARGS)
368
396
369
397
/*
370
398
* float8in - converts "num" to float8
371
- * restricted syntax:
372
- * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
373
- * where <sp> is a space, digit is 0-9,
374
- * <exp> is "e" or "E" followed by an integer.
375
399
*/
376
400
Datum
377
401
float8in (PG_FUNCTION_ARGS )
@@ -388,6 +412,10 @@ float8in(PG_FUNCTION_ARGS)
388
412
*/
389
413
orig_num = num ;
390
414
415
+ /* skip leading whitespace */
416
+ while (* num != '\0' && isspace ((unsigned char ) * num ))
417
+ num ++ ;
418
+
391
419
/*
392
420
* Check for an empty-string input to begin with, to avoid the vagaries of
393
421
* strtod() on different platforms.
@@ -398,20 +426,23 @@ float8in(PG_FUNCTION_ARGS)
398
426
errmsg ("invalid input syntax for type double precision: \"%s\"" ,
399
427
orig_num )));
400
428
401
- /* skip leading whitespace */
402
- while (* num != '\0' && isspace ((unsigned char ) * num ))
403
- num ++ ;
404
-
405
429
errno = 0 ;
406
430
val = strtod (num , & endptr );
407
431
408
432
/* did we not see anything that looks like a double? */
409
433
if (endptr == num || errno != 0 )
410
434
{
435
+ int save_errno = errno ;
436
+
411
437
/*
412
- * C99 requires that strtod() accept NaN and [-]Infinity, but not all
413
- * platforms support that yet (and some accept them but set ERANGE
414
- * anyway...) Therefore, we check for these inputs ourselves.
438
+ * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
439
+ * but not all platforms support all of these (and some accept them
440
+ * but set ERANGE anyway...) Therefore, we check for these inputs
441
+ * ourselves if strtod() fails.
442
+ *
443
+ * Note: C99 also requires hexadecimal input as well as some extended
444
+ * forms of NaN, but we consider these forms unportable and don't try
445
+ * to support them. You can use 'em if your strtod() takes 'em.
415
446
*/
416
447
if (pg_strncasecmp (num , "NaN" , 3 ) == 0 )
417
448
{
@@ -423,12 +454,32 @@ float8in(PG_FUNCTION_ARGS)
423
454
val = get_float8_infinity ();
424
455
endptr = num + 8 ;
425
456
}
457
+ else if (pg_strncasecmp (num , "+Infinity" , 9 ) == 0 )
458
+ {
459
+ val = get_float8_infinity ();
460
+ endptr = num + 9 ;
461
+ }
426
462
else if (pg_strncasecmp (num , "-Infinity" , 9 ) == 0 )
427
463
{
428
464
val = - get_float8_infinity ();
429
465
endptr = num + 9 ;
430
466
}
431
- else if (errno == ERANGE )
467
+ else if (pg_strncasecmp (num , "inf" , 3 ) == 0 )
468
+ {
469
+ val = get_float8_infinity ();
470
+ endptr = num + 3 ;
471
+ }
472
+ else if (pg_strncasecmp (num , "+inf" , 4 ) == 0 )
473
+ {
474
+ val = get_float8_infinity ();
475
+ endptr = num + 4 ;
476
+ }
477
+ else if (pg_strncasecmp (num , "-inf" , 4 ) == 0 )
478
+ {
479
+ val = - get_float8_infinity ();
480
+ endptr = num + 4 ;
481
+ }
482
+ else if (save_errno == ERANGE )
432
483
ereport (ERROR ,
433
484
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
434
485
errmsg ("\"%s\" is out of range for type double precision" ,
@@ -466,6 +517,11 @@ float8in(PG_FUNCTION_ARGS)
466
517
val = get_float8_infinity ();
467
518
endptr = num + 8 ;
468
519
}
520
+ else if (pg_strncasecmp (num , "+Infinity" , 9 ) == 0 )
521
+ {
522
+ val = get_float8_infinity ();
523
+ endptr = num + 9 ;
524
+ }
469
525
else if (pg_strncasecmp (num , "-Infinity" , 9 ) == 0 )
470
526
{
471
527
val = - get_float8_infinity ();
0 commit comments