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 d2611af  Add openCypher trig functions asin, acos, atan, & atan2
d2611af is described below

commit d2611af17bbfb7f75b0000a271d478e2447fde24
Author: John Gemignani <[email protected]>
AuthorDate: Mon Aug 31 17:37:30 2020 -0700

    Add openCypher trig functions asin, acos, atan, & atan2
    
    Added the openCypher trig functions asin (arcsin), acos (arccos),
    atan (arctan), and atan2 (arctan2).
    
    Added regression tests.
---
 age--0.2.0.sql                     |  26 ++++
 regress/expected/cypher_create.out |  16 +--
 regress/expected/expr.out          | 259 +++++++++++++++++++++++++++++++++++++
 regress/sql/expr.sql               |  98 ++++++++++++++
 src/backend/parser/cypher_expr.c   |   8 +-
 src/backend/utils/adt/agtype.c     | 203 +++++++++++++++++++++++++++++
 6 files changed, 600 insertions(+), 10 deletions(-)

diff --git a/age--0.2.0.sql b/age--0.2.0.sql
index f55161d..7b74f75 100644
--- a/age--0.2.0.sql
+++ b/age--0.2.0.sql
@@ -1027,6 +1027,32 @@ STABLE
 PARALLEL SAFE
 AS 'MODULE_PATHNAME';
 
+CREATE FUNCTION r_asin(variadic "any")
+RETURNS agtype
+LANGUAGE c
+STABLE
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE FUNCTION r_acos(variadic "any")
+RETURNS agtype
+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
+STABLE
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
 --
 -- function for typecasting an agtype value to another agtype value
 --
diff --git a/regress/expected/cypher_create.out 
b/regress/expected/cypher_create.out
index fd8de17..1db5da4 100644
--- a/regress/expected/cypher_create.out
+++ b/regress/expected/cypher_create.out
@@ -375,14 +375,14 @@ SELECT * FROM cypher_create.e_var;
 SELECT * FROM ag_label;
        name       | graph | id | kind |            relation            
 ------------------+-------+----+------+--------------------------------
- _ag_label_vertex | 17037 |  1 | v    | cypher_create._ag_label_vertex
- _ag_label_edge   | 17037 |  2 | e    | cypher_create._ag_label_edge
- v                | 17037 |  3 | v    | cypher_create.v
- e                | 17037 |  4 | e    | cypher_create.e
- n_var            | 17037 |  5 | v    | cypher_create.n_var
- e_var            | 17037 |  6 | e    | cypher_create.e_var
- n_other_node     | 17037 |  7 | v    | cypher_create.n_other_node
- b_var            | 17037 |  8 | e    | cypher_create.b_var
+ _ag_label_vertex | 17045 |  1 | v    | cypher_create._ag_label_vertex
+ _ag_label_edge   | 17045 |  2 | e    | cypher_create._ag_label_edge
+ v                | 17045 |  3 | v    | cypher_create.v
+ e                | 17045 |  4 | e    | cypher_create.e
+ n_var            | 17045 |  5 | v    | cypher_create.n_var
+ e_var            | 17045 |  6 | e    | cypher_create.e_var
+ n_other_node     | 17045 |  7 | v    | cypher_create.n_other_node
+ b_var            | 17045 |  8 | e    | cypher_create.b_var
 (8 rows)
 
 --Validate every vertex has the correct label
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 6bd7b96..af28b22 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -3142,6 +3142,265 @@ LINE 1: SELECT * FROM r_cot();
                       ^
 HINT:  No function matches the given name and argument types. You might need 
to add explicit type casts.
 --
