8000 Change ln(), log(), power(), and sqrt() to emit the correct SQLSTATE · postgrespro/postgres_cluster@2871f60 · GitHub
[go: up one dir, main page]

Skip to content
< 10BC0 script crossorigin="anonymous" type="application/javascript" src="https://github.githubassets.com/assets/43862-5c4df3ba1119.js" defer="defer">

Commit 2871f60

Browse files
author
Neil Conway
committed
Change ln(), log(), power(), and sqrt() to emit the correct SQLSTATE
error codes for certain error conditions, as specified by SQL2003.
1 parent 335cf9a commit 2871f60

File tree

4 files changed

+68
-15
lines changed

4 files changed

+68
-15
lines changed

doc/src/sgml/errcodes.sgml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.5 2004/05/14 21:42:27 neilc Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.6 2004/05/16 23:18:52 neilc Exp $ -->
22

33
<appendix id="errcodes-appendix">
44
<title><productname>PostgreSQL</productname> Error Codes</title>
@@ -310,6 +310,16 @@
310310
<entry>INTERVAL FIELD OVERFLOW</entry>
311311
</row>
312312

313+
<row>
314+
<entry><literal>2201E</literal></entry>
315+
<entry>INVALID ARGUMENT FOR LOGARITHM</entry>
316+
</row>
317+
318+
<row>
319+
<entry><literal>2201F</literal></entry>
320+
<entry>INVALID ARGUMENT FOR POWER FUNCTION</entry>
321+
</row>
322+
313323
<row>
314324
<entry><literal>2201G</literal></entry>
315325
<entry>INVALID ARGUMENT FOR WIDTH BUCKET FUNCTION</entry>

src/backend/utils/adt/float.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.104 2004/05/07 00:24:58 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.105 2004/05/16 23:18:55 neilc Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1415,7 +1415,7 @@ dsqrt(PG_FUNCTION_ARGS)
14151415

14161416
if (arg1 < 0)
14171417
ereport(ERROR,
1418-
(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
1418+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
14191419
errmsg("cannot take square root of a negative number")));
14201420

14211421
result = sqrt(arg1);
@@ -1449,6 +1449,16 @@ dpow(PG_FUNCTION_ARGS)
14491449
float8 arg2 = PG_GETARG_FLOAT8(1);
14501450
float8 result;
14511451

1452+
/*
1453+
* The SQL spec requires that we emit a particular SQLSTATE error
1454+
* code for certain error conditions.
1455+
*/
1456+
if ((arg1 == 0 && arg2 < 0) ||
1457+
(arg1 < 0 && floor(arg2) != arg2))
1458+
ereport(ERROR,
1459+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
1460+
errmsg("invalid argument for power function")));
1461+
14521462
/*
14531463
* We must check both for errno getting set and for a NaN result, in
14541464
* order to deal with the vagaries of different platforms...
@@ -1501,22 +1511,24 @@ dexp(PG_FUNCTION_ARGS)
15011511

15021512
/*
15031513
* dlog1 - returns the natural logarithm of arg1
1504-
* ("dlog" is already a logging routine...)
15051514
*/
15061515
Datum
15071516
dlog1(PG_FUNCTION_ARGS)
15081517
{
15091518
float8 arg1 = PG_GETARG_FLOAT8(0);
15101519
float8 result;
15111520

1521+
/*
1522+
* Emit particular SQLSTATE error codes for ln(). This is required
1523+
* by the SQL standard.
1524+
*/
15121525
if (arg1 == 0.0)
15131526
ereport(ERROR,
1514-
(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
1527+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
15151528
errmsg("cannot take logarithm of zero")));
1516-
15171529
if (arg1 < 0)
15181530
ereport(ERROR,
1519-
(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
1531+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
15201532
errmsg("cannot take logarithm of a negative number")));
15211533

15221534
result = log(arg1);
@@ -1535,14 +1547,19 @@ dlog10(PG_FUNCTION_ARGS)
15351547
float8 arg1 = PG_GETARG_FLOAT8(0);
15361548
float8 result;
15371549

1550+
/*
1551+
* Emit particular SQLSTATE error codes for log(). The SQL spec
1552+
* doesn't define log(), but it does define ln(), so it makes
1553+
* sense to emit the same error code for an analogous error
1554+
* condition.
1555+
*/
15381556
if (arg1 == 0.0)
15391557
ereport(ERROR,
1540-
(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
1558+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
15411559
errmsg("cannot take logarithm of zero")));
1542-
15431560
if (arg1 < 0)
15441561
ereport(ERROR,
1545-
(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
1562+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
15461563
errmsg("cannot take logarithm of a negative number")));
15471564

15481565
result = log10(arg1);

src/backend/utils/adt/numeric.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1 D0E4 414
* Copyright (c) 1998-2003, PostgreSQL Global Development Group
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.74 2004/05/14 21:42:28 neilc Exp $
17+
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.75 2004/05/16 23:18:55 neilc Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -1668,6 +1668,7 @@ numeric_power(PG_FUNCTION_ARGS)
16681668
Numeric res;
16691669
NumericVar arg1;
16701670
NumericVar arg2;
1671+
NumericVar arg2_trunc;
16711672
NumericVar result;
16721673

16731674
/*
@@ -1681,10 +1682,26 @@ numeric_power(PG_FUNCTION_ARGS)
16811682
*/
16821683
init_var(&arg1);
16831684
init_var(&arg2);
1685+
init_var(&arg2_trunc);
16841686
init_var(&result);
16851687

16861688
set_var_from_num(num1, &arg1);
16871689
set_var_from_num(num2, &arg2);
1690+
set_var_from_var(&arg2, &arg2_trunc);
1691+
1692+
trunc_var(&arg2_trunc, 0);
1693+
1694+
/*
1695+
* Return special SQLSTATE error codes for a few conditions
1696+
* mandated by the standard.
1697+
*/
1698+
if ((cmp_var(&arg1, &const_zero) == 0 &&
1699+
cmp_var(&arg2, &const_zero) < 0) ||
1700+
(cmp_var(&arg1, &const_zero) < 0 &&
1701+
cmp_var(&arg2, &arg2_trunc) != 0))
1702+
ereport(ERROR,
1703+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
1704+
errmsg("invalid argument for power function")));
16881705

