This is an automated email from the ASF dual-hosted git repository.
dehowef 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 b5d866fa Fix issue 1303: Server crashes on executing SELECT * FROM
agtype(null); (#1317)
b5d866fa is described below
commit b5d866fa100c249f036caf84b11cb8afa0d26a15
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;
}