[GitHub] [age] CapnSpek commented on issue #1219: MERGE does not set properties involving variables

2023-09-18 Thread via GitHub


CapnSpek commented on issue #1219:
URL: https://github.com/apache/age/issues/1219#issuecomment-1723217422

   Some observations:
   
   - The same query with `CREATE` instead of `MERGE` works just fine
   ```
   SELECT * FROM cypher('xyz', 
   $$
   MATCH (x:Label1{arr:[1,2,3,4]})
   CREATE (y:Label2{key1:2, key2:x.arr, key3:3})
   RETURN y
   $$) as (a agtype);
   ```
   
   - The same query with `MERGE` twice also works just fine
   ```
   SELECT * FROM cypher('xyz', 
   $$
   MATCH (x:Label1{arr:[1,2,3,4]})
   MERGE (y:Label2{key1:2, key2:x.arr, key3:3})
   MERGE (z:Label2{key1:2, key2:x.arr, key3:3})
   RETURN y
   $$) as (a agtype);
   ```
   
   Next, let us analyze the Query Plan Trees for `MATCH`-`MERGE`, 
`MATCH`-`CREATE`, and `MATCH`-`MERGE`-`MERGE` queries.
   
   - Query plan for `MATCH`-`MERGE`:
   ```
Custom Scan (Cypher Merge)  (cost=0.00..0.00 rows=0 width=32)
  ->  Subquery Scan on _age_default_alias_previous_cypher_clause  
(cost=0.00..86.02 rows=1 width=32)
->  Nested Loop Left Join  (cost=0.00..86.00 rows=1 width=96)
  Join Filter: (z.properties @> agtype_build_map('key1'::text, 
'2'::agtype, 'key2'::text, agtype_access_operator(VARIADIC 
ARRAY[_agtype_build_vertex(x.id, _label_name('18201'::oid, x.id), x.
   properties), '"arr"'::agtype]), 'key3'::text, '3'::agtype))
  ->  Seq Scan on "Label1" x  (cost=0.00..31.00 rows=1 width=40)
Filter: (properties @> agtype_build_map('arr'::text, 
agtype_build_list('1'::agtype, '2'::agtype, '3'::agtype, '4'::agtype)))
  ->  Seq Scan on "Label2" z  (cost=0.00..28.00 rows=1200 
width=64)
   (7 rows)
   ```
   
   - Query plan for `MATCH`-`CREATE`:
   ```
Custom Scan (Cypher Create)  (cost=0.00..0.00 rows=0 width=32)
  ->  Subquery Scan on _age_default_alias_previous_cypher_clause  
(cost=0.00..31.03 rows=1 width=32)
->  Seq Scan on "Label1" x  (cost=0.00..31.02 rows=1 width=160)
  Filter: (properties @> agtype_build_map('arr'::text, 
agtype_build_list('1'::agtype, '2'::agtype, '3'::agtype, '4'::agtype)))
   (4 rows)
   ```
   
   - Query plan for `MATCH`-`MERGE`-`MERGE`:
   ```
Custom Scan (Cypher Merge)  (cost=0.00..0.00 rows=0 width=32)
  ->  Subquery Scan on _age_default_alias_previous_cypher_clause  
(cost=0.00..49.02 rows=1 width=32)
->  Nested Loop Left Join  (cost=0.00..49.01 rows=1 width=160)
  Join Filter: (z.properties @> agtype_build_map('key1'::text, 
'2'::agtype, 'key2'::text, agtype_access_operator(VARIADIC 
ARRAY[_age_default_alias_previous_cypher_clause_1.x, '"arr"'::agtype
   ]), 'key3'::text, '3'::agtype))
  ->  Custom Scan (Cypher Merge)  (cost=0.00..0.00 rows=0 
width=64)
->  Subquery Scan on 
_age_default_alias_previous_cypher_clause_1  (cost=0.00..86.02 rows=1 width=64)
  ->  Nested Loop Left Join  (cost=0.00..86.01 
rows=1 width=96)
Join Filter: (y.properties @> 
agtype_build_map('key1'::text, '2'::agtype, 'key2'::text, 
agtype_access_operator(VARIADIC ARRAY[_agtype_build_vertex(x.id, 
_label_name('1820
   1'::oid, x.id), x.properties), '"arr"'::agtype]), 'key3'::text, '3'::agtype))
->  Seq Scan on "Label1" x  
(cost=0.00..31.00 rows=1 width=40)
  Filter: (properties @> 
agtype_build_map('arr'::text, agtype_build_list('1'::agtype, '2'::agtype, 
'3'::agtype, '4'::agtype)))
->  Seq Scan on "Label2" y  
(cost=0.00..28.00 rows=1200 width=64)
  ->  Seq Scan on "Label2" z  (cost=0.00..28.00 rows=1200 
width=64)
   (12 rows)
   ```
   
   Cannot draw a conclusion but maybe it has something to do with this part:
   `agtype_access_operator(VARIADIC ARRAY[_agtype_build_vertex(x.id, 
_label_name('18201'::oid, x.id), x.
   properties)`
   
   @ksheroz What do you think?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@age.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [age] CapnSpek commented on issue #1219: MERGE does not set properties involving variables

