Skip to content

Commit ba6f11f

Browse files
committed
Fix Issue 1634: Setting all properties with map object causes error (apache#1637)
Fixed the issue where setting the properties would not work, if it where an object passed as the properties. Added regression tests.
1 parent 118da22 commit ba6f11f

3 files changed

Lines changed: 117 additions & 5 deletions

File tree

regress/expected/cypher_set.out

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,59 @@ $$) AS (p agtype);
935935
{"id": 281474976710658, "label": "", "properties": {"n0": true, "n1": false, "n2": true}}::vertex
936936
(1 row)
937937

938+
--
939+
-- Issue 1634: Setting all properties with map object causes error
940+
--
941+
SELECT * FROM create_graph('issue_1634');
942+
NOTICE: graph "issue_1634" has been created
943+
create_graph
944+
--------------
945+
946+
(1 row)
947+
948+
-- this did not work and was fixed
949+
SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map
950+
MERGE (v:PERSION {id: '1'})
951+
SET v=map
952+
RETURN v,map $$) as (v agtype, map agtype);
953+
v | map
954+
-----------------------------------------------------------------------------------------------------+----------------------------------
955+
{"id": 844424930131969, "label": "PERSION", "properties": {"last": "snow", "first": "jon"}}::vertex | {"last": "snow", "first": "jon"}
956+
(1 row)
957+
958+
-- these 2 did work and are added as extra tests
959+
SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
960+
u
961+
---
962+
(0 rows)
963+
964+
SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map
965+
MERGE (v:PERSION {id: '1'})
966+
SET v.first=map.first, v.last=map.last
967+
RETURN v,map $$) as (v agtype, map agtype);
968+
v | map
969+
----------------------------------------------------------------------------------------------------------------+----------------------------------
970+
{"id": 844424930131970, "label": "PERSION", "properties": {"id": "1", "last": "snow", "first": "jon"}}::vertex | {"last": "snow", "first": "jon"}
971+
(1 row)
972+
973+
SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
974+
u
975+
---
976+
(0 rows)
977+
978+
SELECT * FROM cypher('issue_1634', $$ MERGE (v:PERSION {id: '1'})
979+
SET v={first: 'jon', last: 'snow'}
980+
RETURN v $$) as (v agtype);
981+
v
982+
-----------------------------------------------------------------------------------------------------
983+
{"id": 844424930131971, "label": "PERSION", "properties": {"last": "snow", "first": "jon"}}::vertex
984+
(1 row)
985+
986+
SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
987+
u
988+
---
989+
(0 rows)
990+
938991
--
939992
-- Clean up
940993
--
@@ -974,4 +1027,17 @@ NOTICE: graph "cypher_set_1" has been dropped
9741027

9751028
(1 row)
9761029

1030+
SELECT drop_graph('issue_1634', true);
1031+
NOTICE: drop cascades to 3 other objects
1032+
DETAIL: drop cascades to table issue_1634._ag_label_vertex
1033+
drop cascades to table issue_1634._ag_label_edge
1034+
drop cascades to table issue_1634."PERSION"
1035+
NOTICE: graph "issue_1634" has been dropped
1036+
drop_graph
1037+
------------
1038+
1039+
(1 row)
1040+
1041+
--
1042+
-- End
9771043
--

regress/sql/cypher_set.sql

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,13 +354,40 @@ SELECT * FROM cypher('cypher_set_1', $$
354354
CREATE (x) SET x.n0 = (true OR false), x.n1 = (false AND false), x.n2 = (false = false) RETURN x
355355
$$) AS (p agtype);
356356

357+
--
358+
-- Issue 1634: Setting all properties with map object causes error
359+
--
360+
SELECT * FROM create_graph('issue_1634');
361+
362+
-- this did not work and was fixed
363+
SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map
364+
MERGE (v:PERSION {id: '1'})
365+
SET v=map
366+
RETURN v,map $$) as (v agtype, map agtype);
367+
368+
-- these 2 did work and are added as extra tests
369+
SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
370+
SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map
371+
MERGE (v:PERSION {id: '1'})
372+
SET v.first=map.first, v.last=map.last
373+
RETURN v,map $$) as (v agtype, map agtype);
374+
375+
SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
376+
SELECT * FROM cypher('issue_1634', $$ MERGE (v:PERSION {id: '1'})
377+
SET v={first: 'jon', last: 'snow'}
378+
RETURN v $$) as (v agtype);
379+
380+
SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype);
381+
357382
--
358383
-- Clean up
359384
--
360385
DROP TABLE tbl;
361386
DROP FUNCTION set_test;
362387
SELECT drop_graph('cypher_set', true);
363388
SELECT drop_graph('cypher_set_1', true);
389+
SELECT drop_graph('issue_1634', true);
364390

365391
--
366-
392+
-- End
393+
--

src/backend/utils/adt/agtype.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5566,25 +5566,44 @@ Datum age_properties(PG_FUNCTION_ARGS)
55665566

55675567
/* check for null */
55685568
if (PG_ARGISNULL(0))
5569+
{
55695570
PG_RETURN_NULL();
5571+
}
55705572

55715573
agt_arg = AG_GET_ARG_AGTYPE_P(0);
5572-
/* check for a scalar object */
5573-
if (!AGT_ROOT_IS_SCALAR(agt_arg))
5574+
/* check for a scalar or regular object */
5575+
5576+
if (!AGT_ROOT_IS_SCALAR(agt_arg) && !AGT_ROOT_IS_OBJECT(agt_arg))
5577+
{
55745578
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5575-
errmsg("properties() argument must resolve to a scalar value")));
5579+
errmsg("properties() argument must resolve to an object")));
5580+
}
5581+
5582+
/*
5583+
* If it isn't an array (wrapped scalar) and is an object, just return it.
5584+
* This is necessary for some cases where an object may be passed in. For
5585+
* example, SET v={blah}.
5586+
*/
5587+
if (!AGT_ROOT_IS_ARRAY(agt_arg) && AGT_ROOT_IS_OBJECT(agt_arg))
5588+
{
5589+
PG_RETURN_POINTER(agt_arg);
5590+
}
55765591

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

55805595
/* is it an agtype null? */
55815596
if (agtv_object->type == AGTV_NULL)
5582-
PG_RETURN_NULL();
5597+
{
5598+
PG_RETURN_NULL();
5599+
}
55835600

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

55895608
agtv_result = GET_AGTYPE_VALUE_OBJECT_VALUE(agtv_object, "properties");
55905609

0 commit comments

Comments
 (0)