diff --git a/docs/stdlib/math.rst b/docs/stdlib/math.rst index 1d7b7949108..6014106c416 100644 --- a/docs/stdlib/math.rst +++ b/docs/stdlib/math.rst @@ -194,3 +194,178 @@ Math db> select math::var_pop({1, 3, 5}); {2.66666666666667} + + +----------- + + +.. eql:function:: math::pi() -> float64 + + :index: trigonometry + + Returns the value of pi. + + .. code-block:: edgeql-repl + + db> select math::pi(); + {3.141592653589793} + + +----------- + + +.. eql:function:: math::acos(x: float64) -> float64 + + :index: trigonometry + + Returns the arc cosine of the input. + + .. code-block:: edgeql-repl + + db> select math::acos(-1); + {3.141592653589793} + db> select math::acos(0); + {1.5707963267948966} + db> select math::acos(1); + {0} + + +----------- + + +.. eql:function:: math::asin(x: float64) -> float64 + + :index: trigonometry + + Returns the arc sine of the input. + + .. code-block:: edgeql-repl + + db> select math::asin(-1); + {-1.5707963267948966} + db> select math::asin(0); + {0} + db> select math::asin(1); + {1.5707963267948966} + + +----------- + + +.. eql:function:: math::atan(x: float64) -> float64 + + :index: trigonometry + + Returns the arc tangent of the input. + + .. code-block:: edgeql-repl + + db> select math::atan(-1); + {-0.7853981633974483} + db> select math::atan(0); + {0} + db> select math::atan(1); + {0.7853981633974483} + + +----------- + + +.. eql:function:: math::atan2(y: float64, x: float64) -> float64 + + :index: trigonometry + + Returns the arc tangent of ``y / x``. + + Uses the signs of the arguments determine the correct quadrant. + + .. code-block:: edgeql-repl + + db> select math::atan2(1, 1); + {0.7853981633974483} + db> select math::atan2(1, -1); + {2.356194490192345} + db> select math::atan2(-1, -1); + {-2.356194490192345} + db> select math::atan2(-1, 1); + {-0.7853981633974483} + + +----------- + + +.. eql:function:: math::cos(x: float64) -> float64 + + :index: trigonometry + + Returns the cosine of the input. + + .. code-block:: edgeql-repl + + db> select math::cos(0); + {1} + db> select math::cos(math::pi() / 2); + {0.000000000} + db> select math::cos(math::pi()); + {-1} + db> select math::cos(math::pi() * 3 / 2); + {-0.000000000} + + +----------- + + +.. eql:function:: math::cot(x: float64) -> float64 + + :index: trigonometry + + Returns the cotangent of the input. + + .. code-block:: edgeql-repl + + db> select math::cot(math::pi() / 4); + {1.000000000} + db> select math::cot(math::pi() / 2); + {0.000000000} + db> select math::cot(math::pi() * 3 / 4); + {-0.999999999} + + +----------- + + +.. eql:function:: math::sin(x: float64) -> float64 + + :index: trigonometry + + Returns the sinine of the input. + + .. code-block:: edgeql-repl + + db> select math::sin(0); + {0} + db> select math::sin(math::pi() / 2); + {1} + db> select math::sin(math::pi()); + {0.000000000} + db> select math::sin(math::pi() * 3 / 2); + {-1} + + +----------- + + +.. eql:function:: math::tan(x: float64) -> float64 + + :index: trigonometry + + Returns the tanangent of the input. + + .. code-block:: edgeql-repl + + db> select math::tan(-math::pi() / 4); + {-0.999999999} + db> select math::tan(0); + {0} + db> select math::tan(math::pi() / 4); + {0.999999999} diff --git a/docs/stdlib/math_funcops_table.rst b/docs/stdlib/math_funcops_table.rst index f35077ec3c5..8073c0fa38c 100644 --- a/docs/stdlib/math_funcops_table.rst +++ b/docs/stdlib/math_funcops_table.rst @@ -35,3 +35,30 @@ * - :eql:func:`math::var_pop` - :eql:func-desc:`math::var_pop` + + * - :eql:func:`math::pi` + - :eql:func-desc:`math::pi` + + * - :eql:func:`math::acos` + - :eql:func-desc:`math::acos` + + * - :eql:func:`math::asin` + - :eql:func-desc:`math::asin` + + * - :eql:func:`math::atan` + - :eql:func-desc:`math::atan` + + * - :eql:func:`math::atan2` + - :eql:func-desc:`math::atan2` + + * - :eql:func:`math::cos` + - :eql:func-desc:`math::cos` + + * - :eql:func:`math::cot` + - :eql:func-desc:`math::cot` + + * - :eql:func:`math::sin` + - :eql:func-desc:`math::sin` + + * - :eql:func:`math::tan` + - :eql:func-desc:`math::tan` diff --git a/edb/buildmeta.py b/edb/buildmeta.py index fa51eb292c2..957581cd073 100644 --- a/edb/buildmeta.py +++ b/edb/buildmeta.py @@ -60,7 +60,7 @@ # The merge conflict there is a nice reminder that you probably need # to write a patch in edb/pgsql/patches.py, and then you should preserve # the old value. -EDGEDB_CATALOG_VERSION = 2024_12_03_00_00 +EDGEDB_CATALOG_VERSION = 2024_12_04_00_00 EDGEDB_MAJOR_VERSION = 6 diff --git a/edb/lib/math.edgeql b/edb/lib/math.edgeql index bd9ebb7cc3d..b554adf548d 100644 --- a/edb/lib/math.edgeql +++ b/edb/lib/math.edgeql @@ -402,3 +402,93 @@ std::math::var_pop(vals: SET OF std::float64) -> OPTIONAL std::float64 SET error_on_null_result := 'invalid input to var_pop(): not ' ++ 'enough elements in input set'; }; + + +CREATE FUNCTION +std::math::pi() -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the constant value of pi.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'pi'; +}; + + +CREATE FUNCTION +std::math::acos(x: std::float64) -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the inverse cosine of the input value.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'acos'; +}; + + +CREATE FUNCTION +std::math::asin(x: std::float64) -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the inverse sine of the input value.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'asin'; +}; + + +CREATE FUNCTION +std::math::atan(x: std::float64) -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the inverse tangent of the input value.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'atan'; +}; + + +CREATE FUNCTION +std::math::atan2(y: std::float64, x: std::float64) -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the inverse tangent of y/x of the input value.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'atan2'; +}; + + +CREATE FUNCTION +std::math::cos(x: std::float64) -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the cosine of the input value.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'cos'; +}; + + +CREATE FUNCTION +std::math::cot(x: std::float64) -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the cotangent of the input value.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'cot'; +}; + + +CREATE FUNCTION +std::math::sin(x: std::float64) -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the sine of the input value.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'sin'; +}; + + +CREATE FUNCTION +std::math::tan(x: std::float64) -> std::float64 +{ + CREATE ANNOTATION std::description := + 'Return the tangent of the input value.'; + SET volatility := 'Immutable'; + USING SQL FUNCTION 'tan'; +}; diff --git a/tests/test_edgeql_functions.py b/tests/test_edgeql_functions.py index b85d8b14c8e..ff8d7ab75c2 100644 --- a/tests/test_edgeql_functions.py +++ b/tests/test_edgeql_functions.py @@ -20,6 +20,7 @@ import base64 import decimal import json +import math import os.path import random import uuid @@ -6055,6 +6056,780 @@ async def test_edgeql_functions_math_var_pop_04(self): SELECT math::var_pop({}); ''') + async def test_edgeql_functions_math_pi_01(self): + await self.assert_query_result( + r'''SELECT math::pi() IS float64;''', + {True}, + ) + await self.assert_query_result( + r'''SELECT math::pi();''', + {math.pi}, + abs_tol=0.0000000005, + ) + + async def test_edgeql_functions_math_acos_01(self): + await self.assert_query_result( + r'''SELECT math::acos(-1);''', + {math.pi}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::acos(-math::sqrt(2) / 2);''', + {math.pi * 3 / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::acos(-0.0);''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::acos(0.0);''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::acos(math::sqrt(2) / 2);''', + {math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''WITH x := math::acos(1) SELECT (x, x);''', + [(0.0, '0')], + ) + + await self.assert_query_result( + r'''SELECT math::acos("NaN");''', + {"NaN"}, + ) + + async def test_edgeql_functions_math_acos_02(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::acos(-1.001); + ''') + + async def test_edgeql_functions_math_acos_03(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::acos(1.001); + ''') + + async def test_edgeql_functions_math_acos_04(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::acos("-inf"); + ''') + + async def test_edgeql_functions_math_acos_05(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::acos("inf"); + ''') + + async def test_edgeql_functions_math_asin_01(self): + await self.assert_query_result( + r'''SELECT math::asin(-1);''', + {-math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::asin(-math::sqrt(2) / 2);''', + {-math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''WITH x := math::asin(-0.0) SELECT (x, x);''', + [[-0.0, '-0']], + ) + await self.assert_query_result( + r'''WITH x := math::asin(0.0) SELECT (x, x);''', + [[0.0, '0']], + ) + await self.assert_query_result( + r'''SELECT math::asin(math::sqrt(2) / 2);''', + {math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::asin(1);''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::asin("NaN");''', + {"NaN"}, + ) + + async def test_edgeql_functions_math_asin_02(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::asin(-1.001); + ''') + + async def test_edgeql_functions_math_asin_03(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::asin(1.001); + ''') + + async def test_edgeql_functions_math_asin_04(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::asin("-inf"); + ''') + + async def test_edgeql_functions_math_asin_05(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::asin("inf"); + ''') + + async def test_edgeql_functions_math_atan_01(self): + await self.assert_query_result( + r'''SELECT math::atan("-inf");''', + {-math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan(-1000000000);''', + {-math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan(-math::sqrt(3));''', + {-math.pi / 3}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan(-1);''', + {-math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan(-1 / math::sqrt(3));''', + {-math.pi / 6}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''WITH x := math::atan(-0.0) SELECT (x, x);''', + [[-0.0, '-0']], + ) + await self.assert_query_result( + r'''WITH x := math::atan(0.0) SELECT (x, x);''', + [[0.0, '0']], + ) + await self.assert_query_result( + r'''SELECT math::atan(1 / math::sqrt(3));''', + {math.pi / 6}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan(1);''', + {math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan(math::sqrt(3));''', + {math.pi / 3}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan(1000000000);''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan("inf");''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::atan("NaN");''', + {"NaN"}, + ) + + async def test_edgeql_functions_math_atan2_01(self): + await self.assert_query_result( + r'''SELECT math::atan2(-0.0, -1);''', + {-math.pi}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(-2, -2);''', + {-math.pi * 3 / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(-3, -0.0);''', + {-math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(-4, 0.0);''', + {-math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(-5, 5);''', + {-math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''WITH x := math::atan2(-0.0, 6) SELECT (x, x);''', + [[-0.0, '-0']], + ) + await self.assert_query_result( + r'''WITH x := math::atan2(0.0, 6) SELECT (x, x);''', + [[0.0, '0']], + ) + await self.assert_query_result( + r'''SELECT math::atan2(8, 8);''', + {math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(9, 0.0);''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(10, -0.0);''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(11, -11);''', + {math.pi * 3 / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(0.0, -12);''', + {math.pi}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::atan2(-0.0, -0.0);''', + {-math.pi}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''WITH x := math::atan2(-0.0, 0.0) SELECT (x, x);''', + [[-0.0, '-0']], + ) + await self.assert_query_result( + r'''WITH x := math::atan2(0.0, 0.0) SELECT (x, x);''', + [[0.0, '0']], + ) + await self.assert_query_result( + r'''SELECT math::atan2(0.0, -0.0);''', + {math.pi}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::atan2(-0.0, -"inf");''', + {-math.pi}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(-"inf", -"inf");''', + {-math.pi * 3 / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(-"inf", -0.0);''', + {-math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(-"inf", 0.0);''', + {-math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(-"inf", "inf");''', + {-math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r''' + WITH x := math::atan2(-0.0, "inf") + SELECT (x, x); + ''', + [[-0.0, '-0']], + ) + await self.assert_query_result( + r''' + WITH x := math::atan2(0.0, "inf") + SELECT (x, x); + ''', + [[0.0, '0']], + ) + await self.assert_query_result( + r'''SELECT math::atan2("inf", "inf");''', + {math.pi / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2("inf", 0.0);''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2("inf", -0.0);''', + {math.pi / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2("inf", -"inf");''', + {math.pi * 3 / 4}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::atan2(0.0, -"inf");''', + {math.pi}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::atan2("NaN", 1);''', + {"NaN"}, + ) + await self.assert_query_result( + r'''SELECT math::atan2(1, "NaN");''', + {"NaN"}, + ) + await self.assert_query_result( + r'''SELECT math::atan2("NaN", "NaN");''', + {"NaN"}, + ) + + async def test_edgeql_functions_math_cos_01(self): + await self.assert_query_result( + r'''SELECT math::cos(-math::pi() * 2);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(-math::pi() * 7 / 4);''', + {math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(-math::pi() * 3 / 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(-math::pi() * 5 / 4);''', + {-math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(-math::pi());''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(-math::pi() * 3 / 4);''', + {-math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(-math::pi() / 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(-math::pi() / 4);''', + {math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(-0.0);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(0.0);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(math::pi() / 4);''', + {math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(math::pi() / 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(math::pi() * 3 / 4);''', + {-math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(math::pi());''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(math::pi() * 5 / 4);''', + {-math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(math::pi() * 3 / 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(math::pi() * 7 / 4);''', + {math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cos(math::pi() * 2);''', + {1.0}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::cos("NaN");''', + {"NaN"}, + ) + + async def test_edgeql_functions_math_cos_02(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::cos("-inf"); + ''') + + async def test_edgeql_functions_math_cos_03(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::cos("inf"); + ''') + + async def test_edgeql_functions_math_cot_01(self): + await self.assert_query_result( + r'''SELECT math::cot(-math::pi() * 7 / 4);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(-math::pi() * 3 / 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(-math::pi() * 5 / 4);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(-math::pi() * 3 / 4);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(-math::pi() / 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(-math::pi() / 4);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(-0.0);''', + {"-Infinity"}, + ) + await self.assert_query_result( + r'''SELECT math::cot(0.0);''', + {"Infinity"}, + ) + await self.assert_query_result( + r'''SELECT math::cot(math::pi() / 4);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(math::pi() / 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(math::pi() * 3 / 4);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(math::pi() * 5 / 4);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(math::pi() * 3 / 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::cot(math::pi() * 7 / 4);''', + {-1.0}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::cot("NaN");''', + {"NaN"}, + ) + + async def test_edgeql_functions_math_cot_02(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::cot("-inf"); + ''') + + async def test_edgeql_functions_math_cot_03(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::cot("inf"); + ''') + + async def test_edgeql_functions_math_sin_01(self): + await self.assert_query_result( + r'''SELECT math::sin(-math::pi() * 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(-math::pi() * 7 / 4);''', + {math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(-math::pi() * 3 / 2);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(-math::pi() * 5 / 4);''', + {math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(-math::pi());''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(-math::pi() * 3 / 4);''', + {-math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(-math::pi() / 2);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(-math::pi() / 4);''', + {-math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''WITH x := math::sin(-0.0) SELECT (x, x);''', + [[-0.0, '-0']], + ) + await self.assert_query_result( + r'''WITH x := math::sin(0.0) SELECT (x, x);''', + [[0.0, '0']], + ) + await self.assert_query_result( + r'''SELECT math::sin(math::pi() / 4);''', + {math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(math::pi() / 2);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(math::pi() * 3 / 4);''', + {math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(math::pi());''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(math::pi() * 5 / 4);''', + {-math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(math::pi() * 3 / 2);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(math::pi() * 7 / 4);''', + {-math.sqrt(2) / 2}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::sin(math::pi() * 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::sin("NaN");''', + {"NaN"}, + ) + + async def test_edgeql_functions_math_sin_02(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::sin("-inf"); + ''') + + async def test_edgeql_functions_math_sin_03(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::sin("inf"); + ''') + + async def test_edgeql_functions_math_tan_01(self): + await self.assert_query_result( + r'''SELECT math::tan(-math::pi() * 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(-math::pi() * 7 / 4);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(-math::pi() * 5 / 4);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(-math::pi());''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(-math::pi() * 3 / 4);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(-math::pi() / 4);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''WITH x := math::tan(-0.0) SELECT (x, x);''', + [[-0.0, '-0']], + ) + await self.assert_query_result( + r'''WITH x := math::tan(0.0) SELECT (x, x);''', + [[0.0, '0']], + ) + await self.assert_query_result( + r'''SELECT math::tan(math::pi() / 4);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(math::pi() * 3 / 4);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(math::pi());''', + {0.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(math::pi() * 5 / 4);''', + {1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(math::pi() * 7 / 4);''', + {-1.0}, + abs_tol=0.0000000005, + ) + await self.assert_query_result( + r'''SELECT math::tan(math::pi() * 2);''', + {0.0}, + abs_tol=0.0000000005, + ) + + await self.assert_query_result( + r'''SELECT math::tan("NaN");''', + {"NaN"}, + ) + + async def test_edgeql_functions_math_tan_02(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::tan("-inf"); + ''') + + async def test_edgeql_functions_math_tan_03(self): + with self.assertRaisesRegex( + edgedb.NumericOutOfRangeError, + r"input is out of range"): + await self.con.query(r''' + SELECT math::tan("inf"); + ''') + async def test_edgeql_functions__genseries_01(self): await self.assert_query_result( r'''