From 9b4a3e5c267f74554ed5571754f18f050e2167f3 Mon Sep 17 00:00:00 2001 From: John Gemignani Date: Mon, 8 Jul 2024 16:31:31 -0700 Subject: [PATCH] Fix issue 1953 - PG Boolean used as AGTYPE object (#1959) 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 725b04984..bdc3fd936 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -8426,8 +8426,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 87c860ac1..86e78c91c 100644 --- a/regress/sql/expr.sql +++ b/regress/sql/expr.sql @@ -3431,9 +3431,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 e1ca63936..cbd720046 100644 --- a/src/backend/parser/cypher_expr.c +++ b/src/backend/parser/cypher_expr.c @@ -1318,6 +1318,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; @@ -1356,6 +1357,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);