Skip to content

Commit

Permalink
Fix Issue # 1159: Server terminates for SET plus-equal
Browse files Browse the repository at this point in the history
- The previous implementation of alter_properties() in
  agtype.c while copying the original properties ignored
  non-scalar value cases, this PR fixes that
  • Loading branch information
Zainab-Saad committed Aug 18, 2023
1 parent b4574f5 commit 1b421ac
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 6 deletions.
49 changes: 48 additions & 1 deletion regress/expected/cypher_set.out
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,11 @@ SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Robert {name:'Robert', role:'m
---
(0 rows)

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);
a
---
(0 rows)

-- test copying properties between entities
SELECT * FROM cypher('cypher_set_1', $$
MATCH (at {name: 'Andy'}), (pn {name: 'Peter'})
Expand Down Expand Up @@ -869,6 +874,47 @@ $$) AS (p agtype);
{"id": 2251799813685249, "label": "Robert", "properties": {"age": 47, "city": "London", "name": "Rob"}}::vertex
(1 row)

-- test plus-equal with original properties having non-scalar values
SELECT * FROM cypher('cypher_set_1', $$
MATCH (p {map: {}})
SET p += {json: {a: -1, b: ['a', -1, true], c: {d: 'string'}}}
RETURN p
$$) AS (p agtype);
p
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"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
(1 row)

SELECT * FROM cypher('cypher_set_1', $$
MATCH (p {map: {}})
SET p += {list_upd: [1, 2, 3, 4, 5]}
RETURN p
$$) AS (p agtype);
p
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"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
(1 row)

SELECT * FROM cypher('cypher_set_1', $$
MATCH (p: VertexA)
SET p += {int: 0}
RETURN p
$$) AS (p agtype);
p
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"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
(1 row)

SELECT * FROM cypher('cypher_set_1', $$
MATCH (p {map: {}})
SET p += {}
RETURN p
$$) AS (p agtype);
p
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"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
(1 row)

--
-- Check passing mismatched types with SET
-- Issue 899
Expand Down Expand Up @@ -912,7 +958,7 @@ NOTICE: graph "cypher_set" has been dropped
(1 row)

SELECT drop_graph('cypher_set_1', true);
NOTICE: drop cascades to 8 other objects
NOTICE: drop cascades to 9 other objects
DETAIL: drop cascades to table cypher_set_1._ag_label_vertex
drop cascades to table cypher_set_1._ag_label_edge
drop cascades to table cypher_set_1."Andy"
Expand All @@ -921,6 +967,7 @@ drop cascades to table cypher_set_1."Kevin"
drop cascades to table cypher_set_1."Matt"
drop cascades to table cypher_set_1."Juan"
drop cascades to table cypher_set_1."Robert"
drop cascades to table cypher_set_1."VertexA"
NOTICE: graph "cypher_set_1" has been dropped
drop_graph
------------
Expand Down
26 changes: 26 additions & 0 deletions regress/sql/cypher_set.sql
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Kevin {name:'Kevin', age:32, h
SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Matt {name:'Matt', city:'Toronto'}) $$) AS (a agtype);
SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Juan {name:'Juan', role:'admin'}) $$) AS (a agtype);
SELECT * FROM cypher('cypher_set_1', $$ CREATE (a:Robert {name:'Robert', role:'manager', city:'London'}) $$) AS (a agtype);
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);

-- test copying properties between entities
SELECT * FROM cypher('cypher_set_1', $$
Expand Down Expand Up @@ -316,6 +317,31 @@ SELECT * FROM cypher('cypher_set_1', $$
RETURN p
$$) AS (p agtype);

-- test plus-equal with original properties having non-scalar values
SELECT * FROM cypher('cypher_set_1', $$
MATCH (p {map: {}})
SET p += {json: {a: -1, b: ['a', -1, true], c: {d: 'string'}}}
RETURN p
$$) AS (p agtype);

SELECT * FROM cypher('cypher_set_1', $$
MATCH (p {map: {}})
SET p += {list_upd: [1, 2, 3, 4, 5]}
RETURN p
$$) AS (p agtype);

SELECT * FROM cypher('cypher_set_1', $$
MATCH (p: VertexA)
SET p += {int: 0}
RETURN p
$$) AS (p agtype);

SELECT * FROM cypher('cypher_set_1', $$
MATCH (p {map: {}})
SET p += {}
RETURN p
$$) AS (p agtype);

--
-- Check passing mismatched types with SET
-- Issue 899
Expand Down
21 changes: 16 additions & 5 deletions src/backend/utils/adt/agtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -9149,21 +9149,32 @@ agtype_value *alter_properties(agtype_value *original_properties,
// Copy original properties.
if (original_properties)
{
int i;
agtype_iterator *org_prop_it;
agtype_value *org_prop_key, *org_prop_value;
agtype* original_properties_agt;
agtype_iterator_token org_prop_tok;

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

for (i = 0; i < original_properties->val.object.num_pairs; i++)
org_prop_key = palloc0(sizeof(agtype_value));
org_prop_value = palloc0(sizeof(agtype_value));
original_properties_agt = agtype_value_to_agtype(original_properties);
org_prop_it = agtype_iterator_init(&original_properties_agt->root);
org_prop_tok = agtype_iterator_next(&org_prop_it, org_prop_key, true);

while (org_prop_tok != WAGT_END_OBJECT)
{
agtype_pair* pair = original_properties->val.object.pairs + i;
org_prop_tok = agtype_iterator_next(&org_prop_it, org_prop_key, true);
agtype_iterator_next(&org_prop_it, org_prop_value, true);

parsed_agtype_value = push_agtype_value(&parse_state, WAGT_KEY,
&pair->key);
org_prop_key);
parsed_agtype_value = push_agtype_value(&parse_state, WAGT_VALUE,
&pair->value);
org_prop_value);
}
}

Expand Down

0 comments on commit 1b421ac

Please sign in to comment.