Skip to content

Commit 061a189

Browse files
committed
Add tests for functions in input language
1 parent 92e69af commit 061a189

File tree

5 files changed

+90
-2
lines changed

5 files changed

+90
-2
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ DATA_built = unit--2--3.sql unit--3.sql \
99
unit--4--5.sql unit--5.sql \
1010
unit--5--6.sql unit--6.sql \
1111
unit--6--7.sql unit--7.sql
12-
REGRESS = extension tables unit binary unicode prefix units time temperature functions round derived compare aggregate iec custom
12+
REGRESS = extension tables unit binary unicode prefix units time temperature functions language_functions round derived compare aggregate iec custom
1313
# Jessie's and trusty's bison (3.0.2) is buggy, ship pregenerated .tab files
1414
EXTRA_CLEAN = unitparse.yy.* powers powers.o unit-*.dump # unitparse.tab.*
1515

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,11 @@ Unit values allow a fairly complex expression syntax on input.
249249
* operators + - * /
250250
* exponentiation: `expr^integer` or Unicode superscripts: `expr⁺⁻⁰¹²³⁴⁵⁶⁷⁸⁹`
251251
* parentheses ()
252-
* multiplication binds tighter than division such that `kg/s^2*A`
252+
* multiplication binds tighter than division such that `kg/s^2*A` and `kg/s^2 A`
253253
can be written without parentheses
254254
* `N|M` denotes a numeric fraction, e.g. `3|4`
255255
* use `hh:mm:ss[.sss]` for time values, e.g. `10:05:30 s`
256+
* functions: `sqrt(unit)`, `exp(x)`, `ln(x)`, `log2(x)`, `asin(x)`, `tan(x)`
256257

257258
*Note: This covers the unit input parser for expressions like
258259
`'1|2 m / h'::unit`. PostgreSQL operators on type unit values are a separate

expected/language_functions.out

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
select 'sqrt(4 m^2)'::unit;
2+
unit
3+
------
4+
2 m
5+
(1 row)
6+
7+
select 'sqrt(-4 m^2)'::unit;
8+
ERROR: cannot take square root of a negative-valued unit
9+
LINE 1: select 'sqrt(-4 m^2)'::unit;
10+
^
11+
select 'sqrt(4 m^3)'::unit;
12+
ERROR: cannot take square root of a unit with odd "m" exponent
13+
LINE 1: select 'sqrt(4 m^3)'::unit;
14+
^
15+
select 'exp(1)'::unit;
16+
unit
17+
------------------
18+
2.71828182845905
19+
(1 row)
20+
21+
select 'exp(1 A)'::unit;
22+
ERROR: cannot take base-e exponent of value that is not dimension-less
23+
LINE 1: select 'exp(1 A)'::unit;
24+
^
25+
select 'ln(2.7)'::unit;
26+
unit
27+
-------------------
28+
0.993251773010283
29+
(1 row)
30+
31+
select 'ln(-2.7)'::unit;
32+
ERROR: cannot take ln of a negative-valued unit
33+
LINE 1: select 'ln(-2.7)'::unit;
34+
^
35+
select 'ln(2.7 s)'::unit;
36+
ERROR: cannot take ln of value that is not dimension-less
37+
LINE 1: select 'ln(2.7 s)'::unit;
38+
^
39+
select 'asin(1)'::unit;
40+
unit
41+
-----------------
42+
1.5707963267949
43+
(1 row)
44+
45+
select 'asin(2)'::unit;
46+
ERROR: cannot asin of values outside the range -1 to 1
47+
LINE 1: select 'asin(2)'::unit;
48+
^
49+
select 'asin(1 kg)'::unit;
50+
ERROR: cannot take asin of value that is not dimension-less
51+
LINE 1: select 'asin(1 kg)'::unit;
52+
^
53+
select 'tan(1)'::unit;
54+
unit
55+
-----------------
56+
1.5574077246549
57+
(1 row)
58+
59+
select 'tan(1 mol)'::unit;
60+
ERROR: cannot take tan of value that is not dimension-less
61+
LINE 1: select 'tan(1 mol)'::unit;
62+
^

sql/language_functions.sql

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
select 'sqrt(4 m^2)'::unit;
2+
select 'sqrt(-4 m^2)'::unit;
3+
select 'sqrt(4 m^3)'::unit;
4+
5+
select 'exp(1)'::unit;
6+
select 'exp(1 A)'::unit;
7+
8+
select 'ln(2.7)'::unit;
9+
select 'ln(-2.7)'::unit;
10+
select 'ln(2.7 s)'::unit;
11+
12+
select 'asin(1)'::unit;
13+
select 'asin(2)'::unit;
14+
select 'asin(1 kg)'::unit;
15+
16+
select 'tan(1)'::unit;
17+
select 'tan(1 mol)'::unit;

unit.c

+8
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,10 @@ unit_ln_internal(Unit *a, Unit *result)
995995
int i;
996996

997997
/* compute ln of value */
998+
if (a->value < 0)
999+
ereport(ERROR,
1000+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
1001+
errmsg("cannot take ln of a negative-valued unit")));
9981002
result->value = log(a->value);
9991003

10001004
/* check dimension */
@@ -1014,6 +1018,10 @@ unit_log2_internal(Unit *a, Unit *result)
10141018
int i;
10151019

10161020
/* compute log2 of value */
1021+
if (a->value < 0)
1022+
ereport(ERROR,
1023+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
1024+
errmsg("cannot take log2 of a negative-valued unit")));
10171025
result->value = log2(a->value);
10181026

10191027
/* check dimension */

0 commit comments

Comments
 (0)