Skip to content

Commit 1b421ac

Browse files
committed
Fix Issue # 1159: Server terminates for SET plus-equal
- The previous implementation of alter_properties() in agtype.c while copying the original properties ignored non-scalar value cases, this PR fixes that
1 parent b4574f5 commit 1b421ac

3 files changed

Lines changed: 90 additions & 6 deletions

File tree

regress/expected/cypher_set.out

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,11 @@ SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Robert {name:'Robert', role:'m
787787
---
788788
(0 rows)
789789

790+
SELECT * FROM cypher('cypher_set_1',$$CREATE (a: VertexA {map: {a: 1, b: {c: 2, d: [-100, 22, "string"]}, c: [{d: -100, e: [{f: [1, 2, 3]}]}]}, list: [1, "string", [{a: [0]}, [[1, 2]]]], bool: true, num: -1.9::numeric, str: "string"})$$) as (a agtype);
791+
a
792+
---
793+
(0 rows)
794+
790795
-- test copying properties between entities
791796
SELECT * FROM cypher('cypher_set_1', $$
792797
MATCH (at {name: 'Andy'}), (pn {name: 'Peter'})
@@ -869,6 +874,47 @@ $$) AS (p agtype);
869874
{"id": 2251799813685249, "label": "Robert", "properties": {"age": 47, "city": "London", "name": "Rob"}}::vertex
870875
(1 row)
871876

877+
-- test plus-equal with original properties having non-scalar values
878+
SELECT * FROM cypher('cypher_set_1', $$
879+
MATCH (p {map: {}})
880+
SET p += {json: {a: -1, b: ['a', -1, true], c: {d: 'string'}}}
881+
RETURN p
882+
$$) AS (p agtype);
883+
p
884+
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
885+
{"id": 2533274790395905, "label": "VertexA", "properties": {"map": {"a": 1, "b": {"c": 2, "d": [-100, 22, "string"]}, "c": [{"d": -100, "e": [{"f": [1, 2, 3]}]}]}, "num": -1.9::numeric, "str": "string", "bool": true, "json": {"a": -1, "b": ["a", -1, true], "c": {"d": "string"}}, "list": [1, "string", [{"a": [0]}, [[1, 2]]]]}}::vertex
886+
(1 row)
887+
888+
SELECT * FROM cypher('cypher_set_1', $$
889+
MATCH (p {map: {}})
890+
SET p += {list_upd: [1, 2, 3, 4, 5]}
891+
RETURN p
892+
$$) AS (p agtype);
893+
p
894+
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
895+
{"id": 2533274790395905, "label": "VertexA", "properties": {"map": {"a": 1, "b": {"c": 2, "d": [-100, 22, "string"]}, "c": [{"d": -100, "e": [{"f": [1, 2, 3]}]}]}, "num": -1.9::numeric, "str": "string", "bool": true, "json": {"a": -1, "b": ["a", -1, true], "c": {"d": "string"}}, "list": [1, "string", [{"a": [0]}, [[1, 2]]]], "list_upd": [1, 2, 3, 4, 5]}}::vertex
896+
(1 row)
897+
898+
SELECT * FROM cypher('cypher_set_1', $$
899+
MATCH (p: VertexA)
900+
SET p += {int: 0}
901+
RETURN p
902+
$$) AS (p agtype);
903+
p
904+
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
905+
{"id": 2533274790395905, "label": "VertexA", "properties": {"int": 0, "map": {"a": 1, "b": {"c": 2, "d": [-100, 22, "string"]}, "c": [{"d": -100, "e": [{"f": [1, 2, 3]}]}]}, "num": -1.9::numeric, "str": "string", "bool": true, "json": {"a": -1, "b": ["a", -1, true], "c": {"d": "string"}}, "list": [1, "string", [{"a": [0]}, [[1, 2]]]], "list_upd": [1, 2, 3, 4, 5]}}::vertex
906+
(1 row)
907+
908+
SELECT * FROM cypher('cypher_set_1', $$
909+
MATCH (p {map: {}})
910+
SET p += {}
911+
RETURN p
912+
$$) AS (p agtype);
913+
p
914+
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
915+
{"id": 2533274790395905, "label": "VertexA", "properties": {"int": 0, "map": {"a": 1, "b": {"c": 2, "d": [-100, 22, "string"]}, "c": [{"d": -100, "e": [{"f": [1, 2, 3]}]}]}, "num": -1.9::numeric, "str": "string", "bool": true, "json": {"a": -1, "b": ["a", -1, true], "c": {"d": "string"}}, "list": [1, "string", [{"a": [0]}, [[1, 2]]]], "list_upd": [1, 2, 3, 4, 5]}}::vertex
916+
(1 row)
917+
872918
--
873919
-- Check passing mismatched types with SET
874920
-- Issue 899
@@ -912,7 +958,7 @@ NOTICE: graph "cypher_set" has been dropped
912958
(1 row)
913959

914960
SELECT drop_graph('cypher_set_1', true);
915-
NOTICE: drop cascades to 8 other objects
961+
NOTICE: drop cascades to 9 other objects
916962
DETAIL: drop cascades to table cypher_set_1._ag_label_vertex
917963
drop cascades to table cypher_set_1._ag_label_edge
918964
drop cascades to table cypher_set_1."Andy"
@@ -921,6 +967,7 @@ drop cascades to table cypher_set_1."Kevin"
921967
drop cascades to table cypher_set_1."Matt"
922968
drop cascades to table cypher_set_1."Juan"
923969
drop cascades to table cypher_set_1."Robert"
970+
drop cascades to table cypher_set_1."VertexA"
924971
NOTICE: graph "cypher_set_1" has been dropped
925972
drop_graph
926973
------------

regress/sql/cypher_set.sql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Kevin {name:'Kevin', age:32, h
260260
SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Matt {name:'Matt', city:'Toronto'}) $$) AS (a agtype);
261261
SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Juan {name:'Juan', role:'admin'}) $$) AS (a agtype);
262262
SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Robert {name:'Robert', role:'manager', city:'London'}) $$) AS (a agtype);
263+
SELECT * FROM cypher('cypher_set_1',$$CREATE (a: VertexA {map: {a: 1, b: {c: 2, d: [-100, 22, "string"]}, c: [{d: -100, e: [{f: [1, 2, 3]}]}]}, list: [1, "string", [{a: [0]}, [[1, 2]]]], bool: true, num: -1.9::numeric, str: "string"})$$) as (a agtype);
263264

