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

dehowef pushed a commit to branch PG13
in repository https://gitbox.apache.org/repos/asf/age.git


The following commit(s) were added to refs/heads/PG13 by this push:
     new 43742edb Added toBooleanList() (#1164)
43742edb is described below

commit 43742edb7d7952989b3a91be6b64e7390a0cf379
Author: Matheus Farias de Oliveira Matsumoto 
<[email protected]>
AuthorDate: Fri Aug 18 19:45:00 2023 -0300

    Added toBooleanList() (#1164)
    
    - Same as openCypher's toBooleanList() function: 
https://neo4j.com/docs/cypher-manual/current/functions/list/#functions-tobooleanlist
    - The toBooleanList() function converts a list of values and returns a list 
of boolean values.
    - If any values are not convertible to boolean they will be null in the 
list returned.
    - Created regression tests for it.
---
 age--1.3.0.sql                 |  8 ++++
 regress/expected/expr.out      | 81 ++++++++++++++++++++++++++++++++++++++++
 regress/sql/expr.sql           | 48 ++++++++++++++++++++++++
 src/backend/utils/adt/agtype.c | 85 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 222 insertions(+)

diff --git a/age--1.3.0.sql b/age--1.3.0.sql
index e97a3ce5..3416bb83 100644
--- a/age--1.3.0.sql
+++ b/age--1.3.0.sql
@@ -3509,6 +3509,14 @@ RETURNS NULL ON NULL INPUT
 PARALLEL SAFE
 AS 'MODULE_PATHNAME';
 
+CREATE FUNCTION ag_catalog.age_tobooleanlist(variadic "any")
+RETURNS agtype
+LANGUAGE c
+IMMUTABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
 CREATE FUNCTION ag_catalog.age_tofloat(variadic "any")
 RETURNS agtype
 LANGUAGE c
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index cb79a518..c52056e7 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -2819,6 +2819,87 @@ ERROR:  function ag_catalog.age_toboolean() does not 
exist
 LINE 2:     RETURN toBoolean()
                    ^
 HINT:  No function matches the given name and argument types. You might need 
to add explicit type casts.
+-- toBooleanList()
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([true, false, true])
+$$) AS (toBooleanList agtype);
+    tobooleanlist    
+---------------------
+ [true, false, true]
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(["true", "false", "true"])
+$$) AS (toBooleanList agtype);
+    tobooleanlist    
+---------------------
+ [true, false, true]
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(["True", "False", "True"])
+$$) AS (toBooleanList agtype);
+    tobooleanlist    
+---------------------
+ [true, false, true]
+(1 row)
+
+-- should return null
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([])
+$$) AS (toBooleanList agtype);
+ tobooleanlist 
+---------------
+ 
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([null, null, null])
+$$) AS (toBooleanList agtype);
+   tobooleanlist    
+--------------------
+ [null, null, null]
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(["Hello", "world!"])
+$$) AS (toBooleanList agtype);
+ tobooleanlist 
+---------------
+ [null, null]
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([["A", "B"], ["C", "D"]])
+$$) AS (toBooleanList agtype);
+ tobooleanlist 
+---------------
+ [null, null]
+(1 row)
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([0,1,2,3,4])
+$$) AS (toBooleanList agtype);
+         tobooleanlist          
+--------------------------------
+ [null, null, null, null, null]
+(1 row)
+
+-- should fail
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(fail)
+$$) AS (toBooleanList agtype);
+ERROR:  could not find rte for fail
+LINE 2:     RETURN toBooleanList(fail)
+                                 ^
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList("fail")
+$$) AS (toBooleanList agtype);
+ERROR:  toBooleanList() argument must resolve to a list or null
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(123)
+$$) AS (toBooleanList agtype);
+ERROR:  toBooleanList() argument must resolve to a list or null
 -- toFloat()
 SELECT * FROM cypher('expr', $$
     RETURN toFloat(1)
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 599378ae..779623a9 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -1269,6 +1269,54 @@ $$) AS (toBoolean agtype);
 SELECT * FROM cypher('expr', $$
     RETURN toBoolean()
 $$) AS (toBoolean agtype);