16891706
/*
16901707
* Call power_var() to compute and return the result; note it handles
@@ -1696,6 +1713,7 @@ numeric_power(PG_FUNCTION_ARGS)
16961713

16971714
free_var(&result);
16981715
free_var(&arg2);
1716+
free_var(& D0E4 arg2_trunc);
16991717
free_var(&arg1);
17001718

17011719
PG_RETURN_NUMERIC(res);
@@ -4408,10 +4426,16 @@ ln_var(NumericVar *arg, NumericVar *result, int rscale)
44084426
NumericVar elem;
44094427
NumericVar fact;
44104428
int local_rscale;
4429+
int cmp;
44114430

4412-
if (cmp_var(arg, &const_zero) <= 0)
4431+
cmp = cmp_var(arg, &const_zero);
4432+
if (cmp == 0)
44134433
ereport(ERROR,
4414-
(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
4434+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
4435+
errmsg("cannot take logarithm of zero")));
4436+
else if (cmp < 0)
4437+
ereport(ERROR,
4438+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
44154439
errmsg("cannot take logarithm of a negative number")));
44164440

44174441
local_rscale = rscale + 8;

src/include/utils/errcodes.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
* Copyright (c) 2003, PostgreSQL Global Development Group
1313
*
14-
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.10 2004/05/14 21:42:30 neilc Exp $
14+
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.11 2004/05/16 23:18:55 neilc Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -116,7 +116,9 @@
116116
#define ERRCODE_ESCAPE_CHARACTER_CONFLICT MAKE_SQLSTATE('2','2', '0','0','B')
117117
#define ERRCODE_INDICATOR_OVERFLOW MAKE_SQLSTATE('2','2', '0','2','2')
118118
#define ERRCODE_INTERVAL_FIELD_OVERFLOW MAKE_SQLSTATE('2','2', '0','1','5')
119-
#define ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION MAKE_SQLSTATE('2','2', '0', '1', 'G')
119+
#define ERRCODE_INVALID_ARGUMENT_FOR_LOG MAKE_SQLSTATE('2','2', '0','1','E')
120+
#define ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION MAKE_SQLSTATE('2','2', '0', '1', 'F')
121+
#define ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION MAKE_SQLSTATE('2','2', '0', '1', 'G')
120122
#define ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST MAKE_SQLSTATE('2','2', '0','1','8')
121123
#define ERRCODE_INVALID_DATETIME_FORMAT MAKE_SQLSTATE('2','2', '0','0','7')
122124
#define ERRCODE_INVALID_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2', '0','1','9')

0 commit comments

Comments
 (0)
0