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 0ec2d1cd9d57c1a67d3732813c59ba23222ef6b2
Author: Muhammad Taha Naveed <[email protected]>
AuthorDate: Thu Oct 26 20:40:50 2023 +0500

    Fix issue #1302 - crash on NULL input to UNWIND (#1304)
    
    - Added a check for NULL input in age_unnest.
    - Added regression tests.
---
 regress/expected/cypher_unwind.out | 69 ++++++++++++++++++++++++++++++++++++++
 regress/sql/cypher_unwind.sql      | 29 +++++++++++++++-
 src/backend/utils/adt/agtype.c     |  9 ++++-
 3 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/regress/expected/cypher_unwind.out 
b/regress/expected/cypher_unwind.out
index 3c454f10..fae1a26f 100644
--- a/regress/expected/cypher_unwind.out
+++ b/regress/expected/cypher_unwind.out
@@ -200,6 +200,65 @@ $$) as (i agtype);
  {"id": 281474976710659, "label": "", "properties": {"a": [7, 8, 9], "name": 
"node3", "type": "vertex"}}::vertex
 (3 rows)
 
+--
+-- Issue 1302
+--
+SELECT create_graph('issue_1302');
+NOTICE:  graph "issue_1302" has been created
+ create_graph 
+--------------
+ 
+(1 row)
+
+SELECT * FROM cypher('cypher_unwind', $$
+    CREATE (agtype {name: 'node1', a: [1, 2, 3]}),
+           (m {name: 'node2', a: [4, 5, 6]}),
+           (o {name: 'node3', a: [7, 8, 9]}),
+           (n)-[:KNOWS]->(m),
+           (m)-[:KNOWS]->(o)
+$$) as (i agtype);
+ i 
+---
+(0 rows)
+
+SELECT * FROM cypher('cypher_unwind', $$
+    MATCH (n)
+    WITH n.a AS a
+    UNWIND a AS i
+    RETURN *
+$$) as (i agtype, j agtype);
+     i     | j 
+-----------+---
+ [1, 2, 3] | 1
+ [1, 2, 3] | 2
+ [1, 2, 3] | 3
+ [4, 5, 6] | 4
+ [4, 5, 6] | 5
+ [4, 5, 6] | 6
+ [7, 8, 9] | 7
+ [7, 8, 9] | 8
+ [7, 8, 9] | 9
+ [1, 2, 3] | 1
+ [1, 2, 3] | 2
+ [1, 2, 3] | 3
+ [4, 5, 6] | 4
+ [4, 5, 6] | 5
+ [4, 5, 6] | 6
+ [7, 8, 9] | 7
+ [7, 8, 9] | 8
+ [7, 8, 9] | 9
+           | 
+(19 rows)
+
+SELECT * FROM cypher('cypher_unwind', $$
+    UNWIND NULL as i
+    RETURN i
+$$) as (i agtype);
+ i 
+---
+ 
+(1 row)
+
 --
 -- Clean up
 --
@@ -214,3 +273,13 @@ NOTICE:  graph "cypher_unwind" has been dropped
  
 (1 row)
 
+SELECT drop_graph('issue_1302', true);
+NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to table issue_1302._ag_label_vertex
+drop cascades to table issue_1302._ag_label_edge
+NOTICE:  graph "issue_1302" has been dropped
+ drop_graph 
+------------
+ 
+(1 row)
+
diff --git a/regress/sql/cypher_unwind.sql b/regress/sql/cypher_unwind.sql
index 8e8c74bc..0e8440af 100644
--- a/regress/sql/cypher_unwind.sql
+++ b/regress/sql/cypher_unwind.sql
@@ -122,8 +122,35 @@ SELECT * FROM cypher('cypher_unwind', $$
     RETURN n
 $$) as (i agtype);
 
+--
+-- Issue 1302
+--
+
+SELECT create_graph('issue_1302');
+
+SELECT * FROM cypher('cypher_unwind', $$
+    CREATE (agtype {name: 'node1', a: [1, 2, 3]}),
+           (m {name: 'node2', a: [4, 5, 6]}),
+           (o {name: 'node3', a: [7, 8, 9]}),
+           (n)-[:KNOWS]->(m),
+           (m)-[:KNOWS]->(o)
+$$) as (i agtype);
+
+SELECT * FROM cypher('cypher_unwind', $$
+    MATCH (n)
+    WITH n.a AS a
+    UNWIND a AS i
+    RETURN *
+$$) as (i agtype, j agtype);
+
+SELECT * FROM cypher('cypher_unwind', $$
+    UNWIND NULL as i
+    RETURN i
+$$) as (i agtype);
+
 --
 -- Clean up
 --
 
-SELECT drop_graph('cypher_unwind', true);
\ No newline at end of file
+SELECT drop_graph('cypher_unwind', true);
+SELECT drop_graph('issue_1302', true);
\ No newline at end of file
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 486a8734..41235106 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -10949,7 +10949,7 @@ PG_FUNCTION_INFO_V1(age_unnest);
  */
 Datum age_unnest(PG_FUNCTION_ARGS)
 {
-    agtype *agtype_arg = AG_GET_ARG_AGTYPE_P(0);
+    agtype *agtype_arg = NULL;
     ReturnSetInfo *rsi;
     Tuplestorestate *tuple_store;
     TupleDesc tupdesc;
@@ -10960,6 +10960,13 @@ Datum age_unnest(PG_FUNCTION_ARGS)
     agtype_value v;
     agtype_iterator_token r;
 
+    // check for null
+    if (PG_ARGISNULL(0))
+    {
+        PG_RETURN_NULL();
+    }
+
+    agtype_arg = AG_GET_ARG_AGTYPE_P(0);
     if (!AGT_ROOT_IS_ARRAY(agtype_arg))
     {
         ereport(ERROR,

Reply via email to