Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Issue 1634: Setting all properties with map object causes error #1637

Merged
merged 1 commit into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions regress/expected/cypher_set.out
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,59 @@ $$) AS (p agtype);
{"id": 281474976710658, "label": "", "properties": {"n0": true, "n1": false, "n2": true}}::vertex
(1 row)

--
-- Issue 1634: Setting all properties with map object causes error
--
SELECT * FROM create_graph('issue_1634');
NOTICE: graph "issue_1634" has been created
create_graph
--------------

(1 row)

-- this did not work and was fixed
SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map
MERGE (v:PERSION {id: '1'})
SET v=map
RETURN v,map $$) as (v agtype, map agtype);
v | map
-----------------------------------------------------------------------------------------------------+----------------------------------
{"id": 844424930131969, "label": "PERSION", "properties": {"last": "snow", "first": "jon"}}::vertex | {"last": "snow", "first": "jon"}
(1 row)

-- these 2 did work and are added as extra tests
SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
u
---
(0 rows)

SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map
MERGE (v:PERSION {id: '1'})
SET v.first=map.first, v.last=map.last
RETURN v,map $$) as (v agtype, map agtype);
v | map
----------------------------------------------------------------------------------------------------------------+----------------------------------
{"id": 844424930131970, "label": "PERSION", "properties": {"id": "1", "last": "snow", "first": "jon"}}::vertex | {"last": "snow", "first": "jon"}
(1 row)

SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
u
---
(0 rows)

SELECT * FROM cypher('issue_1634', $$ MERGE (v:PERSION {id: '1'})
SET v={first: 'jon', last: 'snow'}
RETURN v $$) as (v agtype);
v
-----------------------------------------------------------------------------------------------------
{"id": 844424930131971, "label": "PERSION", "properties": {"last": "snow", "first": "jon"}}::vertex
(1 row)

SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
u
---
(0 rows)

--
-- Clean up
--
Expand Down Expand Up @@ -974,4 +1027,17 @@ NOTICE: graph "cypher_set_1" has been dropped

(1 row)

SELECT drop_graph('issue_1634', true);
NOTICE: drop cascades to 3 other objects
DETAIL: drop cascades to table issue_1634._ag_label_vertex
drop cascades to table issue_1634._ag_label_edge
drop cascades to table issue_1634."PERSION"
NOTICE: graph "issue_1634" has been dropped
drop_graph
------------

(1 row)

--
-- End
--
29 changes: 28 additions & 1 deletion regress/sql/cypher_set.sql
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,40 @@ SELECT * FROM cypher('cypher_set_1', $$
CREATE (x) SET x.n0 = (true OR false), x.n1 = (false AND false), x.n2 = (false = false) RETURN x
$$) AS (p agtype);

--
-- Issue 1634: Setting all properties with map object causes error
--
SELECT * FROM create_graph('issue_1634');

-- this did not work and was fixed
SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map
MERGE (v:PERSION {id: '1'})
SET v=map
RETURN v,map $$) as (v agtype, map agtype);

-- these 2 did work and are added as extra tests
SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map
MERGE (v:PERSION {id: '1'})
SET v.first=map.first, v.last=map.last
RETURN v,map $$) as (v agtype, map agtype);

SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
SELECT * FROM cypher('issue_1634', $$ MERGE (v:PERSION {id: '1'})
SET v={first: 'jon', last: 'snow'}
RETURN v $$) as (v agtype);

SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);

--
-- Clean up
--
DROP TABLE tbl;
DROP FUNCTION set_test;
SELECT drop_graph('cypher_set', true);
SELECT drop_graph('cypher_set_1', true);
SELECT drop_graph('issue_1634', true);

--

-- End
--
27 changes: 23 additions & 4 deletions src/backend/utils/adt/agtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -5583,25 +5583,44 @@ Datum age_properties(PG_FUNCTION_ARGS)

/* check for null */
if (PG_ARGISNULL(0))
{
PG_RETURN_NULL();
}

agt_arg = AG_GET_ARG_AGTYPE_P(0);
/* check for a scalar object */
if (!AGT_ROOT_IS_SCALAR(agt_arg))
/* check for a scalar or regular object */

if (!AGT_ROOT_IS_SCALAR(agt_arg) && !AGT_ROOT_IS_OBJECT(agt_arg))
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("properties() argument must resolve to a scalar value")));
errmsg("properties() argument must resolve to an object")));
}

/*
* If it isn't an array (wrapped scalar) and is an object, just return it.
* This is necessary for some cases where an object may be passed in. For
* example, SET v={blah}.
*/
if (!AGT_ROOT_IS_ARRAY(agt_arg) && AGT_ROOT_IS_OBJECT(agt_arg))
{
PG_RETURN_POINTER(agt_arg);
}

/* get the object out of the array */
agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);

/* is it an agtype null? */
if (agtv_object->type == AGTV_NULL)
PG_RETURN_NULL();
{
PG_RETURN_NULL();
}

/* check for proper agtype */
if (agtv_object->type != AGTV_VERTEX && agtv_object->type != AGTV_EDGE)
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("properties() argument must be a vertex, an edge or null")));
}

agtv_result = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "properties");

Expand Down
Loading