From 8b4b2e0dfd30e130b0af21404898b167ffebc64f 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 942fc1018..b0679708f 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -6967,9 +6967,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 7cd74fed9..b22f47a22 100644 --- a/regress/sql/expr.sql +++ b/regress/sql/expr.sql @@ -2835,9 +2835,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 425b1167b..fc9e5a9df 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"); }