+
+-- toBooleanList()
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([true, false, true])
+$$) AS (toBooleanList agtype);
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(["true", "false", "true"])
+$$) AS (toBooleanList agtype);
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(["True", "False", "True"])
+$$) AS (toBooleanList agtype);
+
+-- should return null
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([])
+$$) AS (toBooleanList agtype);
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([null, null, null])
+$$) AS (toBooleanList agtype);
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(["Hello", "world!"])
+$$) AS (toBooleanList agtype);
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([["A", "B"], ["C", "D"]])
+$$) AS (toBooleanList agtype);
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList([0,1,2,3,4])
+$$) AS (toBooleanList agtype);
+
+-- should fail
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(fail)
+$$) AS (toBooleanList agtype);
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList("fail")
+$$) AS (toBooleanList agtype);
+
+SELECT * FROM cypher('expr', $$
+    RETURN toBooleanList(123)
+$$) AS (toBooleanList agtype);
+
 -- toFloat()
 SELECT * FROM cypher('expr', $$
     RETURN toFloat(1)
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 1e5b3c92..b6ba5fef 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -5182,6 +5182,91 @@ Datum age_toboolean(PG_FUNCTION_ARGS)
     PG_RETURN_POINTER(agtype_value_to_agtype(&agtv_result));
 }
 
+PG_FUNCTION_INFO_V1(age_tobooleanlist);
+/*
+ * Converts a list of values and returns a list of boolean values. If any 
values are not convertible
+ * to boolean, they will be null in the list returned.
+ * */
+Datum age_tobooleanlist(PG_FUNCTION_ARGS)
+{
+       agtype *agt_arg = NULL;
+       agtype_in_state agis_result;
+       agtype_value *elem;
+       agtype_value bool_elem;
+    char *string = NULL;
+    int count;
+    int i;
+
+       // check for null
+    if (PG_ARGISNULL(0))
+        PG_RETURN_NULL();
+
+    agt_arg = AG_GET_ARG_AGTYPE_P(0);
+    // check for an array
+    if (!AGT_ROOT_IS_ARRAY(agt_arg) || AGT_ROOT_IS_SCALAR(agt_arg))
+               ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                       errmsg("toBooleanList() argument must 
resolve to a list or null")));
+
+    count = AGT_ROOT_COUNT(agt_arg);
+
+    // if we have an empty list or only one element in the list, return null
+    if (count == 0)
+               PG_RETURN_NULL();
+
+    // clear the result structure 
+    MemSet(&agis_result, 0, sizeof(agtype_in_state));
+
+    // push the beginning of the array 
+    agis_result.res = push_agtype_value(&agis_result.parse_state,
+               WAGT_BEGIN_ARRAY, NULL);
+
+       // iterate through the list
+       for (i = 0; i < count; i++)
+       {
+               elem = get_ith_agtype_value_from_container(&agt_arg->root, i);
+               bool_elem.type = AGTV_BOOL;
+
+               switch (elem->type)
+               {
+                       case AGTV_STRING:
+                               string = elem->val.string.val;
+                               if (pg_strcasecmp(string, "true") == 0)
+                               {
+                                       bool_elem.val.boolean = true;
+                                       agis_result.res = 
push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
+                               }
+                               else if (pg_strcasecmp(string, "false") == 0)
+                               {
+                                       bool_elem.val.boolean = false;
+                                       agis_result.res = 
push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
+                               }
+                               else
+                               {
+                                       bool_elem.type = AGTV_NULL;
+                                       agis_result.res = 
push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
+                               }
+                               break;
+
+
+                       case AGTV_BOOL:
+                               bool_elem.val.boolean = elem->val.boolean;
+                               agis_result.res = 
push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
+                               break;
+
+
+                       default:
+                               bool_elem.type = AGTV_NULL;
+                               agis_result.res = 
push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem);
+                               break;
+               }
+       }
+
+       // push the end of the array
+       agis_result.res = push_agtype_value(&agis_result.parse_state, 
WAGT_END_ARRAY, NULL);
+
+       PG_RETURN_POINTER(agtype_value_to_agtype(agis_result.res));
+}
+
 PG_FUNCTION_INFO_V1(age_tofloat);
 
 Datum age_tofloat(PG_FUNCTION_ARGS)

Reply via email to