On Jul 28, 2007, at 10:00 AM, Robert Zeigler wrote:
> Regarding lines 118 - 125, if attr is null, what should type
> default to? I really don't think that will work, honestly.
> In my own extended types, I do processing based on the type
> attribute... so does the EnumType, for that matter, since it
> determines whether to convert to int or string based on the
> database type. So, seems like the long-term "right" solution is to
> make sure that DbAttribute is something correct...
Sure.
On the long run we may also try to take advantage of JDBC
'java.sql.ParameterMetaData'. When Cayenne project started years ago,
most drivers were fairly low quality, so we have too many workarounds
in the system. At some point we'll need to investigate whether there
is a significant performance penalty with modern drivers when using
PreparedStatememt parameter metadata instead of trying to guess the
types from Cayenne mapping. This should make the translator code
soooo much cleaner.
> As for debugging, I put the breakpoint in and started walking back
> up the stack.
> As predicted, it's QualifierTranslator. More specifically, the
> paramsDbType method of QueryAssemblerHelper is returning null.
> So, digging a little further, the point at which the paramsDbType
> returns null is on the unary operator check.
>
> Lines 286-291 of QueryAssemblerHelper:
>
> protected DbAttribute paramsDbType(Expression e) {
> int len = e.getOperandCount();
> // ignore unary expressions
> if (len < 2) {
> return null;
> }
>
> e.getOperandCount returns 1.
> e is an instance of ASTList, which always returns 1 for the operand
> count.
> So, you get the null DbAttribute there, which is then passed into
> QueryTranslator.appendList, from there into
> QueryTranslator.appendLiteral,
> In appendLiteral, matchingObject is going to be false for any type
> that isn't a data object
> (which suggest that /any/ extended type is going to have issues
> with inExp... something I will test tomorrow).
I am sure you are right in this assessment. I played with it a bit,
changing the algorithm above to use a parent expression for unary
expressions. This worked, except that I noticed that
ExpressionFactory doesn't initialize parent variable. So I had to fix
that as well. The patch below made against 3.0 (trunk) fixes the
problem for me. Now to be consistent I'll have to fix parent
initialization of all expressions. Let me finish the patch, and apply
it to all branches.
Andrus
Index: src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
===================================================================
--- src/main/java/org/apache/cayenne/exp/parser/ASTIn.java (revision
558748)
+++ src/main/java/org/apache/cayenne/exp/parser/ASTIn.java (working
copy)
..-44,6 +44,8 @@
super(ExpressionParserTreeConstants.JJTIN);
jjtAddChild(path, 0);
jjtAddChild(list, 1);
+ path.jjtSetParent(this);
+ list.jjtSetParent(this);
}
protected Object evaluateNode(Object o) throws Exception {
Index: src/main/java/org/apache/cayenne/access/trans/
QueryAssemblerHelper.java
===================================================================
--- src/main/java/org/apache/cayenne/access/trans/
QueryAssemblerHelper.java (revision 558748)
+++ src/main/java/org/apache/cayenne/access/trans/
QueryAssemblerHelper.java (working copy)
..-27,6 +27,7 @@
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.Persistent;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.SimpleNode;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbJoin;
..-285,8 +286,18 @@
*/
protected DbAttribute paramsDbType(Expression e) {
int len = e.getOperandCount();
- // ignore unary expressions
+
+ // for unary expressions, find parent binary - this is a
hack mainly to support
+ // ASTList
if (len < 2) {
+
+ if (e instanceof SimpleNode) {
+ Expression parent = (Expression) ((SimpleNode)
e).jjtGetParent();
+ if (parent != null) {
+ return paramsDbType(parent);
+ }
+ }
+
return null;
}
This archive was generated by hypermail 2.0.0 : Sat Jul 28 2007 - 13:06:55 EDT