3.5.0 ent cartesian error?


(Senica) #1

Something like this happened before on a version update and it turned out to be a bug in the cartesian return, so forgive me if I'm jumping the gun here....

On v3.4.10-enterprise everything worked as expected. On 3.5.0 things are out of place in the return.

Here is the query:

MATCH (u:user {uuid: $uid})-[:allowed_to]->(c:company {uuid: $cid})
    CREATE (u)-[:owns]->(p:payment $data)<-[:allows]-(c)
    WITH *
    MATCH (a:account {uuid: $account})<-[:allows]-(c)

    WITH u, c, p, a
    UNWIND $distribution as distribution
    MATCH (pv:payment_voucher {uuid: distribution.payment_voucher})-[:bills]->(r:receivable)
    MATCH (r)-[:references]->(pr:product)-[:deposits]->(pa:account)
    CREATE (u)-[:owns]->(d:distribution)<-[:allows]-(c)
    SET d = distribution
    CREATE (p)-[:splits]->(d)
    CREATE (d)-[:pays]->(pv)
    MERGE (p)-[:deposits]->(a)
    CREATE (r)-[:references]->(p)
    CREATE (r)-[:references]->(d)

    WITH p, r, a, pr, pa, collect(d) AS distributions, sum(d.amount) as distribution_amount, pv ORDER BY pv.due_date ASC
    SET pa.balance = pa.balance + distribution_amount
    SET a.balance = a.balance + distribution_amount
    SET pv.paid = pv.paid + distribution_amount
    SET pv.unpaid = pv.amount - pv.paid
    SET pv.status = CASE
      WHEN pv.unpaid = 0 THEN 'paid'
      WHEN pv.due_date <= $now THEN 'pastdue'
      WHEN pv.unpaid < pv.amount THEN 'partial'
      ELSE 'unpaid' END

    WITH p, r, a, pr{.*, account: pa} AS product, sum(distribution_amount) AS voucher_amount, collect(pv{.*, distributions: distributions}) AS payment_vouchers

    SET r.paid = r.paid + voucher_amount
    SET r.unpaid = r.total - r.paid
    SET r.status = CASE
      WHEN r.unpaid = 0 THEN 'paid'
      // WHEN ANY (x IN payment_vouchers WHERE x.status = 'pastdue') THEN 'pastdue'
      // we don't have all the payment_vouchers to check if any are past due.
      // so, if it was past due before, then it's past due now.
      WHEN r.status = 'pastdue' THEN 'pastdue'
      WHEN r.unpaid < r.total THEN 'partial'
      ELSE 'unpaid' END

    WITH p, collect(r{.*, product: product, account: a, payment_vouchers: payment_vouchers}) AS receivables

    RETURN p{.*,
      receivables: receivables
    }

I'm using the nodejs neo4j-driver 1.7.2

The most notable thing that I've found which led me to a cartesian result error is that result[0].uuid points to an account, not a payment. Whereas in 3.4.10, result[0].uuid pointed to the uuid of a payment as expected.

I looked through the release notes to see if anything notable changed, but we aren't doing anything fancy in here that would make me think it was suppose to be a breaking change.

Any thoughts?


(Michael Hunger) #2

Don't use numeric id's to index result colums, always use names.

Can you share the profile / explain for both versions?


(Senica) #5

Sorry, modified the wrong thing :( One moment


(Senica) #6

PROFILE 3.5.0
Here is the profile. From the browser, it is return a receivable at the top level of the object instead of the payment. This seems to differ from the nodejs neo4j-driver (but I need to confirm that )


(Senica) #7

EXPLAIN 3.5.0
Here is the explain:


(Senica) #8

So I was mistaken about the browser and the driver returning different results. They are the same results. However, the issue is still the same in that it returns a receivable instead of a payment.


(Michael Hunger) #9

I think it would be best if you could share the statement and the misbehavior in a GitHub issue with a dataset that allows the Neo4j Cypher team to reproduce the issue.

If you find any way to minimizing it to the relevant bits that would be great.


(Michael Hunger) #10

Also do you have the profile from the other version? And please note which is which.


(Senica) #11

I setup the older version 3.4.10. This one works as expected.

Here is the PROFILE 3.4.10


(Senica) #12

EXPLAIN 3.4.10


(Senica) #13

I posted the issue here: https://github.com/neo4j/neo4j/issues/12113


(Michael Hunger) #14

thanks a lot. it will be handled there.