quine icon indicating copy to clipboard operation
quine copied to clipboard

UNWIND regression in 1.2 release

Open jiminoc opened this issue 3 years ago • 3 comments

When trying to test the 1.2 JAR I was getting failures in previously working standing queries with UNWIND where I'm working with an expected map. When retested against the 1.1 open source JAR the queries were successfully accepted and working.

ERROR MATCH (n) WHERE id(n) = $sqMatch.data.id WITH n.tags AS tags, n UNWIND keys(tags) AS key MATCH (m) WHERE id(m) = idFrom(n.cid, 'tag', key, n.tags[key]) CREATE (n)-[:tag]->(m) SET m.key = key, m.value = n.tags[key], m:tag NOT Registered OK for tagquery on http://10.10.10.10:8080: ["Type mismatch: expected Map, Node or Relationship but was Boolean, Float, Integer, Number, Point, String, Duration, Date, Time, LocalTime, LocalDateTime, DateTime, List<Boolean>, List<Float>, List<Integer>, List<Number>, List<Point>, List<String>, List<Duration>, List<Date>, List<Time>, List<LocalTime>, List<LocalDateTime> or List<DateTime>"]

Queries standing_match_tags = """MATCH (n) WHERE exists(n.tags) RETURN id(n)""" standing_action_tags = ( """MATCH (n) WHERE id(n) = $sqMatch.data.id """ """WITH n.tags AS tags, n """ """UNWIND keys(tags) AS key """ """MATCH (m) WHERE id(m) = idFrom(n.foobar, 'tag', key, n.tags[key]) """ """CREATE (n)-[:tag]->(m) """ """SET m.key = key, m.value = n.tags[key], m:tag""" )

jiminoc avatar May 12 '22 18:05 jiminoc

Reproduction using only ad-hoc queries:

Query 1:

MATCH (n) WHERE id(n) = idFrom(0) SET n = {
  tags: {
    foo: "bar",
    fizz: "buzz"
  }
}

Query 2:

MATCH (n) WHERE id(n) = idFrom(0)
UNWIND keys(n.tags) AS key RETURN key

On 1.1.0 this returns 2 rows for "key": "foo" and "fizz". On 1.2.0, it produces a type mismatch error like the one provided in the original ticket.

This seems tied to using a property specifically. Notably, Query 2 fails to compile in isolation (ie on an empty Quine instance) -- this implies the problem is in the cypher compiler

Additionally, both of the following work on 1.1.0 and 1.2.0:

UNWIND keys() of a map literal: UNWIND keys({foo: "bar", fizz: "buzz"}) AS key RETURN key UNWIND keys() of a node variable: MATCH (n) WHERE id(n) = idFrom(0) UNWIND keys(n) AS key RETURN key

emanb29 avatar May 12 '22 18:05 emanb29

As a temporary workaround, this also works on 1.2.0: instead of passing n.tags to keys(), pass properties(n)["tags"]

MATCH (n) WHERE id(n) = $sqMatch.data.id
UNWIND keys(properties(n)["tags"]) AS key
MATCH (m) WHERE id(m) = idFrom(n.cid, 'tag', key, n.tags[key])
CREATE (n)-[:tag]->(m)
SET m.key = key, m.value = n.tags[key], m:tag

emanb29 avatar May 12 '22 19:05 emanb29

The root cause seems to be upstream of Quine, in openCypher: Other cypher interpreters using openCypher have the same problem:

image

We may be able to patch around this issue in our compilation pipeline with a bit more custom logic during function resolution; looking into that possibility now.

emanb29 avatar May 12 '22 19:05 emanb29

A more thorough workaround has been introduced in https://github.com/thatdot/quine/commit/edecbcccd55206c9f028f1d68dc784e6ac38baff and is scheduled to be included in the next release. A new set of casting cypher functions may be used to hint to the compiler what the expected type of a value is: Here's an example of usage https://github.com/thatdot/quine/blob/edecbcccd55206c9f028f1d68dc784e6ac38baff/quine-cypher/src/test/scala/com/thatdot/quine/compiler/cypher/CypherComplete.scala#L741

Closing this for now, as while we'd like to implement a more thorough solution to this issue, we believe this workaround will be an effective mitigation in the near term

emanb29 avatar Feb 21 '23 22:02 emanb29