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

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

commit 105b78e31878df1c8f7b484400a675f40fdfac36
Author: Zainab Saad <[email protected]>
AuthorDate: Fri Oct 27 21:48:59 2023 +0500

    Fix issue 1303: Server crashes on executing SELECT * FROM agtype(null); 
(#1317)
    
    * Add additional checks for Const expression nodes for which the
          walker code would crash.
    
        * The server crashes for few other expr types too including Const,
          OpExpr, Var, BoolExpr and CoerceViaIO for which checks are added
    
        * Add regression tests
---
 regress/expected/expr.out           | 156 ++++++++++++++++++++++++++++++++++++
 regress/sql/expr.sql                |  37 +++++++++
 src/backend/parser/cypher_analyze.c |  26 ++++--
 3 files changed, 213 insertions(+), 6 deletions(-)

diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index 30d66793..476a0d84 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -7304,6 +7304,152 @@ SELECT results, pg_typeof(user) FROM 
cypher('issue_1124', $$ MATCH (u) RETURN u
  {"id": 281474976710657, "label": "", "properties": {}}::vertex | name
 (1 row)
 
+--
+-- issue 1303: segmentation fault on queries like SELECT * FROM agtype(null);
+--
+-- Test Const and CoerceViaIO expression node types
+SELECT * FROM agtype(null);
+ agtype 
+--------
+ 
+(1 row)
+
+SELECT * FROM agtype('1');
+ agtype 
+--------
+ 1
+(1 row)
+
+SELECT * FROM agtype('[1, 2, 3]');
+  agtype   
+-----------
+ [1, 2, 3]
+(1 row)
+
+SELECT * FROM agtype('{"a": 1}');
+  agtype  
+----------
+ {"a": 1}
+(1 row)
+
+SELECT * FROM agtype('{"id": 844424930131971, "label": "v", "properties": 
{"i": 1}}::vertex');
+                                agtype                                 
+-----------------------------------------------------------------------
+ {"id": 844424930131971, "label": "v", "properties": {"i": 1}}::vertex
+(1 row)
+
+SELECT * FROM agtype('{"id": 1407374883553282, "label": "e1", "end_id": 
1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge');
+                                                          agtype               
                                            
+---------------------------------------------------------------------------------------------------------------------------
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, 
"start_id": 1125899906842625, "properties": {}}::edge
+(1 row)
+
+SELECT * FROM agtype('[{"id": 1125899906842625, "label": "v1", "properties": 
{"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 
1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 
1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, 
{"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 
1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": 
"v1", "properties": {"id": [...]
+                                                                               
                                                                                
                                                                                
     agtype                                                                     
                                                                                
                                                                                
                
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [{"id": 1125899906842625, "label": "v1", "properties": {"id": 
"initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 
1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 
1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, 
{"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 
1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": 
"v1", "properties": {"id": "end"}}::vertex]::path
+(1 row)
+
+SELECT * FROM text(1);
+ text 
+------
+ 1
+(1 row)
+
+SELECT * FROM text('1');
+ text 
+------
+ 1
+(1 row)
+
+SELECT * FROM int4(1);
+ int4 
+------
+    1
+(1 row)
+
+SELECT * FROM json('1');
+ json 
+------
+ 1
+(1 row)
+
+SELECT * FROM jsonb('1');
+ jsonb 
+-------
+ 1
+(1 row)
+
+SELECT * FROM bytea('1');
+ bytea 
+-------
+ \x31
+(1 row)
+
+-- Test Var expression node types
+SELECT create_graph('issue_1303');
+NOTICE:  graph "issue_1303" has been created
+ create_graph 
+--------------
+ 
+(1 row)
+
+SELECT result, agtype('[1, 2, 3]')  FROM cypher('issue_1303', $$ CREATE (u) 
RETURN u $$) AS (result agtype);
+                             result                             |  agtype   
+----------------------------------------------------------------+-----------
+ {"id": 281474976710657, "label": "", "properties": {}}::vertex | [1, 2, 3]
+(1 row)
+
+SELECT result, result2, pg_typeof(result2) FROM cypher('issue_1303', $$ MATCH 
(u) RETURN u $$) AS (result agtype), agtype('[1, 2, 3]') AS result2;
+                             result                             |  result2  | 
pg_typeof 
+----------------------------------------------------------------+-----------+-----------
+ {"id": 281474976710657, "label": "", "properties": {}}::vertex | [1, 2, 3] | 
agtype
+(1 row)
+
+SELECT result, result2, pg_typeof(result2) FROM cypher('issue_1303', $$ MATCH 
(u) RETURN u $$) AS (result agtype), text(1) AS result2;
+                             result                             | result2 | 
pg_typeof 
+----------------------------------------------------------------+---------+-----------
+ {"id": 281474976710657, "label": "", "properties": {}}::vertex | 1       | 
text
+(1 row)
+
+SELECT result, result2, pg_typeof(result2), result3, pg_typeof(result3) FROM 
cypher('issue_1303', $$ MATCH (u) RETURN u $$) AS (result agtype), text(1) AS 
result2, agtype(result) AS result3;
+                             result                             | result2 | 
pg_typeof |                            result3                             | 
pg_typeof 
+----------------------------------------------------------------+---------+-----------+----------------------------------------------------------------+-----------
+ {"id": 281474976710657, "label": "", "properties": {}}::vertex | 1       | 
text      | {"id": 281474976710657, "label": "", "properties": {}}::vertex | 
agtype
+(1 row)
+
+SELECT result, result2, pg_typeof(result2), result3, pg_typeof(result3) FROM 
cypher('issue_1303', $$ MATCH (u) RETURN u $$) AS (result agtype), text(1) AS 
result2, agtype(result2) AS result3;
+                             result                             | result2 | 
pg_typeof | result3 | pg_typeof 
+----------------------------------------------------------------+---------+-----------+---------+-----------
+ {"id": 281474976710657, "label": "", "properties": {}}::vertex | 1       | 
text      | 1       | agtype
+(1 row)
+
+-- Text OpExpr expression node types
+SELECT * FROM agtype('[1, 2, 3]'::agtype || '[5, 6, 7]');
+       agtype       
+--------------------
+ [1, 2, 3, 5, 6, 7]
+(1 row)
+
+SELECT * FROM agtype('[1, 2, 3]'::agtype -> 2);
+ agtype 
+--------
+ 3
+(1 row)
+
+SELECT * FROM agtype('{"a": 1, "b": 2}'::agtype -> 'a'::text);
+ agtype 
+--------
+ 1
+(1 row)
+
+-- Text BoolExpr expression node types
+SELECT * FROM bool(true AND false);
+ bool 
+------
+ f
+(1 row)
+
 --
 -- Cleanup
 --
@@ -7317,6 +7463,16 @@ NOTICE:  graph "issue_1124" has been dropped
  
 (1 row)
 
+SELECT * FROM drop_graph('issue_1303', true);
+NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to table issue_1303._ag_label_vertex
+drop cascades to table issue_1303._ag_label_edge
+NOTICE:  graph "issue_1303" has been dropped
+ drop_graph 
+------------
+ 
+(1 row)
+
 SELECT * FROM drop_graph('graph_395', true);
 NOTICE:  drop cascades to 7 other objects
 DETAIL:  drop cascades to table graph_395._ag_label_vertex
diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql
index 13d1ca3c..bf9ffc94 100644
--- a/regress/sql/expr.sql
+++ b/regress/sql/expr.sql
@@ -2986,10 +2986,47 @@ SELECT * FROM create_graph('issue_1124');
 SELECT results, pg_typeof(user) FROM cypher('issue_1124', $$ CREATE (u) RETURN 
u $$) AS (results agtype), user;
 SELECT results, pg_typeof(user) FROM cypher('issue_1124', $$ MATCH (u) RETURN 
u $$) AS (results agtype), user;
 
+--
+-- issue 1303: segmentation fault on queries like SELECT * FROM agtype(null);
+--
+
+-- Test Const and CoerceViaIO expression node types
+SELECT * FROM agtype(null);
+SELECT * FROM agtype('1');
+SELECT * FROM agtype('[1, 2, 3]');
+SELECT * FROM agtype('{"a": 1}');
+SELECT * FROM agtype('{"id": 844424930131971, "label": "v", "properties": 
{"i": 1}}::vertex');
+SELECT * FROM agtype('{"id": 1407374883553282, "label": "e1", "end_id": 
1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge');
+SELECT * FROM agtype('[{"id": 1125899906842625, "label": "v1", "properties": 
{"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 
1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 
1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, 
{"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 
1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": 
"v1", "properties": {"id": [...]
+
+SELECT * FROM text(1);
+SELECT * FROM text('1');
+SELECT * FROM int4(1);
+SELECT * FROM json('1');
+SELECT * FROM jsonb('1');
+SELECT * FROM bytea('1');
+
+-- Test Var expression node types
+SELECT create_graph('issue_1303');
+SELECT result, agtype('[1, 2, 3]')  FROM cypher('issue_1303', $$ CREATE (u) 
RETURN u $$) AS (result agtype);
+SELECT result, result2, pg_typeof(result2) FROM cypher('issue_1303', $$ MATCH 
(u) RETURN u $$) AS (result agtype), agtype('[1, 2, 3]') AS result2;
+SELECT result, result2, pg_typeof(result2) FROM cypher('issue_1303', $$ MATCH 
(u) RETURN u $$) AS (result agtype), text(1) AS result2;
+SELECT result, result2, pg_typeof(result2), result3, pg_typeof(result3) FROM 
cypher('issue_1303', $$ MATCH (u) RETURN u $$) AS (result agtype), text(1) AS 
result2, agtype(result) AS result3;
+SELECT result, result2, pg_typeof(result2), result3, pg_typeof(result3) FROM 
cypher('issue_1303', $$ MATCH (u) RETURN u $$) AS (result agtype), text(1) AS 
result2, agtype(result2) AS result3;
+
+-- Text OpExpr expression node types
+SELECT * FROM agtype('[1, 2, 3]'::agtype || '[5, 6, 7]');
+SELECT * FROM agtype('[1, 2, 3]'::agtype -> 2);
+SELECT * FROM agtype('{"a": 1, "b": 2}'::agtype -> 'a'::text);
+
+-- Text BoolExpr expression node types
+SELECT * FROM bool(true AND false);
+
 --
 -- Cleanup
 --
 SELECT * FROM drop_graph('issue_1124', true);
+SELECT * FROM drop_graph('issue_1303', true);
 SELECT * FROM drop_graph('graph_395', true);
 SELECT * FROM drop_graph('chained', true);
 SELECT * FROM drop_graph('VLE', true);
diff --git a/src/backend/parser/cypher_analyze.c 
b/src/backend/parser/cypher_analyze.c
index a481b315..64725a23 100644
--- a/src/backend/parser/cypher_analyze.c
+++ b/src/backend/parser/cypher_analyze.c
@@ -171,13 +171,20 @@ static bool convert_cypher_walker(Node *node, ParseState 
*pstate)
          * From PG -
          * SQLValueFunction - parameterless functions with special grammar
          *                    productions.
+         * CoerceViaIO - represents a type coercion between two types whose 
textual
+         *               representations are compatible
+         * Var - expression node representing a variable (ie, a table column)
+         * OpExpr - expression node for an operator invocation
+         * Const - constant value or expression node
+         * BoolExpr - expression node for the basic Boolean operators AND, OR, 
NOT
          *
          * These are a special case that needs to be ignored.
          *
-         * TODO: This likely needs to be done with XmlExpr types, and maybe
-         *       a few others too.
          */
-        if (IsA(funcexpr, SQLValueFunction))
+        if (IsA(funcexpr, SQLValueFunction)
+                || IsA(funcexpr, CoerceViaIO)
+                || IsA(funcexpr, Var)   || IsA(funcexpr, OpExpr)
+                || IsA(funcexpr, Const) || IsA(funcexpr, BoolExpr))
         {
             return false;
         }
@@ -315,13 +322,20 @@ static bool is_func_cypher(FuncExpr *funcexpr)
      * From PG -
      * SQLValueFunction - parameterless functions with special grammar
      *                    productions.
+     * CoerceViaIO - represents a type coercion between two types whose textual
+     *               representations are compatible
+     * Var - expression node representing a variable (ie, a table column)
+     * OpExpr - expression node for an operator invocation
+     * Const - constant value or expression node
+     * BoolExpr - expression node for the basic Boolean operators AND, OR, NOT
      *
      * These are a special case that needs to be ignored.
      *
-     *  TODO: This likely needs to be done with XmlExpr types, and maybe
-     *        a few others too.
      */
-    if (IsA(funcexpr, SQLValueFunction))
+    if (IsA(funcexpr, SQLValueFunction)
+            || IsA(funcexpr, CoerceViaIO)
+            || IsA(funcexpr, Var)   || IsA(funcexpr, OpExpr)
+            || IsA(funcexpr, Const) || IsA(funcexpr, BoolExpr))
     {
         return false;
     }

Reply via email to