Actually looking through Velocity sources, this is expression type-
dependent... E.g. ASTOrNode:
public Object value(InternalContextAdapter context )
throws MethodInvocationException
{
return new Boolean( evaluate( context ) );
}
Also I suggest that node.jjtGetChild(0).value(context) == null is
little bit faster then !node.jjtGetChild(0).evaluate(context).
This is not the case in general. See above...
But thinking about it some more, I tend to agree with you on replacing
"evaluate" that returns true/false with "value" that returns an
Object. The purpose of the #chunk directive is documented as "Often it
is desirable to exclude parts of the WHERE clause if some parameters
are null or not set.", so we should be doing NULL checking.
Also since this may be a significant change in behavior and people may
need to rewrite their SQLTemplates, my vote is that it should go to
3.1 only (see this message for a recent discussion on versions http://markmail.org/message/vo6xpzvklye2w5uy
)
Andrus
On May 21, 2010, at 2:52 PM, Рябицкий Евгений wrote:
This is not how Velocity works... It is how we use it...
Actually I have already redefined this behavior by changing
ChunkDirective code.
Change is in one line:
if (node.jjtGetNumChildren() > 1 && !
node.jjtGetChild(0).evaluate(context)) {
return false;
}
To :
if (node.jjtGetNumChildren() > 1 &&
node.jjtGetChild(0).value(context) == null) {
return false;
}
I it quite good working and is exactly what I was expecting from
this case.
Also I suggest that node.jjtGetChild(0).value(context) == null is
little bit faster then !node.jjtGetChild(0).evaluate(context).
Going to make Jira for it. If there no doubts :)
Evgeny.
-----Original Message-----
From: Andrus Adamchik [mailto:and...@objectstyle.org]
Sent: Friday, May 21, 2010 1:33 PM
To: dev@cayenne.apache.org
Subject: Re: Cayenne chain-chank problem
Ok I got it now.
That's how Velocity works. This code is not Cayenne specific. I would
suggest defining extra variables for conditions, or writing a Velocity
expression to match your expectations. E.g. "#chunk($id || $id == 0).
Not sure if you can redefine thsi behavior on the Velocity end.
I am not entirely happy with Velocity as a SQLTemplate engine myself,
but unless and until we write a substitution, we are stuck with that I
guess.
Andrus
On May 21, 2010, at 12:11 PM, Рябицкий Евгений wrote:
I took example from http://cayenne.apache.org/doc20/scripting-sqltemplate.html
and extend it so it use Boolean fields to show my problem.
For me problematic that when I am going to filter ARTISTS with id ==
1 or id == 10 it is all ok I will got query:
SELECT * from ARTIST t0 WHERE id = ? [bind: 1 ]
But if I am filtering with id == 0 (that is absolute valid column
value) I got:
SELECT * from ARTIST t0
But I was expecting:
SELECT * from ARTIST t0 WHERE id = ? [bind: 0 ]
That is my problem.... Same for Boolean values, I just want simple
filtering by only passed column values.
Evgeny.
-----Original Message-----
From: Andrus Adamchik [mailto:and...@objectstyle.org]
Sent: Friday, May 21, 2010 12:12 PM
To: dev@cayenne.apache.org
Subject: Re: Cayenne chain-chank problem
Hi Evgeny,
Where did you find this example?
I am checking #chunk directive example here:
http://cayenne.apache.org/doc20/scripting-sqltemplate.html
and everything seems correct to me. IIRC "0 == null" is how Velocity
evaluates expressions (C-style), so this has to be taken into account
when building SQLtemplates.
So I don't understand which parts you find problematic?
Cheers,
Andrus
On May 21, 2010, at 10:36 AM, Рябицкий Евгений wrote:
Hello, here is example from tutorial for 2.0:
String sql = "SELECT DISTINCT"
+ " #result('ARTIST_ID' 'int'),"
+ " #result('ARTIST_NAME' 'String'),"
+ " #result('DATE_OF_BIRTH' 'java.util.Date')"
+ " #result('IS_DEAD' 'java.util.Boolean')"
+ " FROM ARTIST t0"
+ " #chain('OR' 'WHERE') // start
chain prefixed by WHERE,
// and joined
by OR
+ " #chunk($name) ARTIST_NAME LIKE #bind($name) #end" //
ARTIST_NAMEchunk"
+ " #chunk($id) ARTIST_ID > #bind($id) #end" // ARTIST_ID
chunk"
+ " #chunk($isDead) IS_DEAD = #bind($isDead) #end" // IS_DEAD
chunk"
+ " #end"; // end of
chain
SQLTemplate select = new SQLTemplate(Artist.class, sql, true);
If I put in isDead true - everything is ok, but if I put false I got
chat this condition is skipper because #chunk is actually checking
condition of $isDead.
Same thing if I put 0 in $id it will be false.
So this example of tutorial is bad for Dead Artists or Artists with
id == 0.
Maybe it's a bug of #chunk directive and it should do only null
check??
Evgeny.