This is an automated email from the ASF dual-hosted git repository.

jgemignani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-age.git


The following commit(s) were added to refs/heads/master by this push:
     new 26bf66e  Add openCypher degrees() and radians() functions
26bf66e is described below

commit 26bf66ecccbfbeb1a50608c2ff17c0ec2d078855
Author: John Gemignani <[email protected]>
AuthorDate: Tue Sep 8 17:03:15 2020 -0700

    Add openCypher degrees() and radians() functions
    
    Added the openCypher degrees() and radians() functions.
    
    Added regression tests.
---
 age--0.2.0.sql                   |  16 ++++++
 regress/expected/expr.out        | 105 +++++++++++++++++++++++++++++++++++++++
 regress/sql/expr.sql             |  48 ++++++++++++++++++
 src/backend/parser/cypher_expr.c |   4 +-
 src/backend/utils/adt/agtype.c   |  96 +++++++++++++++++++++++++++++++++++
 5 files changed, 268 insertions(+), 1 deletion(-)

diff --git a/age--0.2.0.sql b/age--0.2.0.sql
index 9348931..11b106b 100644
--- a/age--0.2.0.sql
+++ b/age--0.2.0.sql
@@ -1074,12 +1074,14 @@ LANGUAGE c
 STABLE
 PARALLEL SAFE
 AS 'MODULE_PATHNAME';
+
 CREATE FUNCTION r_atan(variadic "any")
 RETURNS agtype
 LANGUAGE c
 STABLE
 PARALLEL SAFE
 AS 'MODULE_PATHNAME';
+
 CREATE FUNCTION r_atan2(variadic "any")
 RETURNS agtype
 LANGUAGE c
@@ -1087,6 +1089,20 @@ STABLE
 PARALLEL SAFE
 AS 'MODULE_PATHNAME';
 
+CREATE FUNCTION degrees_from_radians(variadic "any")
+RETURNS agtype
+LANGUAGE c
+STABLE
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE FUNCTION radians_from_degrees(variadic "any")
+RETURNS agtype
+LANGUAGE c
+STABLE
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
 --
 -- function for typecasting an agtype value to another agtype value
 --
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index b735d00..293acc7 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -3465,6 +3465,111 @@ ERROR:  invalid number of input parameters for pi()
 LINE 1: SELECT * FROM cypher('expr', $$
                                       ^
 --
+-- radians() & degrees()
+--
+SELECT * FROM cypher('expr', $$
+    RETURN radians(0)
+$$) AS (results agtype);
+ results 
+---------
+ 0.0
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(0)
+$$) AS (results agtype);
+ results 
+---------
+ 0.0
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN radians(360), 2*pi()
+$$) AS (results agtype, Two_PI agtype);
+     results      |      two_pi      
+------------------+------------------
+ 6.28318530717959 | 6.28318530717959
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(2*pi())
+$$) AS (results agtype);
+ results 
+---------
+ 360.0
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN radians(180), pi()
+$$) AS (results agtype, PI agtype);
+     results      |        pi        
+------------------+------------------
+ 3.14159265358979 | 3.14159265358979
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(pi())
+$$) AS (results agtype);
+ results 
+---------
+ 180.0
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN radians(90), pi()/2
+$$) AS (results agtype, Half_PI agtype);
+     results     |     half_pi     
+-----------------+-----------------
+ 1.5707963267949 | 1.5707963267949
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(pi()/2)
+$$) AS (results agtype);
+ results 
+---------
+ 90.0
+(1 row)
+
+-- should return null
+SELECT * FROM cypher('expr', $$
+    RETURN radians(null)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(null)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+-- should fail
+SELECT * FROM cypher('expr', $$
+    RETURN radians()
+$$) AS (results agtype);
+ERROR:  unrecognized or unsupported function
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+SELECT * FROM cypher('expr', $$
+    RETURN degrees()
+$$) AS (results agtype);
+ERROR:  unrecognized or unsupported function
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+SELECT * FROM cypher('expr', $$
+    RETURN radians("1")
+$$) AS (results agtype);
+ERROR:  radians() unsuppoted argument agtype 1
+SELECT * FROM cypher('expr', $$
+    RETURN degrees("1")
+$$) AS (results agtype);
+ERROR:  degrees() unsuppoted argument agtype 1
+--
 -- Cleanup
 --
 SELECT * FROM drop_graph('expr', true);
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index a689c8d..1ce8182 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -1467,6 +1467,54 @@ SELECT * FROM cypher('expr', $$
 $$) AS (results agtype);
 
 --
+-- radians() & degrees()
+--
+SELECT * FROM cypher('expr', $$
+    RETURN radians(0)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(0)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN radians(360), 2*pi()
+$$) AS (results agtype, Two_PI agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(2*pi())
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN radians(180), pi()
+$$) AS (results agtype, PI agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(pi())
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN radians(90), pi()/2
+$$) AS (results agtype, Half_PI agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(pi()/2)
+$$) AS (results agtype);
+-- should return null
+SELECT * FROM cypher('expr', $$
+    RETURN radians(null)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN degrees(null)
+$$) AS (results agtype);
+-- should fail
+SELECT * FROM cypher('expr', $$
+    RETURN radians()
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN degrees()
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN radians("1")
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN degrees("1")
+$$) AS (results agtype);
+
+--
 -- Cleanup
 --
 SELECT * FROM drop_graph('expr', true);
diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c
index 359136a..feba68d 100644
--- a/src/backend/parser/cypher_expr.c
+++ b/src/backend/parser/cypher_expr.c
@@ -79,6 +79,8 @@
 #define FUNC_RATAN      {"atan",       "r_atan",     ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false, false}
 #define FUNC_RATAN2     {"atan2",      "r_atan2",    ANYOID,    0, 0, 
AGTYPEOID, 2, 1, false, false}
 #define FUNC_PI         {"pi",         "pi",         0,         0, 0, 
