Re: pgsql: Have numeric 0 ^ 4.3 return 1, rather than an error, and have 0 ^ - Mailing list pgsql-committers
From | Bruce Momjian |
---|---|
Subject | Re: pgsql: Have numeric 0 ^ 4.3 return 1, rather than an error, and have 0 ^ |
Date | |
Msg-id | 200805082218.m48MI0E19032@momjian.us Whole thread Raw |
In response to | Re: pgsql: Have numeric 0 ^ 4.3 return 1, rather than an error, and have 0 ^ (Neil Conway <neilc@samurai.com>) |
List | pgsql-committers |
Neil Conway wrote: > On Thu, 2008-05-08 at 19:25 +0000, Bruce Momjian wrote: > > Have numeric 0 ^ 4.3 return 1, rather than an error, and have 0 ^ 0.0 > > return 1, rather than error. > > A regression test for this behavior would be useful, I think. Done, plus I wasn't happy with the original patch so I redid it to be more modular, also attached. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + If your life is a hard drive, Christ can be your backup. + Index: src/backend/utils/adt/numeric.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v retrieving revision 1.111 diff -c -c -r1.111 numeric.c *** src/backend/utils/adt/numeric.c 8 May 2008 19:25:38 -0000 1.111 --- src/backend/utils/adt/numeric.c 8 May 2008 22:16:55 -0000 *************** *** 5170,5190 **** int local_rscale; double val; - /* - * This avoids log(0) for cases of 0 raised to a non-integer. - * Also, while 0 ^ 0 can be either 1 or indeterminate (error), we - * treat it as one because most programming languages do this. - * http://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power - */ - if (cmp_var(base, &const_zero) == 0) - { - if (cmp_var(exp, &const_zero) == 0) - set_var_from_var(&const_one, result); - else - set_var_from_var(&const_zero, result); - return; - } - /* If exp can be represented as an integer, use power_var_int */ if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1) { --- 5170,5175 ---- *************** *** 5217,5222 **** --- 5202,5218 ---- free_var(&x); } + /* + * This avoids log(0) for cases of 0 raised to a non-integer. + * 0 ^ 0 handled by power_var_int(). + */ + if (cmp_var(base, &const_zero) == 0) + { + set_var_from_var(&const_zero, result); + result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */ + return; + } + init_var(&ln_base); init_var(&ln_num); *************** *** 5284,5289 **** --- 5280,5290 ---- switch (exp) { case 0: + /* + * While 0 ^ 0 can be either 1 or indeterminate (error), we + * treat it as 1 because most programming languages do this. + * http://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power + */ set_var_from_var(&const_one, result); result->dscale = rscale; /* no need to round */ return; Index: src/test/regress/expected/float8.out =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/expected/float8.out,v retrieving revision 1.25 diff -c -c -r1.25 float8.out *** src/test/regress/expected/float8.out 2 Jan 2007 20:00:50 -0000 1.25 --- src/test/regress/expected/float8.out 8 May 2008 22:16:56 -0000 *************** *** 349,354 **** --- 349,360 ---- ERROR: value out of range: overflow SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f; ERROR: value out of range: overflow + SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5; + ?column? + ---------- + 2 + (1 row) + SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ; ERROR: cannot take logarithm of zero SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ; Index: src/test/regress/sql/float8.sql =================================================================== RCS file: /cvsroot/pgsql/src/test/regress/sql/float8.sql,v retrieving revision 1.15 diff -c -c -r1.15 float8.sql *** src/test/regress/sql/float8.sql 8 Jun 2005 21:15:29 -0000 1.15 --- src/test/regress/sql/float8.sql 8 May 2008 22:16:56 -0000 *************** *** 129,134 **** --- 129,136 ---- SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f; + SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5; + SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ; SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ;
pgsql-committers by date: