~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-security

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-11 16:59:35 UTC
  • mfrom: (5.1.1 karmic)
  • Revision ID: james.westby@ubuntu.com-20090711165935-jfwin6gfrxf0gfsi
Tags: 8.4.0-2
* debian/libpq-dev.install: Ship catalog/genbki.h. (Closes: #536139)
* debian/rules: Drop --enable-cassert for final release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 * Copyright (c) 1998-2009, PostgreSQL Global Development Group
15
15
 *
16
16
 * IDENTIFICATION
17
 
 *        $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.117 2009/04/08 22:08:40 tgl Exp $
 
17
 *        $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.118 2009/06/11 14:49:03 momjian Exp $
18
18
 *
19
19
 *-------------------------------------------------------------------------
20
20
 */
90
90
 
91
91
 
92
92
/* ----------
93
 
 * NumericVar is the format we use for arithmetic.  The digit-array part
 
93
 * NumericVar is the format we use for arithmetic.      The digit-array part
94
94
 * is the same as the NumericData storage format, but the header is more
95
95
 * complex.
96
96
 *
243
243
static void zero_var(NumericVar *var);
244
244
 
245
245
static const char *set_var_from_str(const char *str, const char *cp,
246
 
                                                                        NumericVar *dest);
 
246
                                 NumericVar *dest);
247
247
static void set_var_from_num(Numeric value, NumericVar *dest);
248
248
static void set_var_from_var(NumericVar *value, NumericVar *dest);
249
249
static char *get_str_from_var(NumericVar *var, int dscale);
271
271
static void div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
272
272
                int rscale, bool round);
273
273
static void div_var_fast(NumericVar *var1, NumericVar *var2, NumericVar *result,
274
 
                int rscale, bool round);
 
274
                         int rscale, bool round);
275
275
static int      select_div_scale(NumericVar *var1, NumericVar *var2);
276
276
static void mod_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
277
277
static void ceil_var(NumericVar *var, NumericVar *result);
348
348
                        if (!isspace((unsigned char) *cp))
349
349
                                ereport(ERROR,
350
350
                                                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
351
 
                                         errmsg("invalid input syntax for type numeric: \"%s\"",
352
 
                                                        str)));
 
351
                                          errmsg("invalid input syntax for type numeric: \"%s\"",
 
352
                                                         str)));
353
353
                        cp++;
354
354
                }
355
355
        }
367
367
                /*
368
368
                 * We duplicate a few lines of code here because we would like to
369
369
                 * throw any trailing-junk syntax error before any semantic error
370
 
                 * resulting from apply_typmod.  We can't easily fold the two
371
 
                 * cases together because we mustn't apply apply_typmod to a NaN.
 
370
                 * resulting from apply_typmod.  We can't easily fold the two cases
 
371
                 * together because we mustn't apply apply_typmod to a NaN.
372
372
                 */
373
373
                while (*cp)
374
374
                {
375
375
                        if (!isspace((unsigned char) *cp))
376
376
                                ereport(ERROR,
377
377
                                                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
378
 
                                         errmsg("invalid input syntax for type numeric: \"%s\"",
379
 
                                                        str)));
 
378
                                          errmsg("invalid input syntax for type numeric: \"%s\"",
 
379
                                                         str)));
380
380
                        cp++;
381
381
                }
382
382
 
1938
1938
 
1939
1939
        /*
1940
1940
         * The SQL spec requires that we emit a particular SQLSTATE error code for
1941
 
         * certain error conditions.  Specifically, we don't return a divide-by-zero
1942
 
         * error code for 0 ^ -1.
 
1941
         * certain error conditions.  Specifically, we don't return a
 
1942
         * divide-by-zero error code for 0 ^ -1.
1943
1943
         */
1944
1944
        if (cmp_var(&arg1, &const_zero) == 0 &&
1945
1945
                cmp_var(&arg2, &const_zero) < 0)
