orientdb: Incorrect MATCH result with if/eval on a datetime value
OrientDB Version: 2.2.14 and 2.2.15
Java Version: Java 8
OS: OSX and Ubuntu Linux
Expected behavior
In the repro section, all MATCH queries are equivalent and should produce identical results – returning one row with all of the created vertices in it.
Actual behavior
Except for the first query (without any if/eval), all subsequent queries incorrectly return no results.
Steps to reproduce
Database setup:
CREATE CLASS Foo EXTENDS V
CREATE CLASS Event EXTENDS V
CREATE PROPERTY Event.name String
CREATE PROPERTY Event.event_date Datetime
CREATE CLASS Foo_Start EXTENDS E
CREATE CLASS Foo_End EXTENDS E
CREATE CLASS Foo_Center EXTENDS E
CREATE VERTEX Foo
CREATE VERTEX Event SET name = 'start', event_date = '1990-01-01 00:00:00'
CREATE VERTEX Event SET name = 'end', event_date = '2017-01-01 00:00:00'
CREATE VERTEX Event SET name = 'center', event_date = '2000-01-01 00:00:00'
CREATE EDGE Foo_Start FROM (SELECT * FROM Foo) TO (SELECT * FROM Event WHERE name = 'start')
CREATE EDGE Foo_End FROM (SELECT * FROM Foo) TO (SELECT * FROM Event WHERE name = 'end')
CREATE EDGE Foo_Center FROM (SELECT * FROM Foo) TO (SELECT * FROM Event WHERE name = 'center')
All of the following queries attempt to ensure that the center Event has an event_date between the start and end.
The following query returns one result, as expected:
MATCH {
class: Foo,
as: foo
}.out('Foo_Start') {
as: start
}, {
class: Foo,
as: foo
}.out('Foo_End') {
as: end
}, {
class: Foo,
as: foo
}.out('Foo_Center') {
where: (($matched.start.event_date <= event_date) AND (event_date <= $matched.end.event_date)),
as: center
}
RETURN $matches
Let’s allow the Foo_End edge to be optional. That means that before using the as: end matched value, we must check it against null. However, the following query returns no results:
MATCH {
class: Foo,
as: foo
}.out('Foo_Start') {
as: start
}, {
class: Foo,
as: foo
}.out('Foo_End') {
optional: true,
as: end
}, {
class: Foo,
as: foo
}.out('Foo_Center') {
where: (
(event_date >= $matched.start.event_date) AND
(
if(eval("($matched.end IS NOT null)"),
if(eval("(event_date <= $matched.end.event_date)"),
true,
false
),
true
) = true
)
),
as: center
}
RETURN $matches
The following equivalent query with only a single if/eval also returns no results:
MATCH {
class: Foo,
as: foo
}.out('Foo_Start') {
as: start
}, {
class: Foo,
as: foo
}.out('Foo_End') {
optional: true,
as: end
}, {
class: Foo,
as: foo
}.out('Foo_Center') {
where: (
(event_date >= $matched.start.event_date) AND
(
if(eval("(($matched.end IS null) OR (event_date <= $matched.end.event_date))"),
true,
false
) = true
)
),
as: center
}
RETURN $matches
Even getting rid of the optionality of the Foo_End edge doesn’t fix the problem – this variant also returns no results:
MATCH {
class: Foo,
as: foo
}.out('Foo_Start') {
as: start
}, {
class: Foo,
as: foo
}.out('Foo_End') {
as: end
}, {
class: Foo,
as: foo
}.out('Foo_Center') {
where: (
(event_date >= $matched.start.event_date) AND
(
if(eval("(($matched.end IS null) OR (event_date <= $matched.end.event_date))"),
true,
false
) = true
)
),
as: center
}
RETURN $matches
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 22 (22 by maintainers)
Commits related to this issue
- Fix evaluation of MATCH expressions with eval() Resolves: #7160 — committed to orientechnologies/orientdb by luigidellaquila 7 years ago
Hi @obi1kenobi
Yes, the eval() function still has this problem, but please consider that
eval()is no longer needed in v 3.0, as you can write complex math expressions in plain SQLThanks
Luigi