2023-09-18 Thread via GitHub


CapnSpek commented on issue #1219:
URL: https://github.com/apache/age/issues/1219#issuecomment-1723262498

   The same query also fails if instead of an array, we have any other datatype.
   
   If the setup is changed to
   ...
   SELECT * FROM cypher('xyz',
   $$
   CREATE (x:Label1{arr:[1,2,3,4]})
   RETURN x 
   $$) as (a agtype);
   ...
   
   And the query to:
   ```
   SELECT * FROM cypher('xyz', 
   $$
   MATCH (x:Label1{arr:[1,2,3,4]})
   MERGE (y:Label2{key1:2, key2:x.arr, key3:3})
   RETURN y
   $$) as (a agtype);
   ```
   
   The return value is still
   `{"id": 1125899906842643, "label": "Label2", "properties": {"key1": 2, 
"key3": 3}}::vertex`
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@age.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [age] CapnSpek commented on issue #1219: MERGE does not set properties involving variables

2023-09-28 Thread via GitHub


CapnSpek commented on issue #1219:
URL: https://github.com/apache/age/issues/1219#issuecomment-1739124705

   I am not very sure but can `transform_cypher_merge` function have something 
to do with it?
   
   The comments mention this, and the function is also hit during debugging.
   
   It is proving to be difficult to trace this bug because there seems to be no 
particular variable where I can check whether x is being passed or not, and no 
way to check what would be an SQL equivalent of the cypher query, specially 
when the query plan trees look fine.
   
   Can anyone suggest a way to track the source of this bug?
   
   ```
   \*
   * 2. If there is a previous clause then the query will have two subqueries.
* The first query will be for the previous clause that we recursively 
handle.
* The second query will be for the path that this MERGE clause defines. The
* two subqueries will be joined together using a LATERAL LEFT JOIN with the
* previous query on the left and the MERGE path subquery on the right. Like
* case 1 the targetList will have all the declared variables and a FuncExpr
* that represents the MERGE clause with its needed metadata information, 
that
* will be caught in the planner phase and converted into a path.
*
* This will allow us to be capable of handling the 2 cases that exist with a
* MERGE clause correctly.
*
* Case 1: the path already exists. In this case we do not need to create
* the path and MERGE will simply pass the tuple information up the execution
* tree.
*
* Case 2: the path does not exist. In this case the LEFT part of the join
* will not prevent the tuples from the previous clause from being emitted. 
We
* can catch when this happens in the execution phase and create the missing
* data, before passing up the execution tree.
*
* It should be noted that both cases can happen in the same query. If the
* MERGE clause references a variable from a previous clause, it could be 
that
* for one tuple the path exists (or there is multiple paths that exist and 
all
* paths must be emitted) and for another the path does not exist. This is
* similar to OPTIONAL MATCH, however with the added feature of creating the
* path if not there, rather than just emitting NULL.
*/
   
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@age.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org