From a3873dc0ea56dd78a618e329690fa35749dc7ca5 Mon Sep 17 00:00:00 2001 From: John Gemignani Date: Tue, 8 Aug 2023 11:36:27 -0700 Subject: [PATCH] Fix issue 1124: Segmentation fault when using specific tables (#1125) This is a fix for issue 1124 - Segmentation fault when using specific names for tables. This issue is due to an oversight of some very specific types of tables that are parameterless functions. The logic to walk through these nodes didn't expect them and would crash due to them. This fix adds in code to skip over these types of tables. Added regression tests. --- regress/expected/expr.out | 70 +++++++++++++++++++++++++++++ regress/sql/expr.sql | 18 ++++++++ src/backend/parser/cypher_analyze.c | 30 +++++++++++++ 3 files changed, 118 insertions(+) diff --git a/regress/expected/expr.out b/regress/expected/expr.out index b01cf977b..cb79a5189 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -6905,9 +6905,79 @@ SELECT * FROM cypher('graph_395', $$ MATCH (p:Project)-[:Has]->(t:Task)-[:Assign {"pn": "Project B", "tasks": [{"tn": "Task C", "users": [{"id": 1407374883553282, "label": "Person", "properties": {"age": 43, "name": "Bob"}}::vertex]}]} (2 rows) +--- +--- Fix: Segmentation fault when using specific names for tables #1124 +--- +--- The following are just a few commands to test SQLValueFunction types +--- +SELECT count(*) FROM CURRENT_ROLE; + count +------- + 1 +(1 row) + +SELECT count(*) FROM CURRENT_USER; + count +------- + 1 +(1 row) + +SELECT count(*) FROM USER; + count +------- + 1 +(1 row) + +SELECT count(*) FROM SESSION_USER; + count +------- + 1 +(1 row) + +SELECT * FROM CURRENT_CATALOG; + current_catalog +-------------------- + contrib_regression +(1 row) + +SELECT * FROM CURRENT_SCHEMA; + current_schema +---------------- + ag_catalog +(1 row) + +SELECT * FROM create_graph('issue_1124'); +NOTICE: graph "issue_1124" has been created + create_graph +-------------- + +(1 row) + +SELECT results, pg_typeof(user) FROM cypher('issue_1124', $$ CREATE (u) RETURN u $$) AS (results agtype), user; + results | pg_typeof +----------------------------------------------------------------+----------- + {"id": 281474976710657, "label": "", "properties": {}}::vertex | name +(1 row) + +SELECT results, pg_typeof(user) FROM cypher('issue_1124', $$ MATCH (u) RETURN u $$) AS (results agtype), user; + results | pg_typeof +----------------------------------------------------------------+----------- + {"id": 281474976710657, "label": "", "properties": {}}::vertex | name +(1 row) + -- -- Cleanup -- +SELECT * FROM drop_graph('issue_1124', true); +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table issue_1124._ag_label_vertex +drop cascades to table issue_1124._ag_label_edge +NOTICE: graph "issue_1124" 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 d4a7efbda..599378aec 100644 --- a/regress/sql/expr.sql +++ b/regress/sql/expr.sql @@ -2810,9 +2810,27 @@ SELECT * FROM cypher('graph_395', $$ MATCH (p:Project)-[:Has]->(t:Task)-[:Assign WITH p, collect(task) AS tasks WITH {pn: p.name, tasks:tasks} AS project RETURN project $$) AS (p agtype); + +--- +--- Fix: Segmentation fault when using specific names for tables #1124 +--- +--- The following are just a few commands to test SQLValueFunction types +--- + +SELECT count(*) FROM CURRENT_ROLE; +SELECT count(*) FROM CURRENT_USER; +SELECT count(*) FROM USER; +SELECT count(*) FROM SESSION_USER; +SELECT * FROM CURRENT_CATALOG; +SELECT * FROM CURRENT_SCHEMA; +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; + -- -- Cleanup -- +SELECT * FROM drop_graph('issue_1124', 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 a78959006..848c32982 100644 --- a/src/backend/parser/cypher_analyze.c +++ b/src/backend/parser/cypher_analyze.c @@ -167,6 +167,21 @@ static bool convert_cypher_walker(Node *node, ParseState *pstate) parser_errposition(pstate, exprLocation((Node *)funcexpr)))); } + /* + * From PG - + * SQLValueFunction - parameterless functions with special grammar + * productions. + * + * 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)) + { + return false; + } + return expression_tree_walker((Node *)funcexpr->args, convert_cypher_walker, pstate); } @@ -296,6 +311,21 @@ static bool is_rte_cypher(RangeTblEntry *rte) */ static bool is_func_cypher(FuncExpr *funcexpr) { + /* + * From PG - + * SQLValueFunction - parameterless functions with special grammar + * productions. + * + * 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)) + { + return false; + } + return is_oid_ag_func(funcexpr->funcid, "cypher"); }