Skip to content

Commit

Permalink
Fix issue 395: ERROR: container is not an agtype array (apache#1039)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrgemignani authored and muhammadshoaib committed Jul 20, 2023
1 parent b0696f9 commit ef5ef31
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 7 deletions.
75 changes: 75 additions & 0 deletions regress/expected/expr.out
Original file line number Diff line number Diff line change
Expand Up @@ -6703,9 +6703,84 @@ SELECT * FROM cypher('expr', $$MATCH (u) RETURN toString(pg_catalog.pg_typeof(u.
"agtype"
(7 rows)

-- issue: 395 aggregate function collect() incorrect container for operation
SELECT create_graph('graph_395');
NOTICE: graph "graph_395" has been created
create_graph
--------------

(1 row)

SELECT * FROM cypher('graph_395', $$ CREATE (n:Project {name: 'Project A'}),
(m:Project {name: 'Project B'}),
(a:Task {name: 'Task A', size: 10}),
(b:Task {name: 'Task B', size: 5}),
(c:Task {name: 'Task C', size: 7}),
(x:Person {name: 'John', age: 55}),
(y:Person {name: 'Bob', age: 43}),
(z:Person {name: 'Alice', age: 33}),
(n)-[:Has]->(a),
(n)-[:Has]->(b),
(m)-[:Has]->(c),
(a)-[:AssignedTo]->(x),
(b)-[:AssignedTo]->(y),
(c)-[:AssignedTo]->(y) $$) as (n agtype);
n
---
(0 rows)

SELECT * FROM cypher('graph_395', $$ MATCH (p:Project)-[:Has]->(t:Task)-[:AssignedTo]->(u:Person)
WITH p, t, collect(u) AS users
WITH p, {tn: t.name, users: users} AS task
RETURN task $$) AS (p agtype);
p
-----------------------------------------------------------------------------------------------------------------------------
{"tn": "Task A", "users": [{"id": 1407374883553281, "label": "Person", "properties": {"age": 55, "name": "John"}}::vertex]}
{"tn": "Task B", "users": [{"id": 1407374883553282, "label": "Person", "properties": {"age": 43, "name": "Bob"}}::vertex]}
{"tn": "Task C", "users": [{"id": 1407374883553282, "label": "Person", "properties": {"age": 43, "name": "Bob"}}::vertex]}
(3 rows)

SELECT * FROM cypher('graph_395', $$ MATCH (p:Project)-[:Has]->(t:Task)-[:AssignedTo]->(u:Person)
WITH p, t, collect(u) AS users
WITH p, {tn: t.name, users: users} AS task
WITH p, collect(task) AS tasks
RETURN tasks $$) AS (p agtype);
p
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[{"tn": "Task A", "users": [{"id": 1407374883553281, "label": "Person", "properties": {"age": 55, "name": "John"}}::vertex]}, {"tn": "Task B", "users": [{"id": 1407374883553282, "label": "Person", "properties": {"age": 43, "name": "Bob"}}::vertex]}]
[{"tn": "Task C", "users": [{"id": 1407374883553282, "label": "Person", "properties": {"age": 43, "name": "Bob"}}::vertex]}]
(2 rows)

SELECT * FROM cypher('graph_395', $$ MATCH (p:Project)-[:Has]->(t:Task)-[:AssignedTo]->(u:Person)
WITH p, t, collect(u) AS users
WITH p, {tn: t.name, users: users} AS task
WITH p, collect(task) AS tasks
WITH {pn: p.name, tasks:tasks} AS project
RETURN project $$) AS (p agtype);
p
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"pn": "Project A", "tasks": [{"tn": "Task A", "users": [{"id": 1407374883553281, "label": "Person", "properties": {"age": 55, "name": "John"}}::vertex]}, {"tn": "Task B", "users": [{"id": 1407374883553282, "label": "Person", "properties": {"age": 43, "name": "Bob"}}::vertex]}]}
{"pn": "Project B", "tasks": [{"tn": "Task C", "users": [{"id": 1407374883553282, "label": "Person", "properties": {"age": 43, "name": "Bob"}}::vertex]}]}
(2 rows)

--
-- Cleanup
--
SELECT * FROM drop_graph('graph_395', true);
NOTICE: drop cascades to 7 other objects
DETAIL: drop cascades to table graph_395._ag_label_vertex
drop cascades to table graph_395._ag_label_edge
drop cascades to table graph_395."Project"
drop cascades to table graph_395."Task"
drop cascades to table graph_395."Person"
drop cascades to table graph_395."Has"
drop cascades to table graph_395."AssignedTo"
NOTICE: graph "graph_395" has been dropped
drop_graph
------------

(1 row)

SELECT * FROM drop_graph('chained', true);
NOTICE: drop cascades to 3 other objects
DETAIL: drop cascades to table chained._ag_label_vertex
Expand Down
35 changes: 35 additions & 0 deletions regress/sql/expr.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2713,9 +2713,44 @@ SELECT * FROM cypher('list',$$ MATCH p=(n:xyz)-[e]->() SET n.array=[0, 1, 2, 3,
-- pg_typeof
SELECT * FROM cypher('expr', $$MATCH (u) RETURN toString(pg_catalog.pg_typeof(u.id)) $$) AS (u agtype);

-- issue: 395 aggregate function collect() incorrect container for operation
SELECT create_graph('graph_395');
SELECT * FROM cypher('graph_395', $$ CREATE (n:Project {name: 'Project A'}),
(m:Project {name: 'Project B'}),
(a:Task {name: 'Task A', size: 10}),
(b:Task {name: 'Task B', size: 5}),
(c:Task {name: 'Task C', size: 7}),
(x:Person {name: 'John', age: 55}),
(y:Person {name: 'Bob', age: 43}),
(z:Person {name: 'Alice', age: 33}),
(n)-[:Has]->(a),
(n)-[:Has]->(b),
(m)-[:Has]->(c),
(a)-[:AssignedTo]->(x),
(b)-[:AssignedTo]->(y),
(c)-[:AssignedTo]->(y) $$) as (n agtype);

SELECT * FROM cypher('graph_395', $$ MATCH (p:Project)-[:Has]->(t:Task)-[:AssignedTo]->(u:Person)
WITH p, t, collect(u) AS users
WITH p, {tn: t.name, users: users} AS task
RETURN task $$) AS (p agtype);

SELECT * FROM cypher('graph_395', $$ MATCH (p:Project)-[:Has]->(t:Task)-[:AssignedTo]->(u:Person)
WITH p, t, collect(u) AS users
WITH p, {tn: t.name, users: users} AS task
WITH p, collect(task) AS tasks
RETURN tasks $$) AS (p agtype);

SELECT * FROM cypher('graph_395', $$ MATCH (p:Project)-[:Has]->(t:Task)-[:AssignedTo]->(u:Person)
WITH p, t, collect(u) AS users
WITH p, {tn: t.name, users: users} AS task
WITH p, collect(task) AS tasks
WITH {pn: p.name, tasks:tasks} AS project
RETURN project $$) AS (p agtype);
--
-- Cleanup
--
SELECT * FROM drop_graph('graph_395', true);
SELECT * FROM drop_graph('chained', true);
SELECT * FROM drop_graph('VLE', true);
SELECT * FROM drop_graph('case_statement', true);
Expand Down
17 changes: 10 additions & 7 deletions src/backend/utils/adt/agtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -9430,6 +9430,7 @@ Datum age_collect_aggtransfn(PG_FUNCTION_ARGS)
/* create and initialize the state */
castate = palloc0(sizeof(agtype_in_state));
memset(castate, 0, sizeof(agtype_in_state));

/* start the array */
castate->res = push_agtype_value(&castate->parse_state,
WAGT_BEGIN_ARRAY, NULL);
Expand Down Expand Up @@ -9459,23 +9460,25 @@ Datum age_collect_aggtransfn(PG_FUNCTION_ARGS)
/* only add non null values */
if (nulls[0] == false)
{
agtype_value *agtv_value = NULL;

/* we need to check for agtype null and skip it, if found */
if (types[0] == AGTYPEOID)
{
agtype *agt_arg;
agtype_value *agtv_value;

/* get the agtype argument */
agt_arg = DATUM_GET_AGTYPE_P(args[0]);
agtv_value = get_ith_agtype_value_from_container(&agt_arg->root,
0);
/* add the arg if not agtype null */
if (agtv_value->type != AGTV_NULL)

/* get the scalar value */
if (AGTYPE_CONTAINER_IS_SCALAR(&agt_arg->root))
{
add_agtype(args[0], nulls[0], castate, types[0], false);
agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0);
}
}
else

/* skip the arg if agtype null */
if (agtv_value == NULL || agtv_value->type != AGTV_NULL)
{
add_agtype(args[0], nulls[0], castate, types[0], false);
}
Expand Down

0 comments on commit ef5ef31

Please sign in to comment.