Re: Outer join status [Was: Building null-checking expression without calling objectNode() twice?]

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Wed Aug 23 2006 - 05:44:32 EDT

  • Next message: Andrus Adamchik: "Re: thanks and good luck"

    Hey Mike,

    I am not surprised that translator code is so hard to refactor - it
    was one of the first pieces we wrote in Cayenne and some rework was
    long overdue.

    I guess I can check the details once you have a patch in place. Now I
    just wanted to make sure I understand proposed null handling. So you
    are planning to convert all "NOT SOMETHING" expressions to the form
    like this "t0.X IS NULL OR t0.X <> ?" (if the bound parameter is not
    null itself I guess). Probably the right way to handle it. Do you
    think it is worth having a separate patch just for this feature?

    Andrus

    On Aug 23, 2006, at 2:18 AM, Mike Kienenberger wrote:

    > Finished handling null inequalities -- redesigned
    > ObjectMatchTranslator sql generation. Passes all unit tests.
    >
    > Still generating the search clauses using the wrong aliases for outer
    > joins and there's some odd classCast exception under some
    > circumstances. The code is a lot cleaner, now, though. Need to
    > write some more unit tests to pick up the failures.
    >
    >
    >
    > On 8/22/06, Mike Kienenberger <mkienen..mail.com> wrote:
    >> Just as an update, I think I have all of this working, almost. I
    >> wouldn't have guessed it would involve rewriting so much of
    >> QualifierTranslator when I started.
    >>
    >> The only thing currently failing unit testing is
    >> DataContextPrefetchTst.testPrefetch9, which is generating sql with a
    >> missing column name.
    >>
    >> SELECT t0.ESTIMATED_PRICE, t0.PAINTING_DESCRIPTION,
    >> t0.PAINTING_TITLE,
    >> t0.ARTIST_ID, t0.GALLERY_ID, t0.PAINTING_ID FROM PAINTING t0 WHERE ((
    >> IS NULL) OR t0.ARTIST_ID <> ?)
    >>
    >>
    >>
    >> On 8/22/06, Mike Kienenberger <mkienen..mail.com> wrote:
    >> > I'm trying to build the ((exp is null) or (exp <> 'Y')) sql for
    >> an inequality.
    >> >
    >> > My thought was to stick the following code at the top of startNode,
    >> > essentially calling the part of Expression.traverse(Expression,
    >> > TraversalHandler) that generates the left-hand-side twice. Calling
    >> > the code twice turns out to have bad side effects, like creating
    >> > multiple joins.
    >> >
    >> > if (handleNullInequalityComparison)
    >> > {
    >> > qualBuf.append("((");
    >> >
    >> > Object child = node.getOperand(0);
    >> > if (child instanceof Expression) {
    >> > Expression childExp = (Expression) child;
    >> > childExp.traverse(node, this);
    >> > }
    >> > else {
    >> > this.objectNode(child, node);
    >> > }
    >> >
    >> > qualBuf.append(" IS NULL) OR ");
    >> > }
    >> >
    >> > So I guess what I need to do is call it once and then cache the
    >> value.
    >> > I'm trying to figure out the best way to do this as well as
    >> how to
    >> > share the cached value since I can't store it in the Expression
    >> or the
    >> > TraversalHandler instance.
    >> >
    >>
    >



    This archive was generated by hypermail 2.0.0 : Wed Aug 23 2006 - 05:44:53 EDT