+-- Arc functions: asin, acos, atan, & atan2
+--
+SELECT * FROM cypher('expr', $$
+    RETURN asin(1)*2
+$$) AS (results agtype);
+     results      
+------------------
+ 3.14159265358979
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN acos(0)*2
+$$) AS (results agtype);
+     results      
+------------------
+ 3.14159265358979
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN atan(1)*4
+$$) AS (results agtype);
+     results      
+------------------
+ 3.14159265358979
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(1, 1)*4
+$$) AS (results agtype);
+     results      
+------------------
+ 3.14159265358979
+(1 row)
+
+SELECT * FROM asin(1), r_asin(1);
+      asin       |     r_asin      
+-----------------+-----------------
+ 1.5707963267949 | 1.5707963267949
+(1 row)
+
+SELECT * FROM acos(0), r_acos(0);
+      acos       |     r_acos      
+-----------------+-----------------
+ 1.5707963267949 | 1.5707963267949
+(1 row)
+
+SELECT * FROM atan(1), r_atan(1);
+       atan        |      r_atan       
+-------------------+-------------------
+ 0.785398163397448 | 0.785398163397448
+(1 row)
+
+SELECT * FROM atan2(1, 1), r_atan2(1, 1);
+       atan2       |      r_atan2      
+-------------------+-------------------
+ 0.785398163397448 | 0.785398163397448
+(1 row)
+
+-- should return null
+SELECT * FROM cypher('expr', $$
+    RETURN asin(1.1)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN acos(1.1)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN asin(-1.1)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN acos(-1.1)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN asin(null)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN acos(null)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN atan(null)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(null, null)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(null, 1)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(1, null)
+$$) AS (results agtype);
+ results 
+---------
+ 
+(1 row)
+
+SELECT * FROM r_asin(null);
+ r_asin 
+--------
+ 
+(1 row)
+
+SELECT * FROM r_acos(null);
+ r_acos 
+--------
+ 
+(1 row)
+
+SELECT * FROM r_atan(null);
+ r_atan 
+--------
+ 
+(1 row)
+
+SELECT * FROM r_atan2(null, null);
+ r_atan2 
+---------
+ 
+(1 row)
+
+SELECT * FROM r_atan2(1, null);
+ r_atan2 
+---------
+ 
+(1 row)
+
+SELECT * FROM r_atan2(null, 1);
+ r_atan2 
+---------
+ 
+(1 row)
+
+-- should fail
+SELECT * FROM cypher('expr', $$
+    RETURN asin("0")
+$$) AS (results agtype);
+ERROR:  asin() unsuppoted argument agtype 1
+SELECT * FROM cypher('expr', $$
+    RETURN acos("0")
+$$) AS (results agtype);
+ERROR:  acos() unsuppoted argument agtype 1
+SELECT * FROM cypher('expr', $$
+    RETURN atan("0")
+$$) AS (results agtype);
+ERROR:  atan() unsuppoted argument agtype 1
+SELECT * FROM cypher('expr', $$
+    RETURN atan2("0", 1)
+$$) AS (results agtype);
+ERROR:  atan2() unsuppoted argument agtype 1
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(0, "1")
+$$) AS (results agtype);
+ERROR:  atan2() unsuppoted argument agtype 1
+SELECT * FROM cypher('expr', $$
+    RETURN asin()
+$$) AS (results agtype);
+ERROR:  unrecognized or unsupported function
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+SELECT * FROM cypher('expr', $$
+    RETURN acos()
+$$) AS (results agtype);
+ERROR:  unrecognized or unsupported function
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+SELECT * FROM cypher('expr', $$
+    RETURN atan()
+$$) AS (results agtype);
+ERROR:  unrecognized or unsupported function
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+SELECT * FROM cypher('expr', $$
+    RETURN atan2()
+$$) AS (results agtype);
+ERROR:  unrecognized or unsupported function
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(null)
+$$) AS (results agtype);
+ERROR:  invalid number of input parameters for atan2()
+LINE 1: SELECT * FROM cypher('expr', $$
+                                      ^
+SELECT * FROM r_asin('0');
+ERROR:  asin() unsuppoted argument type 25
+SELECT * FROM r_acos('0');
+ERROR:  acos() unsuppoted argument type 25
+SELECT * FROM r_atan('0');
+ERROR:  atan() unsuppoted argument type 25
+SELECT * FROM r_atan2('0', 1);
+ERROR:  atan2() unsuppoted argument type 25
+SELECT * FROM r_atan2(1, '0');
+ERROR:  atan2() unsuppoted argument type 25
+SELECT * FROM r_asin();
+ERROR:  function r_asin() does not exist
+LINE 1: SELECT * FROM r_asin();
+                      ^
+HINT:  No function matches the given name and argument types. You might need 
to add explicit type casts.
+SELECT * FROM r_acos();
+ERROR:  function r_acos() does not exist
+LINE 1: SELECT * FROM r_acos();
+                      ^
+HINT:  No function matches the given name and argument types. You might need 
to add explicit type casts.
+SELECT * FROM r_atan();
+ERROR:  function r_atan() does not exist
+LINE 1: SELECT * FROM r_atan();
+                      ^
+HINT:  No function matches the given name and argument types. You might need 
to add explicit type casts.
+SELECT * FROM r_atan2();
+ERROR:  function r_atan2() does not exist
+LINE 1: SELECT * FROM r_atan2();
+                      ^
+HINT:  No function matches the given name and argument types. You might need 
to add explicit type casts.
+SELECT * FROM r_atan2(1);
+ERROR:  atan2() invalid number of arguments
+--
 -- Cleanup
 --
 SELECT * FROM drop_graph('expr', true);
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 06dbc11..246f0f4 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -1340,6 +1340,104 @@ SELECT * FROM r_tan();
 SELECT * FROM r_cot();
 
 --
+-- Arc functions: asin, acos, atan, & atan2
+--
+SELECT * FROM cypher('expr', $$
+    RETURN asin(1)*2
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN acos(0)*2
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan(1)*4
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(1, 1)*4
+$$) AS (results agtype);
+SELECT * FROM asin(1), r_asin(1);
+SELECT * FROM acos(0), r_acos(0);
+SELECT * FROM atan(1), r_atan(1);
+SELECT * FROM atan2(1, 1), r_atan2(1, 1);
+-- should return null
+SELECT * FROM cypher('expr', $$
+    RETURN asin(1.1)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN acos(1.1)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN asin(-1.1)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN acos(-1.1)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN asin(null)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN acos(null)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan(null)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(null, null)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(null, 1)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(1, null)
+$$) AS (results agtype);
+SELECT * FROM r_asin(null);
+SELECT * FROM r_acos(null);
+SELECT * FROM r_atan(null);
+SELECT * FROM r_atan2(null, null);
+SELECT * FROM r_atan2(1, null);
+SELECT * FROM r_atan2(null, 1);
+-- should fail
+SELECT * FROM cypher('expr', $$
+    RETURN asin("0")
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN acos("0")
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan("0")
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan2("0", 1)
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(0, "1")
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN asin()
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN acos()
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan()
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan2()
+$$) AS (results agtype);
+SELECT * FROM cypher('expr', $$
+    RETURN atan2(null)
+$$) AS (results agtype);
+SELECT * FROM r_asin('0');
+SELECT * FROM r_acos('0');
+SELECT * FROM r_atan('0');
+SELECT * FROM r_atan2('0', 1);
+SELECT * FROM r_atan2(1, '0');
+SELECT * FROM r_asin();
+SELECT * FROM r_acos();
+SELECT * FROM r_atan();
+SELECT * FROM r_atan2();
+SELECT * FROM r_atan2(1);
+
+--
 -- Cleanup
 --
 SELECT * FROM drop_graph('expr', true);
diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c
index acdc94b..0af5d5d 100644
--- a/src/backend/parser/cypher_expr.c
+++ b/src/backend/parser/cypher_expr.c
@@ -72,7 +72,10 @@
 #define FUNC_RCOS       {"cos",        "r_cos",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
 #define FUNC_RTAN       {"tan",        "r_tan",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
 #define FUNC_RCOT       {"cot",        "r_cot",      ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
-
+#define FUNC_RASIN      {"asin",        "r_asin",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
+#define FUNC_RACOS      {"acos",        "r_acos",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
+#define FUNC_RATAN      {"atan",        "r_atan",    ANYOID,    0, 0, 
AGTYPEOID, 1, 1, false}
+#define FUNC_RATAN2     {"atan2",       "r_atan2",   ANYOID,    0, 0, 
AGTYPEOID, 2, 1, false}
 
 /* supported functions */
 #define SUPPORTED_FUNCTIONS {FUNC_TYPE, FUNC_ENDNODE, FUNC_HEAD, FUNC_ID, \
@@ -84,7 +87,8 @@
                              FUNC_RTRIM, FUNC_BTRIM, FUNC_RSUBSTR, \
                              FUNC_LSUBSTR, FUNC_BSUBSTR, FUNC_SPLIT, \
                              FUNC_REPLACE, FUNC_RSIN, FUNC_RCOS, FUNC_RTAN, \
-                             FUNC_RCOT}
+                             FUNC_RCOT, FUNC_RASIN, FUNC_RACOS, FUNC_RATAN, \
+                             FUNC_RATAN2}
 
 /* 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 b879af7..0cadda3 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -5907,3 +5907,206 @@ Datum r_cot(PG_FUNCTION_ARGS)
 
     PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
 }
+
+PG_FUNCTION_INFO_V1(r_asin);
+
+Datum r_asin(PG_FUNCTION_ARGS)
+{
+    int nargs;
+    Datum *args;
+    bool *nulls;
+    Oid *types;
+    agtype_value agtv_result;
+    float8 x;
+    float8 angle;
+    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("asin() invalid number of arguments")));
+
+    /* check for a null input */
+    if (nargs < 0 || nulls[0])
+        PG_RETURN_NULL();
+
+    /*
+     * asin() supports integer, float, and numeric or the agtype integer, 
float,
+     * and numeric for the input expression.
+     */
+
+    x = get_float_compatible_arg(args[0], types[0], "asin", &is_null);
+
+    /* verify that x is within range */
+    if (x < -1 || x > 1)
+        PG_RETURN_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 = DatumGetFloat8(DirectFunctionCall1(dasin,
+                                               Float8GetDatum(x)));
+
+    /* build the result */
+    agtv_result.type = AGTV_FLOAT;
+    agtv_result.val.float_value = angle;
+
+    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
+}
+
+PG_FUNCTION_INFO_V1(r_acos);
+
+Datum r_acos(PG_FUNCTION_ARGS)
+{
+    int nargs;
+    Datum *args;
+    bool *nulls;
+    Oid *types;
+    agtype_value agtv_result;
+    float8 x;
+    float8 angle;
+    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("acos() invalid number of arguments")));
+
+    /* check for a null input */
+    if (nargs < 0 || nulls[0])
+        PG_RETURN_NULL();
+
+    /*
+     * acos() supports integer, float, and numeric or the agtype integer, 
float,
+     * and numeric for the input expression.
+     */
+
+    x = get_float_compatible_arg(args[0], types[0], "acos", &is_null);
+
+    /* verify that x is within range */
+    if (x < -1 || x > 1)
+        PG_RETURN_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 = DatumGetFloat8(DirectFunctionCall1(dacos,
+                                               Float8GetDatum(x)));
+
+    /* build the result */
+    agtv_result.type = AGTV_FLOAT;
+    agtv_result.val.float_value = angle;
+
+    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
+}
+
+PG_FUNCTION_INFO_V1(r_atan);
+
+Datum r_atan(PG_FUNCTION_ARGS)
+{
+    int nargs;
+    Datum *args;
+    bool *nulls;
+    Oid *types;
+    agtype_value agtv_result;
+    float8 x;
+    float8 angle;
+    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("atan() invalid number of arguments")));
+
+    /* check for a null input */
+    if (nargs < 0 || nulls[0])
+        PG_RETURN_NULL();
+
+    /*
+     * atan() supports integer, float, and numeric or the agtype integer, 
float,
+     * and numeric for the input expression.
+     */
+
+    x = get_float_compatible_arg(args[0], types[0], "atan", &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 = DatumGetFloat8(DirectFunctionCall1(datan,
+                                               Float8GetDatum(x)));
+
+    /* build the result */
+    agtv_result.type = AGTV_FLOAT;
+    agtv_result.val.float_value = angle;
+
+    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
+}
+
+PG_FUNCTION_INFO_V1(r_atan2);
+
+Datum r_atan2(PG_FUNCTION_ARGS)
+{
+    int nargs;
+    Datum *args;
+    bool *nulls;
+    Oid *types;
+    agtype_value agtv_result;
+    float8 x, y;
+    float8 angle;
+    bool is_null = true;
+
+    /* extract argument values */
+    nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
+
+    /* check number of args */
+    if (nargs != 2)
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                        errmsg("atan2() invalid number of arguments")));
+
+    /* check for a null input */
+    if (nargs < 0 || nulls[0] || nulls[1])
+        PG_RETURN_NULL();
+
+    /*
+     * atan2() supports integer, float, and numeric or the agtype integer,
+     * float, and numeric for the input expressions.
+     */
+
+    y = get_float_compatible_arg(args[0], types[0], "atan2", &is_null);
+
+    /* check for a agtype null input */
+    if (is_null)
+        PG_RETURN_NULL();
+
+    x = get_float_compatible_arg(args[1], types[1], "atan2", &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 = DatumGetFloat8(DirectFunctionCall2(datan2,
+                                               Float8GetDatum(y),
+                                               Float8GetDatum(x)));
+
+    /* build the result */
+    agtv_result.type = AGTV_FLOAT;
+    agtv_result.val.float_value = angle;
+
+    PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
+}

Reply via email to