From e3afeebcdbdeb1fd79bc8278c4b6f8302aad522b 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 52f5eb026..99a91b662 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -6968,9 +6968,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 501286282..f3076fb39 100644 --- a/regress/sql/expr.sql +++ b/regress/sql/expr.sql @@ -2836,9 +2836,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 1e881c3b7..54cc6e713 100644 --- a/src/backend/parser/cypher_analyze.c +++ b/src/backend/parser/cypher_analyze.c @@ -166,6 +166,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); } @@ -295,6 +310,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"); }