~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to src/backend/utils/adt/float.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-10-09 10:28:08 UTC
  • mfrom: (1.4.1) (12.1.8 lucid-security)
  • Revision ID: package-import@ubuntu.com-20131009102808-zrhonpfn94r34fho
Tags: 8.4.18-0ubuntu10.04
New upstream bug fix release (LP: #1237248). No security issues or
critical issues this time; see HISTORY/changelog.gz for details about bug
fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
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
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
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
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
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
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
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
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
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();