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 2007/08/04 22:34:07 UTC

svn commit: r562762 - in /cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src: main/java/org/apache/cayenne/access/jdbc/ test/java/org/apache/cayenne/access/

Author: aadamchik
Date: Sat Aug  4 13:34:05 2007
New Revision: 562762

URL: http://svn.apache.org/viewvc?view=rev&rev=562762
Log:
CAY-840 EJBQL Subquery support
(EXISTS subselect)

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLSubqueryTest.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectColumnsTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java?view=diff&rev=562762&r1=562761&r2=562762
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java Sat Aug  4 13:34:05 2007
@@ -34,11 +34,9 @@
 
     private EJBQLTranslationContext context;
     private String attributeType;
-    private boolean resultColumns;
 
-    EJBQLAggregateColumnTranslator(EJBQLTranslationContext context, boolean resultColumns) {
+    EJBQLAggregateColumnTranslator(EJBQLTranslationContext context) {
         this.context = context;
-        this.resultColumns = resultColumns;
     }
 
     public boolean visitCount(EJBQLAggregateColumn expression) {
@@ -70,7 +68,7 @@
             EJBQLAggregateColumn column,
             EJBQLExpressionVisitor pathVisitor) {
 
-        if (resultColumns) {
+        if (context.isAppendingResultColumns()) {
             context.append(" #result('");
         }
         else {
@@ -83,7 +81,7 @@
         column.visit(pathVisitor);
         context.append(')');
 
-        if (resultColumns) {
+        if (context.isAppendingResultColumns()) {
             context
                     .append("' '")
                     .append(column.getJavaType(attributeType))

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java?view=diff&rev=562762&r1=562761&r2=562762
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java Sat Aug  4 13:34:05 2007
@@ -53,7 +53,7 @@
     }
 
     public boolean visitAggregate(EJBQLExpression expression) {
-        expression.visit(new EJBQLAggregateColumnTranslator(context, false));
+        expression.visit(new EJBQLAggregateColumnTranslator(context));
         return false;
     }
 
@@ -336,7 +336,7 @@
     }
     
     public boolean visitSubselect(EJBQLExpression expression) {
-        context.append('(');
+        context.append(" (");
         expression.visit(new EJBQLSelectTranslator(context));
         context.append(')');
         return false;

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java?view=diff&rev=562762&r1=562761&r2=562762
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java Sat Aug  4 13:34:05 2007
@@ -37,7 +37,7 @@
     }
 
     public boolean visitIdentifier(EJBQLExpression expression) {
-        expression.visit(new EJBQLIdentifierColumnsTranslator(context, false));
+        expression.visit(new EJBQLIdentifierColumnsTranslator(context));
         return false;
     }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java?view=diff&rev=562762&r1=562761&r2=562762
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLIdentifierColumnsTranslator.java Sat Aug  4 13:34:05 2007
@@ -48,12 +48,9 @@
 
     private EJBQLTranslationContext context;
     private Set columns;
-    private boolean resultColumns;
 
-    EJBQLIdentifierColumnsTranslator(EJBQLTranslationContext context,
-            boolean resultColumns) {
+    EJBQLIdentifierColumnsTranslator(EJBQLTranslationContext context) {
         this.context = context;
-        this.resultColumns = resultColumns;
     }
 
     public boolean visitIdentifier(EJBQLExpression expression) {
@@ -144,13 +141,13 @@
 
             context.append(columns.size() > 1 ? ", " : " ");
 
-            if (resultColumns) {
+            if (context.isAppendingResultColumns()) {
                 context.append("#result('");
             }
 
             context.append(columnName);
 
-            if (resultColumns) {
+            if (context.isAppendingResultColumns()) {
                 if (javaType == null) {
                     javaType = TypesMapping.getJavaBySqlType(column.getType());
                 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectColumnsTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectColumnsTranslator.java?view=diff&rev=562762&r1=562761&r2=562762
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectColumnsTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectColumnsTranslator.java Sat Aug  4 13:34:05 2007
@@ -49,7 +49,7 @@
     }
 
     public boolean visitAggregate(EJBQLExpression expression) {
-        expression.visit(new EJBQLAggregateColumnTranslator(context, true));
+        expression.visit(new EJBQLAggregateColumnTranslator(context));
         return false;
     }
 
@@ -71,19 +71,24 @@
                 // TODO: andrus 6/27/2007 - the last parameter is an unofficial "jdbcType"
                 // pending CAY-813 implementation, switch to #column directive
                 String columnAlias = context.nextColumnAlias();
-                context
-                        .append(" #result('")
-                        .append(alias)
-                        .append('.')
-                        .append(dbAttribute.getName())
-                        .append("' '")
-                        .append(attribute.getType())
-                        .append("' '")
-                        .append(columnAlias)
-                        .append("' '")
-                        .append(columnAlias)
-                        .append("' " + dbAttribute.getType())
-                        .append(")");
+
+                if (context.isAppendingResultColumns()) {
+                    context.append(" #result('");
+                }
+
+                context.append(alias).append('.').append(dbAttribute.getName());
+
+                if (context.isAppendingResultColumns()) {
+                    context
+                            .append("' '")
+                            .append(attribute.getType())
+                            .append("' '")
+                            .append(columnAlias)
+                            .append("' '")
+                            .append(columnAlias)
+                            .append("' " + dbAttribute.getType())
+                            .append(")");
+                }
             }
         };
 
@@ -92,7 +97,7 @@
     }
 
     public boolean visitIdentifier(EJBQLExpression expression) {
-        expression.visit(new EJBQLIdentifierColumnsTranslator(context, true));
+        expression.visit(new EJBQLIdentifierColumnsTranslator(context));
         return false;
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java?view=diff&rev=562762&r1=562761&r2=562762
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java Sat Aug  4 13:34:05 2007
@@ -46,6 +46,7 @@
 
     public boolean visitFrom(EJBQLExpression expression, int finishedChildIndex) {
         context.append(" FROM");
+        context.setAppendingResultColumns(false);
         expression.visit(new EJBQLFromTranslator(context));
         return false;
     }
@@ -55,7 +56,7 @@
         expression.visit(new EJBQLGroupByTranslator(context));
         return false;
     }
-    
+
     public boolean visitHaving(EJBQLExpression expression) {
         context.append(" HAVING");
         expression.visit(new EJBQLConditionTranslator(context));
@@ -66,6 +67,13 @@
         context.append(" ORDER BY");
         expression.visit(new EJBQLOrderByTranslator(context));
         return false;
+    }
+
+    public boolean visitSelect(EJBQLExpression expression) {
+        // this ensures that result columns are appeneded only in top-level select, but
+        // not subselect (as 'visitSelect' is not called on subselect)
+        context.setAppendingResultColumns(true);
+        return true;
     }
 
     public boolean visitSelectClause(EJBQLExpression expression) {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java?view=diff&rev=562762&r1=562761&r2=562762
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLTranslationContext.java Sat Aug  4 13:34:05 2007
@@ -44,6 +44,10 @@
     private Map parameters;
     private int columnAliasPosition;
 
+    // a flag indicating whether column expressions should be treated as result columns or
+    // not.
+    private boolean appendingResultColumns;
+
     EJBQLTranslationContext(EJBQLCompiledExpression compiledExpression, Map parameters) {
         this.compiledExpression = compiledExpression;
         this.mainBuffer = new StringBuffer();
@@ -283,5 +287,13 @@
         }
 
         return (String) resultSetMapping.getColumnResults().get(columnAliasPosition++);
+    }
+
+    boolean isAppendingResultColumns() {
+        return appendingResultColumns;
+    }
+
+    void setAppendingResultColumns(boolean appendingResultColumns) {
+        this.appendingResultColumns = appendingResultColumns;
     }
 }

Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLSubqueryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLSubqueryTest.java?view=auto&rev=562762
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLSubqueryTest.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLSubqueryTest.java Sat Aug  4 13:34:05 2007
@@ -0,0 +1,61 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.access;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.cayenne.DataObjectUtils;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.query.EJBQLQuery;
+import org.apache.cayenne.unit.CayenneCase;
+
+public class DataContextEJBQLSubqueryTest extends CayenneCase {
+
+    protected void setUp() throws Exception {
+        deleteTestData();
+    }
+
+    public void testExists() throws Exception {
+        createTestData("prepare");
+
+        String ejbql = "SELECT p FROM Painting p"
+                + " WHERE EXISTS ("
+                + " SELECT DISTINCT p1 FROM Painting p1"
+                + " WHERE p1.paintingTitle = p.paintingTitle"
+                + " AND p.estimatedPrice <> p1.estimatedPrice"
+                + ")";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List objects = createDataContext().performQuery(query);
+        assertEquals(2, objects.size());
+
+        Set ids = new HashSet();
+        Iterator it = objects.iterator();
+        while (it.hasNext()) {
+            Object id = DataObjectUtils.pkForObject((Persistent) it.next());
+            ids.add(id);
+        }
+
+        assertTrue(ids.contains(new Integer(33001)));
+        assertTrue(ids.contains(new Integer(33003)));
+    }
+}