From 4d15c05de728327e70df51ff81bfb09e301c15be Mon Sep 17 00:00:00 2001 From: Wendel de Lana Date: Mon, 22 Apr 2024 07:38:45 +0000 Subject: [PATCH] Added integer conversion in toBoolean functions Implemented integer conversion to boolean in both toBoolean and toBooleanList functions. Also made corresponding changes to regression tests and broke long lines to adhere to the 79-column line length limit in the toBooleanList function. --- regress/expected/expr.out | 36 ++++++++++++++++++++----------- regress/sql/expr.sql | 17 +++++++++------ src/backend/utils/adt/agtype.c | 39 +++++++++++++++++++++++++++------- 3 files changed, 65 insertions(+), 27 deletions(-) diff --git a/regress/expected/expr.out b/regress/expected/expr.out index cc582cccc..8fc5da8e6 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -3077,6 +3077,22 @@ $$) AS (toBoolean agtype); false (1 row) +SELECT * FROM cypher('expr', $$ + RETURN toBoolean(1) +$$) AS (toBoolean agtype); + toboolean +----------- + true +(1 row) + +SELECT * FROM cypher('expr', $$ + RETURN toBoolean(0) +$$) AS (toBoolean agtype); + toboolean +----------- + false +(1 row) + -- should return null SELECT * FROM cypher('expr', $$ RETURN toBoolean("false_") @@ -3095,10 +3111,6 @@ $$) AS (toBoolean agtype); (1 row) -- should fail -SELECT * FROM cypher('expr', $$ - RETURN toBoolean(1) -$$) AS (toBoolean agtype); -ERROR: toBoolean() unsupported argument agtype 3 SELECT * FROM cypher('expr', $$ RETURN toBoolean() $$) AS (toBoolean agtype); @@ -3131,6 +3143,14 @@ $$) AS (toBooleanList agtype); [true, false, true] (1 row) +SELECT * FROM cypher('expr', $$ + RETURN toBooleanList([0,1,2,3,4]) +$$) AS (toBooleanList agtype); + tobooleanlist +--------------------------------- + [false, true, true, true, true] +(1 row) + -- should return null SELECT * FROM cypher('expr', $$ RETURN toBooleanList([]) @@ -3164,14 +3184,6 @@ $$) AS (toBooleanList agtype); [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) diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql index d58027122..18714f79b 100644 --- a/regress/sql/expr.sql +++ b/regress/sql/expr.sql @@ -1349,6 +1349,12 @@ $$) AS (toBoolean agtype); SELECT * FROM cypher('expr', $$ RETURN toBoolean("false") $$) AS (toBoolean agtype); +SELECT * FROM cypher('expr', $$ + RETURN toBoolean(1) +$$) AS (toBoolean agtype); +SELECT * FROM cypher('expr', $$ + RETURN toBoolean(0) +$$) AS (toBoolean agtype); -- should return null SELECT * FROM cypher('expr', $$ RETURN toBoolean("false_") @@ -1357,9 +1363,6 @@ SELECT * FROM cypher('expr', $$ RETURN toBoolean(null) $$) AS (toBoolean agtype); -- should fail -SELECT * FROM cypher('expr', $$ - RETURN toBoolean(1) -$$) AS (toBoolean agtype); SELECT * FROM cypher('expr', $$ RETURN toBoolean() $$) AS (toBoolean agtype); @@ -1377,6 +1380,10 @@ SELECT * FROM cypher('expr', $$ RETURN toBooleanList(["True", "False", "True"]) $$) AS (toBooleanList agtype); +SELECT * FROM cypher('expr', $$ + RETURN toBooleanList([0,1,2,3,4]) +$$) AS (toBooleanList agtype); + -- should return null SELECT * FROM cypher('expr', $$ RETURN toBooleanList([]) @@ -1394,10 +1401,6 @@ 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) diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c index c02a37a90..cbcacdc78 100644 --- a/src/backend/utils/adt/agtype.c +++ b/src/backend/utils/adt/agtype.c @@ -5720,8 +5720,8 @@ Datum age_toboolean(PG_FUNCTION_ARGS) PG_RETURN_NULL(); /* - * toBoolean() supports bool, text, cstring, or the agtype bool, and string - * input. + * toBoolean() supports bool, text, cstring, integer or the agtype bool, + * string and integer input. */ arg = args[0]; type = types[0]; @@ -5744,6 +5744,10 @@ Datum age_toboolean(PG_FUNCTION_ARGS) else PG_RETURN_NULL(); } + else if (type == INT2OID || type == INT4OID || type == INT8OID) + { + result = DatumGetBool(DirectFunctionCall1(int4_bool, arg)); + } else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("toBoolean() unsupported argument type %d", @@ -5778,6 +5782,11 @@ Datum age_toboolean(PG_FUNCTION_ARGS) else PG_RETURN_NULL(); } + else if (agtv_value->type == AGTV_INTEGER) + { + result = DatumGetBool(DirectFunctionCall1(int4_bool, + Int64GetDatum(agtv_value->val.int_value))); + } else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("toBoolean() unsupported argument agtype %d", @@ -5832,7 +5841,7 @@ Datum age_tobooleanlist(PG_FUNCTION_ARGS) /* iterate through the list */ for (i = 0; i < count; i++) { - // TODO: check element's type, it's value, and convert it to boolean if possible. + // check element's type, it's value, and convert it to boolean if possible. elem = get_ith_agtype_value_from_container(&agt_arg->root, i); bool_elem.type = AGTV_BOOL; @@ -5845,17 +5854,20 @@ Datum age_tobooleanlist(PG_FUNCTION_ARGS) 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); + 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); + 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); + agis_result.res = push_agtype_value(&agis_result.parse_state, + WAGT_ELEM, &bool_elem); } break; @@ -5863,14 +5875,25 @@ Datum age_tobooleanlist(PG_FUNCTION_ARGS) case AGTV_BOOL: bool_elem.val.boolean = elem->val.boolean; - agis_result.res = push_agtype_value(&agis_result.parse_state, WAGT_ELEM, &bool_elem); + agis_result.res = push_agtype_value(&agis_result.parse_state, + WAGT_ELEM, &bool_elem); + + break; + + case AGTV_INTEGER: + + bool_elem.val.boolean = DatumGetBool(DirectFunctionCall1(int4_bool, + Int64GetDatum(elem->val.int_value))); + 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); + agis_result.res = push_agtype_value(&agis_result.parse_state, + WAGT_ELEM, &bool_elem); break; }