提交 4a586bd4 编写于 作者: B Bruce Momjian

Add regression test for various power expressions with a zero base, and

adjust source code to be more modular.
上级 6b4e9d16
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* Copyright (c) 1998-2008, PostgreSQL Global Development Group * Copyright (c) 1998-2008, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.111 2008/05/08 19:25:38 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.112 2008/05/08 22:17:54 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -5170,21 +5170,6 @@ power_var(NumericVar *base, NumericVar *exp, NumericVar *result) ...@@ -5170,21 +5170,6 @@ power_var(NumericVar *base, NumericVar *exp, NumericVar *result)
int local_rscale; int local_rscale;
double val; 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 can be represented as an integer, use power_var_int */
if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1) if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
{ {
...@@ -5217,6 +5202,17 @@ power_var(NumericVar *base, NumericVar *exp, NumericVar *result) ...@@ -5217,6 +5202,17 @@ power_var(NumericVar *base, NumericVar *exp, NumericVar *result)
free_var(&x); 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_base);
init_var(&ln_num); init_var(&ln_num);
...@@ -5284,6 +5280,11 @@ power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale) ...@@ -5284,6 +5280,11 @@ power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
switch (exp) switch (exp)
{ {
case 0: 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); set_var_from_var(&const_one, result);
result->dscale = rscale; /* no need to round */ result->dscale = rscale; /* no need to round */
return; return;
......
...@@ -349,6 +349,12 @@ SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f; ...@@ -349,6 +349,12 @@ SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
ERROR: value out of range: overflow ERROR: value out of range: overflow
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f; SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f;
ERROR: value out of range: overflow 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' ; SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ;
ERROR: cannot take logarithm of zero ERROR: cannot take logarithm of zero
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' ;
......
...@@ -129,6 +129,8 @@ SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f; ...@@ -129,6 +129,8 @@ SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f;
SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f; 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' ;
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' ;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册