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");