FLOAT8OID, 0, 0, false, true}
+#define FUNC_DEGREES    {"degrees",    "degrees_from_radians", ANYOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
+#define FUNC_RADIANS    {"radians",    "radians_from_degrees", ANYOID, 0, 0, 
AGTYPEOID, 1, 1, false, false}
 
 /* supported functions */
 #define SUPPORTED_FUNCTIONS {FUNC_TYPE, FUNC_ENDNODE, FUNC_HEAD, FUNC_ID, \
@@ -91,7 +93,7 @@
                              FUNC_LSUBSTR, FUNC_BSUBSTR, FUNC_SPLIT, \
                              FUNC_REPLACE, FUNC_RSIN, FUNC_RCOS, FUNC_RTAN, \
                              FUNC_RCOT, FUNC_RASIN, FUNC_RACOS, FUNC_RATAN, \
-                             FUNC_RATAN2, FUNC_PI}
+                             FUNC_RATAN2, FUNC_PI, FUNC_DEGREES, FUNC_RADIANS}
 
 /* structure for supported function signatures */
 typedef struct function_signature
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 4b165f4..9152e12 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -6183,3 +6183,99 @@ Datum r_atan2(PG_FUNCTION_ARGS)
 
     PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
 }
+
+PG_FUNCTION_INFO_V1(degrees_from_radians);
+
+Datum degrees_from_radians(PG_FUNCTION_ARGS)
+{
+    int nargs;
+    Datum *args;
+    bool *nulls;
+    Oid *types;
+    agtype_value agtv_result;
+    float8 angle_degrees;
+    float8 angle_radians;
+    bool is_null = true;
+
+    /* extract argument values */
+    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
+
+    /* check number of args */
+    if (nargs != 1)
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                        errmsg("degrees() invalid number of arguments")));
+
+    /* check for a null input */
+    if (nargs < 0 || nulls[0])
+        PG_RETURN_NULL();
+
+    /*
+     * degrees_from_radians() supports integer, float, and numeric or the 
agtype
+     * integer, float, and numeric for the input expression.
+     */
+
+    angle_radians = get_float_compatible_arg(args[0], types[0], "degrees",
+                                             &is_null);
+
+    /* check for a agtype null input */
+    if (is_null)
+        PG_RETURN_NULL();
+
+    /* We need the numeric input as a float8 so that we can pass it off to PG 
*/
+    angle_degrees = DatumGetFloat8(DirectFunctionCall1(degrees,
+                                                       
Float8GetDatum(angle_radians)));
+
+    /* build the result */
+    agtv_result.type = AGTV_FLOAT;
+    agtv_result.val.float_value = angle_degrees;
+
+    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
+}
+
+PG_FUNCTION_INFO_V1(radians_from_degrees);
+
+Datum radians_from_degrees(PG_FUNCTION_ARGS)
+{
+    int nargs;
+    Datum *args;
+    bool *nulls;
+    Oid *types;
+    agtype_value agtv_result;
+    float8 angle_degrees;
+    float8 angle_radians;
+    bool is_null = true;
+
+    /* extract argument values */
+    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
+
+    /* check number of args */
+    if (nargs != 1)
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                        errmsg("radians() invalid number of arguments")));
+
+    /* check for a null input */
+    if (nargs < 0 || nulls[0])
+        PG_RETURN_NULL();
+
+    /*
+     * radians_from_degrees() supports integer, float, and numeric or the 
agtype
+     * integer, float, and numeric for the input expression.
+     */
+
+    angle_degrees = get_float_compatible_arg(args[0], types[0], "radians",
+                                             &is_null);
+
+    /* check for a agtype null input */
+    if (is_null)
+        PG_RETURN_NULL();
+
+    /* We need the numeric input as a float8 so that we can pass it off to PG 
*/
+    angle_radians = DatumGetFloat8(DirectFunctionCall1(radians,
+                                                       
Float8GetDatum(angle_degrees)));
+
+    /* build the result */
+    agtv_result.type = AGTV_FLOAT;
+    agtv_result.val.float_value = angle_radians;
+
+    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
+}

Reply via email to