You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2009/02/12 12:56:42 UTC
svn commit: r743696 - in
/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src:
main/java/org/apache/cayenne/access/jdbc/
main/java/org/apache/cayenne/ejbql/parser/
test/java/org/apache/cayenne/access/
Author: aadamchik
Date: Thu Feb 12 11:56:42 2009
New Revision: 743696
URL: http://svn.apache.org/viewvc?rev=743696&view=rev
Log:
CAY-1139 EJBQL condition translation - must track the type of condition
patch by Olga Tkachova - fixing NULL 'type'
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNamedInputParameter.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLIsNullTest.java
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java?rev=743696&r1=743695&r2=743696&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java Thu Feb 12 11:56:42 2009
@@ -21,12 +21,14 @@
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.Persistent;
+import org.apache.cayenne.dba.TypesMapping;
import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
import org.apache.cayenne.ejbql.EJBQLException;
import org.apache.cayenne.ejbql.EJBQLExpression;
@@ -34,6 +36,7 @@
import org.apache.cayenne.ejbql.parser.EJBQLEquals;
import org.apache.cayenne.ejbql.parser.EJBQLIdentificationVariable;
import org.apache.cayenne.ejbql.parser.EJBQLIntegerLiteral;
+import org.apache.cayenne.ejbql.parser.EJBQLNamedInputParameter;
import org.apache.cayenne.ejbql.parser.EJBQLPath;
import org.apache.cayenne.ejbql.parser.EJBQLPositionalInputParameter;
import org.apache.cayenne.ejbql.parser.EJBQLSubselect;
@@ -44,6 +47,7 @@
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbJoin;
import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.reflect.AttributeProperty;
import org.apache.cayenne.reflect.ClassDescriptor;
/**
@@ -339,7 +343,7 @@
@Override
public boolean visitNamedInputParameter(EJBQLExpression expression) {
String parameter = context.bindNamedParameter(expression.getText());
- processParameter(parameter);
+ processParameter(parameter, expression);
return true;
}
@@ -614,7 +618,7 @@
public boolean visitPositionalInputParameter(EJBQLPositionalInputParameter expression) {
String parameter = context.bindPositionalParameter(expression.getPosition());
- processParameter(parameter);
+ processParameter(parameter, expression);
return true;
}
@@ -654,7 +658,7 @@
return false;
}
- private void processParameter(String boundName) {
+ private void processParameter(String boundName, EJBQLExpression expression) {
Object object = context.getBoundParameter(boundName);
Map<?, ?> map = null;
@@ -684,6 +688,36 @@
context.append(" #bind($").append(boundName).append(")");
}
else {
+
+ String type = null;
+ EJBQLEquals parent = ((EJBQLNamedInputParameter) expression).getParent();
+
+ context.pushMarker("@processParameter", true);
+ EJBQLPathAnaliserTranslator translator = new EJBQLPathAnaliserTranslator(
+ context);
+ parent.visit(translator);
+ translator.visitPath(parent, parent.getChildrenCount());
+
+ String id = translator.idPath;
+ if (id != null) {
+
+ ClassDescriptor descriptor = context.getEntityDescriptor(id);
+ if (descriptor == null) {
+ throw new EJBQLException("Unmapped id variable: " + id);
+ }
+ String pathChunk = translator.lastPathComponent;
+ AttributeProperty property = (AttributeProperty) descriptor
+ .getProperty(pathChunk);
+ String atrType = property.getAttribute().getType();
+
+ type = TypesMapping.getSqlNameByType(TypesMapping.getSqlTypeByJava(atrType));
+
+ }
+ context.popMarker();
+
+ if (type == null) {
+ type = "VARCHAR";
+ }
// this is a hack to prevent execptions on DB's like Derby for expressions
// "X = NULL". The 'VARCHAR' parameter is totally bogus, but seems to work on
// all tested DB's... Also note what JPA spec, chapter 4.11 says: "Comparison
@@ -691,7 +725,8 @@
// TODO: andrus 6/28/2007 Ideally we should track the type of the current
// expression to provide a meaningful type.
- context.append(" #bind($").append(boundName).append(" 'VARCHAR')");
+
+ context.append(" #bind($").append(boundName).append(" '" + type + "')");
}
}
@@ -957,4 +992,43 @@
context.append(" {fn LTRIM({fn RTRIM(");
return false;
}
+
+}
+
+class EJBQLPathAnaliserTranslator extends EJBQLPathTranslator {
+
+ private boolean isPath;
+
+ public EJBQLPathAnaliserTranslator(EJBQLTranslationContext context) {
+ super(context);
+ isPath = false;
+ }
+
+ @Override
+ protected void appendMultiColumnPath(EJBQLMultiColumnOperand operand) {
+ }
+
+ @Override
+ public boolean visitPath(EJBQLExpression expression, int finishedChildIndex) {
+ if (isPath) {
+ return false;
+ }
+ else {
+
+ if (finishedChildIndex > 0) {
+
+ if (finishedChildIndex + 1 < expression.getChildrenCount()) {
+ processIntermediatePathComponent();
+ }
+ else {
+ processLastPathComponent();
+ if(idPath!=null && lastPathComponent!=null){
+ isPath = true;
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+ }
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java?rev=743696&r1=743695&r2=743696&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java Thu Feb 12 11:56:42 2009
@@ -46,7 +46,7 @@
private EJBQLTranslationContext context;
protected ObjEntity currentEntity;
- private String lastPathComponent;
+ protected String lastPathComponent;
protected String lastAlias;
protected String idPath;
protected String joinMarker;
@@ -152,7 +152,7 @@
}
}
- private void processIntermediatePathComponent() {
+ protected void processIntermediatePathComponent() {
ObjRelationship relationship = (ObjRelationship) currentEntity
.getRelationship(lastPathComponent);
if (relationship == null) {
@@ -166,7 +166,7 @@
this.currentEntity = (ObjEntity) relationship.getTargetEntity();
}
- private void processLastPathComponent() {
+ protected void processLastPathComponent() {
ObjAttribute attribute = (ObjAttribute) currentEntity
.getAttribute(lastPathComponent);
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNamedInputParameter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNamedInputParameter.java?rev=743696&r1=743695&r2=743696&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNamedInputParameter.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/EJBQLNamedInputParameter.java Thu Feb 12 11:56:42 2009
@@ -33,4 +33,8 @@
protected boolean visitNode(EJBQLExpressionVisitor visitor) {
return visitor.visitNamedInputParameter(this);
}
+
+ public EJBQLEquals getParent() {
+ return (EJBQLEquals) parent;
+ }
}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLIsNullTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLIsNullTest.java?rev=743696&r1=743695&r2=743696&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLIsNullTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLIsNullTest.java Thu Feb 12 11:56:42 2009
@@ -48,7 +48,38 @@
// assertions about the result. Just making sure the query doesn't blow up
createDataContext().performQuery(query1);
}
+
+ public void testCompareToNull2() throws Exception {
+ if (!getAccessStackAdapter().supportsEqualNullSyntax()) {
+ return;
+ }
+ deleteTestData();
+ createTestData("prepare");
+
+ String ejbql1 = "SELECT p FROM Painting p WHERE p.toArtist.artistName = :x";
+ EJBQLQuery query1 = new EJBQLQuery(ejbql1);
+ query1.setParameter("x", null);
+
+ createDataContext().performQuery(query1);
+ }
+
+ public void testCompareToNull3() throws Exception {
+ if (!getAccessStackAdapter().supportsEqualNullSyntax()) {
+ return;
+ }
+
+ deleteTestData();
+ createTestData("prepare");
+
+ String ejbql1 = "SELECT p FROM Painting p WHERE :x = p.toArtist.artistName";
+ EJBQLQuery query1 = new EJBQLQuery(ejbql1);
+ query1.setParameter("x", null);
+
+ createDataContext().performQuery(query1);
+ }
+
+
public void testIsNull() throws Exception {
deleteTestData();
createTestData("prepare");