2654
2654
        /*
2655
2655
         * If we're invoked by nodeAgg, we can cheat and modify our first
2656
2656
         * parameter in-place to avoid palloc overhead. If not, we need to return
2657
 
         * the new value of the transition variable.
2658
 
         * (If int8 is pass-by-value, then of course this is useless as well
2659
 
         * as incorrect, so just ifdef it out.)
 
2657
         * the new value of the transition variable. (If int8 is pass-by-value,
 
2658
         * then of course this is useless as well as incorrect, so just ifdef it
 
2659
         * out.)
2660
2660
         */
2661
2661
#ifndef USE_FLOAT8_BYVAL                /* controls int8 too */
2662
2662
        if (fcinfo->context &&
2705
2705
        /*
2706
2706
         * If we're invoked by nodeAgg, we can cheat and modify our first
2707
2707
         * parameter in-place to avoid palloc overhead. If not, we need to return
2708
 
         * the new value of the transition variable.
2709
 
         * (If int8 is pass-by-value, then of course this is useless as well
2710
 
         * as incorrect, so just ifdef it out.)
 
2708
         * the new value of the transition variable. (If int8 is pass-by-value,
 
2709
         * then of course this is useless as well as incorrect, so just ifdef it
 
2710
         * out.)
2711
2711
         */
2712
2712
#ifndef USE_FLOAT8_BYVAL                /* controls int8 too */
2713
2713
        if (fcinfo->context &&
4209
4209
        /* If rounding needed, figure one more digit to ensure correct result */
4210
4210
        if (round)
4211
4211
                res_ndigits++;
 
4212
 
4212
4213
        /*
4213
4214
         * The working dividend normally requires res_ndigits + var2ndigits
4214
4215
         * digits, but make it at least var1ndigits so we can load all of var1
4222
4223
        /*
4223
4224
         * We need a workspace with room for the working dividend (div_ndigits+1
4224
4225
         * digits) plus room for the possibly-normalized divisor (var2ndigits
4225
 
         * digits).  It is convenient also to have a zero at divisor[0] with
4226
 
         * the actual divisor data in divisor[1 .. var2ndigits].  Transferring the
 
4226
         * digits).  It is convenient also to have a zero at divisor[0] with the
 
4227
         * actual divisor data in divisor[1 .. var2ndigits].  Transferring the
4227
4228
         * digits into the workspace also allows us to realloc the result (which
4228
4229
         * might be the same as either input var) before we begin the main loop.
4229
4230
         * Note that we use palloc0 to ensure that divisor[0], dividend[0], and
4244
4245
        if (var2ndigits == 1)
4245
4246
        {
4246
4247
                /*
4247
 
                 * If there's only a single divisor digit, we can use a fast path
4248
 
                 * (cf. Knuth section 4.3.1 exercise 16).
 
4248
                 * If there's only a single divisor digit, we can use a fast path (cf.
 
4249
                 * Knuth section 4.3.1 exercise 16).
4249
4250
                 */
4250
4251
                divisor1 = divisor[1];
4251
4252
                carry = 0;
4264
4265
                 *
4265
4266
                 * We need the first divisor digit to be >= NBASE/2.  If it isn't,
4266
4267
                 * make it so by scaling up both the divisor and dividend by the
4267
 
                 * factor "d".  (The reason for allocating dividend[0] above is to
 
4268
                 * factor "d".  (The reason for allocating dividend[0] above is to
4268
4269
                 * leave room for possible carry here.)
4269
4270
                 */
4270
4271
                if (divisor[1] < HALF_NBASE)
4271
4272
                {
4272
 
                        int             d = NBASE / (divisor[1] + 1);
 
4273
                        int                     d = NBASE / (divisor[1] + 1);
4273
4274
 
4274
4275
                        carry = 0;
4275
4276
                        for (i = var2ndigits; i > 0; i--)
4295
4296
                divisor2 = divisor[2];
4296
4297
 
4297
4298
                /*
4298
 
                 * Begin the main loop.  Each iteration of this loop produces the
4299
 
                 * j'th quotient digit by dividing dividend[j .. j + var2ndigits]
4300
 
                 * by the divisor; this is essentially the same as the common manual
 
4299
                 * Begin the main loop.  Each iteration of this loop produces the j'th
 
4300
                 * quotient digit by dividing dividend[j .. j + var2ndigits] by the
 
4301
                 * divisor; this is essentially the same as the common manual
4301
4302
                 * procedure for long division.
4302
4303
                 */
4303
4304
                for (j = 0; j < res_ndigits; j++)
4304
4305
                {
4305
4306
                        /* Estimate quotient digit from the first two dividend digits */
4306
 
                        int             next2digits = dividend[j] * NBASE + dividend[j+1];
4307
 
                        int             qhat;
 
4307
                        int                     next2digits = dividend[j] * NBASE + dividend[j + 1];
 
4308
                        int                     qhat;
4308
4309
 
4309
4310
                        /*
4310
4311
                         * If next2digits are 0, then quotient digit must be 0 and there's
4311
 
                         * no need to adjust the working dividend.  It's worth testing
4312
 
                         * here to fall out ASAP when processing trailing zeroes in
4313
 
                         * a dividend.
 
4312
                         * no need to adjust the working dividend.      It's worth testing
 
4313
                         * here to fall out ASAP when processing trailing zeroes in a
 
4314
                         * dividend.
4314
4315
                         */
4315
4316
                        if (next2digits == 0)
4316
4317
                        {
4322
4323
                                qhat = NBASE - 1;
4323
4324
                        else
4324
4325
                                qhat = next2digits / divisor1;
 
4326
 
4325
4327
                        /*
4326
4328
                         * Adjust quotient digit if it's too large.  Knuth proves that
4327
 
                         * after this step, the quotient digit will be either correct
4328
 
                         * or just one too large.  (Note: it's OK to use dividend[j+2]
4329
 
                         * here because we know the divisor length is at least 2.)
 
4329
                         * after this step, the quotient digit will be either correct or
 
4330
                         * just one too large.  (Note: it's OK to use dividend[j+2] here
 
4331
                         * because we know the divisor length is at least 2.)
4330
4332
                         */
4331
4333
                        while (divisor2 * qhat >
4332
 
                                   (next2digits - qhat * divisor1) * NBASE + dividend[j+2])
 
4334
                                   (next2digits - qhat * divisor1) * NBASE + dividend[j + 2])
4333
4335
                                qhat--;
4334
4336
 
4335
4337
                        /* As above, need do nothing more when quotient digit is 0 */
5253
5255
        }
5254
5256
 
5255
5257
        /*
5256
 
         *      This avoids log(0) for cases of 0 raised to a non-integer.
5257
 
         *      0 ^ 0 handled by power_var_int().
 
5258
         * This avoids log(0) for cases of 0 raised to a non-integer. 0 ^ 0
 
5259
         * handled by power_var_int().
5258
5260
         */
5259
5261
        if (cmp_var(base, &const_zero) == 0)
5260
5262
        {
5261
5263
                set_var_from_var(&const_zero, result);
5262
 
                result->dscale = NUMERIC_MIN_SIG_DIGITS;        /* no need to round */
 
5264
                result->dscale = NUMERIC_MIN_SIG_DIGITS;                /* no need to round */
5263
5265
                return;
5264
5266
        }
5265
 
        
 
5267
 
5266
5268
        init_var(&ln_base);
5267
5269
        init_var(&ln_num);
5268
5270
 
5330
5332
        switch (exp)
5331
5333
        {
5332
5334
                case 0:
 
5335
 
5333
5336
                        /*
5334
 
                         *      While 0 ^ 0 can be either 1 or indeterminate (error), we
5335
 
                         *      treat it as 1 because most programming languages do this.
5336
 
                         *      SQL:2003 also requires a return value of 1.
5337
 
                         *      http://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
 
5337
                         * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
 
5338
                         * it as 1 because most programming languages do this. SQL:2003
 
5339
                         * also requires a return value of 1.
 
5340
                         * http://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_pow
 
5341
                         * er
5338
5342
                         */
5339
5343
                        set_var_from_var(&const_one, result);
5340
5344
                        result->dscale = rscale;        /* no need to round */