264265
-- test copying properties between entities
265266
SELECT * FROM cypher('cypher_set_1', $$
@@ -316,6 +317,31 @@ SELECT * FROM cypher('cypher_set_1', $$
316317
RETURN p
317318
$$) AS (p agtype);
318319

320+
-- test plus-equal with original properties having non-scalar values
321+
SELECT * FROM cypher('cypher_set_1', $$
322+
MATCH (p {map: {}})
323+
SET p += {json: {a: -1, b: ['a', -1, true], c: {d: 'string'}}}
324+
RETURN p
325+
$$) AS (p agtype);
326+
327+
SELECT * FROM cypher('cypher_set_1', $$
328+
MATCH (p {map: {}})
329+
SET p += {list_upd: [1, 2, 3, 4, 5]}
330+
RETURN p
331+
$$) AS (p agtype);
332+
333+
SELECT * FROM cypher('cypher_set_1', $$
334+
MATCH (p: VertexA)
335+
SET p += {int: 0}
336+
RETURN p
337+
$$) AS (p agtype);
338+
339+
SELECT * FROM cypher('cypher_set_1', $$
340+
MATCH (p {map: {}})
341+
SET p += {}
342+
RETURN p
343+
$$) AS (p agtype);
344+
319345
--
320346
-- Check passing mismatched types with SET
321347
-- Issue 899

src/backend/utils/adt/agtype.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9149,21 +9149,32 @@ agtype_value *alter_properties(agtype_value *original_properties,
91499149
// Copy original properties.
91509150
if (original_properties)
91519151
{
9152-
int i;
9152+
agtype_iterator *org_prop_it;
9153+
agtype_value *org_prop_key, *org_prop_value;
9154+
agtype* original_properties_agt;
9155+
agtype_iterator_token org_prop_tok;
91539156

91549157
if (original_properties->type != AGTV_OBJECT)
91559158
{
91569159
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
91579160
errmsg("a map is expected")));
91589161
}
91599162

9160-
for (i = 0; i < original_properties->val.object.num_pairs; i++)
9163+
org_prop_key = palloc0(sizeof(agtype_value));
9164+
org_prop_value = palloc0(sizeof(agtype_value));
9165+
original_properties_agt = agtype_value_to_agtype(original_properties);
9166+
org_prop_it = agtype_iterator_init(&original_properties_agt->root);
9167+
org_prop_tok = agtype_iterator_next(&org_prop_it, org_prop_key, true);
9168+
9169+
while (org_prop_tok != WAGT_END_OBJECT)
91619170
{
9162-
agtype_pair* pair = original_properties->val.object.pairs + i;
9171+
org_prop_tok = agtype_iterator_next(&org_prop_it, org_prop_key, true);
9172+
agtype_iterator_next(&org_prop_it, org_prop_value, true);
9173+
91639174
parsed_agtype_value = push_agtype_value(&parse_state, WAGT_KEY,
9164-
&pair->key);
9175+
org_prop_key);
91659176
parsed_agtype_value = push_agtype_value(&parse_state, WAGT_VALUE,
9166-
&pair->value);
9177+
org_prop_value);
91679178
}
91689179
}
91699180

0 commit comments

Comments
 (0)