Skip to content

Commit

Permalink
Fix Issue 1634: Setting all properties with map object causes error (#…
Browse files Browse the repository at this point in the history
…1637)

Fixed the issue where setting the properties would not work, if it where
an object passed as the properties.

Added regression tests.
  • Loading branch information
jrgemignani authored Mar 6, 2024
1 parent 001b005 commit 438f551
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 5 deletions.
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

0 comments on commit 438f551

Please sign in to comment.