Re: In-memory EOQualifier evaluation and to-many relations
Re: In-memory EOQualifier evaluation and to-many relations
- Subject: Re: In-memory EOQualifier evaluation and to-many relations
- From: Jean-François Veillette <email@hidden>
- Date: Fri, 27 Sep 2013 14:26:27 -0400
In fact the problem with to-many relationship traversal come from the fact that we are used to expect sql-like behavior from the memory evaluation when in fact EOF mangled the qualifier for us.
We forget that the database behaviour is obtained by __transforming first__ the qualifier. ... something that do not occur when we evaluate in memory.
Let me explain ...
Ex: Library ->> Book ->> Author
Find a library where you can find the only book that « John Doe » (the one who was born in 1970) as written.
Qualifier = (Library.books.author.name="John Doe").and(Library.books.author.birthDateYear='1970').
1- EOF will try to identify the many tables involved in the query:
-> Library t0, Book t1, Author t2, library_book t3, book_author t4
2- It will result the « join » clause:
-> t0.pk = t3.library_fk AND -- from Library to Library_book
t3.book_fk = t1.pk AND -- from library_book to book
t1.pk = t4.book_fk AND -- from book to book_author
t4.author_fk = t2.pk -- from book_author to author
3- and the where clause from the qualifier itself:
-> t2.name="John Doe" AND
t2.birthDateYear="1970"
That will work for database operation, since the sql transformation has simplified and unified the key-path traversal for us.
which is is more like: Qualifier = Library.books.author where (author.name = "John Doe" AND author.birthDateYear="1970")
By comparison, if we take the original query and evaluate it in memory, we get:
1- EOAndQualifier (Library.books.author.name="John Doe", Library.books.author.birthDateYear="1970")
-> first = Library.books.author.name="John Doe"
-> second = Library.books.author.birthDateYear="1970"
-> first = all the library that has books from author Jon Doe
-> second = all the library that has books from an author born in 1970
which return « A AND B » == >> « A + B » ... which is WRONG !!!
it will be all the libraries where there is a book written by an author named "John Doe" or an author born in 1970.
But what's wrong here, where is the bug ? ...
Look at the original qualifier, it is not explicit that it should refer to the same author, so the fact that the transformation in SQL does imply it should be considered kind of boggus, right?
I think we should rewrite the qualifier to something like:
Library.books.author.where(name="John Doe" AND birthDateYeay="1970")
That way, the SQL transformation will be implicit and identical to the memory evaluation.
Obviously it emphasis the fact that EOF __lack__ such a qualifier ... unless playing with the « inner join / outer join / ... » and all those kind of join definition have an impact on the memory evaluation (which I do not think if does).
Did I miss something in EOF? ... please point me in the right direction !
Any volunteer to write a new eof-qualifier-operator to take care of this to-many cases problem?
jfv
Le 2013-09-20 à 13:15, Fabian Peters <email@hidden> a écrit :
> Hi Samuel,
>
> Am 20.09.2013 um 16:42 schrieb Samuel Pelletier:
>
>> Hi Fabian,
>>
>> The problem with too many qualifier is the fact you traverse a too many. There is no way to answer to the question "watch do you want?", do you want the Course where there is at least one event after now of course where all events are after now?
>
> I'd expect the qualifier to match courses that have at least one event with an end date after "now", which is what the same qualifier will do in SQL. On most occasions when qualifying in memory, I guess one would approach this in a different way. Here I wanted to unit test a qualifier that otherwise only gets used when fetching from the DB.
>
> Tant pis…
>
> Fabian
>
>> You need to be more precise.
>>
>> Try add a atMin() or atMax() like Course.EVENTS.atMax(CourseEvent.END_DATE_TIME).after(new NSTimestamp()) to get Course where the last event is after now (not ended).
>>
>> Samuel
>>
>>
>>
>> Le 2013-09-19 à 12:36, Fabian Peters <email@hidden> a écrit :
>>
>>> Hi all,
>>>
>>> I just tried to write a unit test for a basic qualifying fetch spec. What I found is that the in-memory evaluation fails for key-paths with a to-many, e.g. this:
>>>
>>> EOQualifier q = Course.EVENTS.dot(CourseEvent.END_DATE_TIME.after(new NSTimestamp()));
>>>
>>> Debugging the qualifier evaluation, I see that the timestamp gets directly compared to an array of timestamps and thus the qualifier never matches.
>>>
>>> Having looked through some old code, I seem to never have used an in-memory evaluation on a to-many key-path. But somehow I assumed it should be possible. Wishful thinking?
>>>
>>> Fabian
>>> _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Webobjects-dev mailing list (email@hidden)
>>> Help/Unsubscribe/Update your Subscription:
>>>
>>> This email sent to email@hidden
>>
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden