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/age.git


The following commit(s) were added to refs/heads/master by this push:
     new ca7e1748 Fix CASE and boolean typecasting in WHEN... THEN (#914)
ca7e1748 is described below

commit ca7e1748b1778f3574020683fef4152bf76687bf
Author: Dehowe Feng <[email protected]>
AuthorDate: Fri May 19 10:45:26 2023 -0700

    Fix CASE and boolean typecasting in WHEN... THEN (#914)
    
    Addresses issue #875.
    
    Simple fix in casting logic to allow CASE statements to handle boolean
    logic in the THEN statement.
    
    Added related regression tests.
---
 regress/expected/expr.out        | 35 +++++++++++++++++++++++++++++++++++
 regress/sql/expr.sql             | 17 +++++++++++++++++
 src/backend/parser/cypher_expr.c | 17 +++++++++++++++--
 3 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 91bc70fe..36dd8471 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -5974,6 +5974,41 @@ SELECT * FROM cypher('case_statement', $$CREATE ({i: {}, 
j: {i:1}})$$) AS (resul
 --------
 (0 rows)
 
+--standalone case & edge cases
+--base case
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN true THEN true 
END) $$) as (a agtype);
+  a   
+------
+ true
+(1 row)
+
+--should return 1 empty row
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN false THEN true 
END) $$) as (a agtype);
+ a 
+---
+ 
+(1 row)
+
+--should return 'false'
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN true THEN false 
END) $$) as (a agtype);
+   a   
+-------
+ false
+(1 row)
+
+--invalid case (WHEN should be boolean)
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN 1 THEN 'fail' END) 
$$) as (a agtype);
+ERROR:  cannot cast agtype integer to type boolean
+-- booleans + logic gates
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN true THEN (true 
AND true) END) $$) as (a agtype);
+  a   
+------
+ true
+(1 row)
+
+-- invalid mixed logic gate
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN true THEN (true 
AND 1) END) $$) as (a agtype);
+ERROR:  cannot cast agtype integer to type boolean
 --CASE WHEN condition THEN result END
 SELECT * FROM cypher('case_statement', $$
        MATCH (n)
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 456f38c8..4623f1c7 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -2462,6 +2462,23 @@ SELECT * FROM cypher('case_statement', $$CREATE ({i: 
true, j: false})$$) AS (res
 SELECT * FROM cypher('case_statement', $$CREATE ({i: [], j: [0,1,2]})$$) AS 
(result agtype);
 SELECT * FROM cypher('case_statement', $$CREATE ({i: {}, j: {i:1}})$$) AS 
(result agtype);
 
+--standalone case & edge cases
+--base case
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN true THEN true 
END) $$) as (a agtype);
+--should return 1 empty row
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN false THEN true 
END) $$) as (a agtype);
+--should return 'false'
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN true THEN false 
END) $$) as (a agtype);
+--invalid case (WHEN should be boolean)
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN 1 THEN 'fail' END) 
$$) as (a agtype);
+
+-- booleans + logic gates
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN true THEN (true 
AND true) END) $$) as (a agtype);
+-- invalid mixed logic gate
+SELECT * FROM cypher('case_statement', $$ RETURN (CASE WHEN true THEN (true 
AND 1) END) $$) as (a agtype);
+
+
+
 --CASE WHEN condition THEN result END
 SELECT * FROM cypher('case_statement', $$
        MATCH (n)
diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c
index afb695a3..b476e0b0 100644
--- a/src/backend/parser/cypher_expr.c
+++ b/src/backend/parser/cypher_expr.c
@@ -1125,7 +1125,7 @@ static Node *transform_CoalesceExpr(cypher_parsestate 
*cpstate, CoalesceExpr
 /*
  * Code borrowed from PG's transformCaseExpr and updated for AGE
  */
-static Node *transform_CaseExpr(cypher_parsestate *cpstate,CaseExpr
+static Node *transform_CaseExpr(cypher_parsestate *cpstate, CaseExpr
                                 *cexpr)
 {
     ParseState *pstate = &cpstate->pstate;
@@ -1210,7 +1210,20 @@ static Node *transform_CaseExpr(cypher_parsestate 
*cpstate,CaseExpr
 
     resultexprs = lcons(newcexpr->defresult, resultexprs);
 
-    ptype = select_common_type(pstate, resultexprs, "CASE", NULL);
+    /*
+     * we pass a NULL context to select_common_type because the common types 
can
+     * only be AGTYPEOID or BOOLOID. If it returns invalidoid, we know there 
is a
+     * boolean involved.
+     */
+    ptype = select_common_type(pstate, resultexprs, NULL, NULL);
+
+    //InvalidOid shows that there is a boolean in the result expr.
+    if (ptype == InvalidOid)
+    {
+        //we manually set the type to boolean here to handle the bool casting.
+        ptype = BOOLOID;
+    }
+
     Assert(OidIsValid(ptype));
     newcexpr->casetype = ptype;
     /* casecollid will be set by parse_collate.c */

Reply via email to