From 23795945a0e41db11ca0e39bcd0cfe79ba74f56f Mon Sep 17 00:00:00 2001 From: John Gemignani Date: Thu, 18 Jul 2024 08:05:33 -0700 Subject: [PATCH] Fix issue 1953 - PG Boolean used as AGTYPE object (#1972) Fixed issue 1953 - Server crashes when executing - SELECT * FROM cypher('ag_graph_3'...) This was due to the executor phase trying to use a PG Boolean as an AGTYPE object for the indirection argument. The fix was to use coerce_to_common_type on the input argument in transform_A_Indirection. Added regression tests. --- regress/expected/expr.out | 48 ++++++++++++++++++++++++++++++++ regress/sql/expr.sql | 14 ++++++++++ src/backend/parser/cypher_expr.c | 4 +++ 3 files changed, 66 insertions(+) diff --git a/regress/expected/expr.out b/regress/expected/expr.out index 275d60a09..ea43a625d 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -8355,8 +8355,56 @@ ERROR: argument 1: key must not be null SELECT agtype_build_map('name', 'John', 'null'::agtype, 1); ERROR: argument 3: key must not be null -- +-- Issue 1953 - crash when trying to use a boolean as an object +-- +SELECT * FROM create_graph('issue_1953'); +NOTICE: graph "issue_1953" has been created + create_graph +-------------- + +(1 row) + +SELECT * FROM cypher('issue_1953', $$ RETURN delete_global_graphs('issue_1953')[{}][{}][{}][{}][{}] $$) AS (result agtype); +ERROR: A_indirection could not convert type boolean to agtype +LINE 1: ...ypher('issue_1953', $$ RETURN delete_global_graphs('issue_19... + ^ +SELECT * FROM cypher('issue_1953', $$ RETURN delete_global_graphs('issue_1953')[{}] $$) AS (result agtype); +ERROR: A_indirection could not convert type boolean to agtype +LINE 1: ...ypher('issue_1953', $$ RETURN delete_global_graphs('issue_19... + ^ +SELECT * FROM cypher('issue_1953', $$ RETURN delete_global_graphs('issue_1953')[0] $$) AS (result agtype); +ERROR: A_indirection could not convert type boolean to agtype +LINE 1: ...ypher('issue_1953', $$ RETURN delete_global_graphs('issue_19... + ^ +SELECT * FROM cypher('issue_1953', $$ RETURN delete_global_graphs('issue_1953')[0..1] $$) AS (result agtype); +ERROR: A_indirection could not convert type boolean to agtype +LINE 1: ...ypher('issue_1953', $$ RETURN delete_global_graphs('issue_19... + ^ +SELECT * FROM cypher('issue_1953', $$ RETURN is_valid_label_name('issue_1953')[{}] $$) AS (result agtype); +ERROR: A_indirection could not convert type boolean to agtype +LINE 1: ...cypher('issue_1953', $$ RETURN is_valid_label_name('issue_19... + ^ +SELECT * FROM cypher('issue_1953', $$ RETURN is_valid_label_name('issue_1953')[0] $$) AS (result agtype); +ERROR: A_indirection could not convert type boolean to agtype +LINE 1: ...cypher('issue_1953', $$ RETURN is_valid_label_name('issue_19... + ^ +SELECT * FROM cypher('issue_1953', $$ RETURN is_valid_label_name('issue_1953')[0..1] $$) AS (result agtype); +ERROR: A_indirection could not convert type boolean to agtype +LINE 1: ...cypher('issue_1953', $$ RETURN is_valid_label_name('issue_19... + ^ +-- -- Cleanup -- +SELECT * FROM drop_graph('issue_1953', true); +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table issue_1953._ag_label_vertex +drop cascades to table issue_1953._ag_label_edge +NOTICE: graph "issue_1953" has been dropped + drop_graph +------------ + +(1 row) + SELECT * FROM drop_graph('expanded_map', true); NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to table expanded_map._ag_label_vertex diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql index f8334a4c7..a0a5e0c53 100644 --- a/regress/sql/expr.sql +++ b/regress/sql/expr.sql @@ -3404,9 +3404,23 @@ SELECT agtype_build_map('null'::agtype, 1); SELECT agtype_build_map(null, 1); SELECT agtype_build_map('name', 'John', 'null'::agtype, 1); +-- +-- Issue 1953 - crash when trying to use a boolean as an object +-- +SELECT * FROM create_graph('issue_1953'); +SELECT * FROM cypher('issue_1953', $$ RETURN delete_global_graphs('issue_1953')[{}][{}][{}][{}][{}] $$) AS (result agtype); +SELECT * FROM cypher('issue_1953', $$ RETURN delete_global_graphs('issue_1953')[{}] $$) AS (result agtype); +SELECT * FROM cypher('issue_1953', $$ RETURN delete_global_graphs('issue_1953')[0] $$) AS (result agtype); +SELECT * FROM cypher('issue_1953', $$ RETURN delete_global_graphs('issue_1953')[0..1] $$) AS (result agtype); + +SELECT * FROM cypher('issue_1953', $$ RETURN is_valid_label_name('issue_1953')[{}] $$) AS (result agtype); +SELECT * FROM cypher('issue_1953', $$ RETURN is_valid_label_name('issue_1953')[0] $$) AS (result agtype); +SELECT * FROM cypher('issue_1953', $$ RETURN is_valid_label_name('issue_1953')[0..1] $$) AS (result agtype); + -- -- Cleanup -- +SELECT * FROM drop_graph('issue_1953', true); SELECT * FROM drop_graph('expanded_map', true); SELECT * FROM drop_graph('issue_1124', true); SELECT * FROM drop_graph('issue_1303', true); diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c index ede946152..3733573a2 100644 --- a/src/backend/parser/cypher_expr.c +++ b/src/backend/parser/cypher_expr.c @@ -1331,6 +1331,7 @@ static Node *transform_column_ref_for_indirection(cypher_parsestate *cpstate, static Node *transform_A_Indirection(cypher_parsestate *cpstate, A_Indirection *a_ind) { + ParseState *pstate = &cpstate->pstate; int location; ListCell *lc = NULL; Node *ind_arg_expr = NULL; @@ -1369,6 +1370,9 @@ static Node *transform_A_Indirection(cypher_parsestate *cpstate, ind_arg_expr = transform_cypher_expr_recurse(cpstate, a_ind->arg); } + ind_arg_expr = coerce_to_common_type(pstate, ind_arg_expr, AGTYPEOID, + "A_indirection"); + /* get the location of the expression */ location = exprLocation(ind_arg_expr);