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/05 23:07:55 UTC

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

Author: aadamchik
Date: Sun Aug  5 14:07:54 2007
New Revision: 562960

URL: http://svn.apache.org/viewvc?view=rev&rev=562960
Log:
CAY-842 EJBQL Collections condition support
(IS [NOT] EMPTY)

Modified:
    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/EJBQLPathTranslator.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
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslatorTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLConditionsTest.xml

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=562960&r1=562959&r2=562960
==============================================================================
--- 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 Sun Aug  5 14:07:54 2007
@@ -84,6 +84,26 @@
         return true;
     }
 
+    public boolean visitIsEmpty(EJBQLExpression expression) {
+
+        // handle as "path is [not] null" (an alt. way would've been a correlated subquery
+        // on the target entity)...
+
+        if (expression.isNegated()) {
+            context.switchToMarker(EJBQLSelectTranslator.makeDistinctMarker(), true);
+            context.append(" DISTINCT");
+            context.switchToMainBuffer();
+        }
+
+        visitIsNull(expression, -1);
+        for (int i = 0; i < expression.getChildrenCount(); i++) {
+            expression.getChild(i).visit(this);
+            visitIsNull(expression, i);
+        }
+
+        return false;
+    }
+
     public boolean visitAll(EJBQLExpression expression) {
         context.append(" ALL");
         return true;
@@ -256,7 +276,7 @@
                 visitSubselect(expression.getChild(1));
                 return false;
             }
-            
+
             context.append(" (");
         }
         else if (finishedChildIndex == expression.getChildrenCount() - 1) {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java?view=diff&rev=562960&r1=562959&r2=562960
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLPathTranslator.java Sun Aug  5 14:07:54 2007
@@ -29,6 +29,8 @@
 import org.apache.cayenne.ejbql.parser.EJBQLIdentificationVariable;
 import org.apache.cayenne.ejbql.parser.EJBQLIdentifier;
 import org.apache.cayenne.ejbql.parser.EJBQLInnerJoin;
+import org.apache.cayenne.ejbql.parser.EJBQLJoin;
+import org.apache.cayenne.ejbql.parser.EJBQLOuterJoin;
 import org.apache.cayenne.ejbql.parser.EJBQLPath;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
@@ -36,6 +38,7 @@
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.map.Relationship;
 import org.apache.cayenne.reflect.ClassDescriptor;
 
 /**
@@ -97,7 +100,7 @@
         // TODO: andrus 6/11/2007 - if the path ends with relationship, the last join will
         // get lost...
         if (lastPathComponent != null) {
-            resolveJoin();
+            resolveJoin(true);
         }
 
         this.lastPathComponent = expression.getText();
@@ -112,7 +115,7 @@
         return joinAppender;
     }
 
-    private void resolveJoin() {
+    private void resolveJoin(boolean inner) {
 
         String newPath = idPath + '.' + lastPathComponent;
         String oldPath = context.registerReusableJoin(idPath, lastPathComponent, newPath);
@@ -139,18 +142,34 @@
             EJBQLIdentifier joinId = new EJBQLIdentifier(-1);
             joinId.setText(fullPath);
 
-            EJBQLInnerJoin join = new EJBQLInnerJoin(-1);
-            join.jjtAddChild(path, 0);
-            join.jjtAddChild(joinId, 1);
+            context.switchToMarker(joinMarker, false);
 
-            context.switchToMarker(joinMarker);
+            if (inner) {
+                EJBQLJoin join = new EJBQLInnerJoin(-1);
+                join.jjtAddChild(path, 0);
+                join.jjtAddChild(joinId, 1);
+                getJoinAppender().visitInnerJoin(join);
+                
+                this.lastAlias = context.getTableAlias(fullPath, currentEntity
+                        .getDbEntityName());
+            }
+            else {
+                EJBQLJoin join = new EJBQLOuterJoin(-1);
+                join.jjtAddChild(path, 0);
+                join.jjtAddChild(joinId, 1);
+                getJoinAppender().visitOuterJoin(join);
+                
+                Relationship lastRelationship = currentEntity.getRelationship(lastPathComponent);
+                ObjEntity targetEntity = (ObjEntity) lastRelationship.getTargetEntity();
+                
+                this.lastAlias = context.getTableAlias(fullPath, targetEntity
+                        .getDbEntityName());
+            }
 
-            getJoinAppender().visitInnerJoin(join);
             context.switchToMainBuffer();
 
             this.idPath = newPath;
-            this.lastAlias = context.getTableAlias(fullPath, currentEntity
-                    .getDbEntityName());
+
         }
     }
 
@@ -200,9 +219,35 @@
 
     private void processTerminatingRelationship(ObjRelationship relationship) {
 
-        // check whether we need a join
         if (relationship.isSourceIndependentFromTargetChange()) {
-            // TODO: andrus, 6/13/2007 - implement
+
+            // use an outer join for to-many matches
+            resolveJoin(false);
+
+            // TODO: andrus, 6/21/2007 - flattened support
+            DbRelationship dbRelationship = (DbRelationship) relationship
+                    .getDbRelationships()
+                    .get(0);
+            DbEntity table = (DbEntity) dbRelationship.getTargetEntity();
+
+            String alias = this.lastAlias != null ? lastAlias : context.getTableAlias(
+                    idPath,
+                    table.getFullyQualifiedName());
+
+            List joins = dbRelationship.getJoins();
+
+            if (joins.size() == 1) {
+                DbJoin join = (DbJoin) joins.get(0);
+                context
+                        .append(' ')
+                        .append(alias)
+                        .append('.')
+                        .append(join.getTargetName());
+            }
+            else {
+                throw new EJBQLException(
+                        "Multi-column to-many matches are not yet supported.");
+            }
         }
         else {
             // match FK against the target object

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=562960&r1=562959&r2=562960
==============================================================================
--- 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 Sun Aug  5 14:07:54 2007
@@ -31,6 +31,10 @@
 
     private EJBQLTranslationContext context;
 
+    static String makeDistinctMarker() {
+        return "DISTINCT_MARKER";
+    }
+
     EJBQLSelectTranslator(EJBQLTranslationContext context) {
         this.context = context;
     }
@@ -40,7 +44,11 @@
     }
 
     public boolean visitDistinct(EJBQLExpression expression) {
+        // "distinct" is appended via a marker as sometimes a later match on to-many would
+        // require a DISTINCT insertion.
+        context.switchToMarker(makeDistinctMarker(), true);
         context.append(" DISTINCT");
+        context.switchToMainBuffer();
         return true;
     }
 
@@ -78,6 +86,7 @@
 
     public boolean visitSelectClause(EJBQLExpression expression) {
         context.append("SELECT");
+        context.markCurrentPosition(makeDistinctMarker());
         return true;
     }
 

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=562960&r1=562959&r2=562960
==============================================================================
--- 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 Sun Aug  5 14:07:54 2007
@@ -88,10 +88,14 @@
 
     /**
      * Switches the current buffer to a marked buffer. Note that this can be done even
-     * before the marker is inserted in the main buffer.
+     * before the marker is inserted in the main buffer. If "reset" is true, any previous
+     * contents of the marker are cleared.
      */
-    void switchToMarker(String marker) {
+    void switchToMarker(String marker, boolean reset) {
         this.currentBuffer = (StringBuffer) findOrCreateMarkedBuffer(marker);
+        if (reset) {
+            this.currentBuffer.delete(0, this.currentBuffer.length());
+        }
     }
 
     void switchToMainBuffer() {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java?view=diff&rev=562960&r1=562959&r2=562960
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLConditionsTest.java Sun Aug  5 14:07:54 2007
@@ -173,4 +173,62 @@
         assertTrue(ids.contains(new Integer(33007)));
     }
 
+    public void testCollectionEmpty() throws Exception {
+        createTestData("prepareCollection");
+
+        String ejbql = "SELECT a FROM Artist a WHERE a.paintingArray IS EMPTY";
+
+        EJBQLQuery query = new EJBQLQuery(ejbql);
+        List objects = createDataContext().performQuery(query);
+        assertEquals(1, 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(33003)));
+    }
+
+    public void testCollectionNotEmpty() throws Exception {
+        createTestData("prepareCollection");
+
+        String ejbql = "SELECT a FROM Artist a WHERE a.paintingArray IS NOT EMPTY";
+
+        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(33002)));
+    }
+
+    public void testCollectionNotEmptyExplicitDistinct() throws Exception {
+        createTestData("prepareCollection");
+
+        String ejbql = "SELECT DISTINCT a FROM Artist a WHERE a.paintingArray IS NOT EMPTY";
+
+        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(33002)));
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslatorTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslatorTest.java?view=diff&rev=562960&r1=562959&r2=562960
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslatorTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslatorTest.java Sun Aug  5 14:07:54 2007
@@ -49,13 +49,13 @@
         String sql = query.getDefaultTemplate();
 
         // column order is unpredictable, just need to ensure that they are all there
-        assertTrue(sql, sql.startsWith("SELECT "));
+        assertTrue(sql, sql.startsWith("SELECT"));
         assertTrue(sql, sql.indexOf("t0.ARTIST_ID") > 0);
         assertTrue(sql, sql.indexOf("t0.ARTIST_NAME") > 0);
         assertTrue(sql, sql.indexOf("t0.DATE_OF_BIRTH") > 0);
-        assertTrue(sql, sql.endsWith(" FROM ARTIST t0${marker0}"));
+        assertTrue(sql, sql.endsWith(" FROM ARTIST t0${marker1}"));
 
-        StringBuffer fromMarker = (StringBuffer) query.getParameters().get("marker0");
+        StringBuffer fromMarker = (StringBuffer) query.getParameters().get("marker1");
         assertNotNull(fromMarker);
         assertEquals("", fromMarker.toString());
     }
@@ -66,7 +66,7 @@
                 + "WHERE b.paintingTitle = 'P1' AND c.paintingTitle = 'P2'");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
+        assertTrue(sql, sql.startsWith("SELECT"));
 
         StringBuffer fromMarker = (StringBuffer) query.getParameters().get("marker0");
         assertNotNull(fromMarker);
@@ -83,10 +83,10 @@
                 + "FROM Artist a JOIN a.paintingArray b");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
+        assertTrue(sql, sql.startsWith("SELECT"));
 
         // check that overlapping implicit and explicit joins did not result in duplicates
-        StringBuffer fromMarker = (StringBuffer) query.getParameters().get("marker0");
+        StringBuffer fromMarker = (StringBuffer) query.getParameters().get("marker1");
         assertNotNull(fromMarker);
         assertTrue(fromMarker.toString(), fromMarker.indexOf("INNER JOIN GALLERY") >= 0);
         assertTrue(fromMarker.toString(), fromMarker.indexOf("INNER JOIN PAINTING") >= 0);
@@ -101,21 +101,21 @@
         SQLTemplate query = translateSelect("select distinct a from Artist a");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT DISTINCT "));
+        assertTrue(sql, sql.startsWith("SELECT${marker0} "));
     }
 
     public void testSelectFromWhereEqual() {
         SQLTemplate query = translateSelect("select a from Artist a where a.artistName = 'Dali'");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
+        assertTrue(sql, sql.startsWith("SELECT"));
 
-        StringBuffer fromMarker = (StringBuffer) query.getParameters().get("marker0");
+        StringBuffer fromMarker = (StringBuffer) query.getParameters().get("marker1");
         assertNotNull(fromMarker);
         String from = fromMarker.toString();
         assertEquals("", from);
 
-        assertTrue(sql, sql.endsWith(" FROM ARTIST t0${marker0} WHERE t0.ARTIST_NAME ="
+        assertTrue(sql, sql.endsWith(" FROM ARTIST t0${marker1} WHERE t0.ARTIST_NAME ="
                 + " #bind('Dali' 'VARCHAR')"));
     }
 
@@ -129,12 +129,12 @@
                 + "or a.artistName = 'Dali'");
         String sql1 = query1.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
-        assertTrue(sql, sql.indexOf(" FROM ARTIST t0${marker0} WHERE ") > 0);
+        assertTrue(sql, sql.startsWith("SELECT"));
+        assertTrue(sql, sql.indexOf(" FROM ARTIST t0${marker1} WHERE ") > 0);
         assertEquals(1, countDelimiters(sql, " OR ", sql.indexOf("WHERE ")));
 
-        assertTrue(sql1, sql1.startsWith("SELECT "));
-        assertTrue(sql1, sql.indexOf(" FROM ARTIST t0${marker0} WHERE ") > 0);
+        assertTrue(sql1, sql1.startsWith("SELECT"));
+        assertTrue(sql1, sql.indexOf(" FROM ARTIST t0${marker1} WHERE ") > 0);
         assertEquals(2, countDelimiters(sql1, " OR ", sql.indexOf("WHERE ")));
     }
 
@@ -149,11 +149,11 @@
                 + "and a.artistName = 'Dali'");
         String sql1 = query1.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
+        assertTrue(sql, sql.startsWith("SELECT"));
         assertTrue(sql, sql.indexOf(" WHERE ") > 0);
         assertEquals(1, countDelimiters(sql, " AND ", sql.indexOf("WHERE ")));
 
-        assertTrue(sql1, sql1.startsWith("SELECT "));
+        assertTrue(sql1, sql1.startsWith("SELECT"));
         assertTrue(sql1, sql1.indexOf(" WHERE ") > 0);
         assertEquals(2, countDelimiters(sql1, " AND ", sql1.indexOf("WHERE ")));
     }
@@ -162,7 +162,7 @@
         SQLTemplate query = translateSelect("select a from Artist a where not (a.artistName = 'Dali')");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
+        assertTrue(sql, sql.startsWith("SELECT"));
         assertTrue(sql, sql.endsWith(" WHERE NOT "
                 + "t0.ARTIST_NAME = #bind('Dali' 'VARCHAR')"));
     }
@@ -171,41 +171,37 @@
         SQLTemplate query = translateSelect("select p from Painting p where p.estimatedPrice > 1.0");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
-        assertTrue(sql, sql.endsWith(" WHERE t0.ESTIMATED_PRICE > #bind($id1 'DECIMAL')"));
+        assertTrue(sql, sql.startsWith("SELECT"));
+        assertTrue(sql, sql.endsWith(" WHERE t0.ESTIMATED_PRICE > #bind($id2 'DECIMAL')"));
     }
 
     public void testSelectFromWhereGreaterOrEqual() {
         SQLTemplate query = translateSelect("select p from Painting p where p.estimatedPrice >= 2");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
         assertTrue(sql, sql
-                .endsWith(" WHERE t0.ESTIMATED_PRICE >= #bind($id1 'INTEGER')"));
+                .endsWith(" WHERE t0.ESTIMATED_PRICE >= #bind($id2 'INTEGER')"));
     }
 
     public void testSelectFromWhereLess() {
         SQLTemplate query = translateSelect("select p from Painting p where p.estimatedPrice < 1.0");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
-        assertTrue(sql, sql.endsWith(" WHERE t0.ESTIMATED_PRICE < #bind($id1 'DECIMAL')"));
+        assertTrue(sql, sql.endsWith(" WHERE t0.ESTIMATED_PRICE < #bind($id2 'DECIMAL')"));
     }
 
     public void testSelectFromWhereLessOrEqual() {
         SQLTemplate query = translateSelect("select p from Painting p where p.estimatedPrice <= 1.0");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
         assertTrue(sql, sql
-                .endsWith(" WHERE t0.ESTIMATED_PRICE <= #bind($id1 'DECIMAL')"));
+                .endsWith(" WHERE t0.ESTIMATED_PRICE <= #bind($id2 'DECIMAL')"));
     }
 
     public void testSelectFromWhereNotEqual() {
         SQLTemplate query = translateSelect("select a from Artist a where a.artistName <> 'Dali'");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
         assertTrue(sql, sql.endsWith(" WHERE t0.ARTIST_NAME <> #bind('Dali' 'VARCHAR')"));
     }
 
@@ -213,25 +209,22 @@
         SQLTemplate query = translateSelect("select p from Painting p where p.estimatedPrice between 3 and 5");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
         assertTrue(sql, sql.endsWith(" WHERE t0.ESTIMATED_PRICE "
-                + "BETWEEN #bind($id1 'INTEGER') AND #bind($id2 'INTEGER')"));
+                + "BETWEEN #bind($id2 'INTEGER') AND #bind($id3 'INTEGER')"));
     }
 
     public void testSelectFromWhereNotBetween() {
         SQLTemplate query = translateSelect("select p from Painting p where p.estimatedPrice not between 3 and 5");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
         assertTrue(sql, sql.endsWith(" WHERE t0.ESTIMATED_PRICE "
-                + "NOT BETWEEN #bind($id1 'INTEGER') AND #bind($id2 'INTEGER')"));
+                + "NOT BETWEEN #bind($id2 'INTEGER') AND #bind($id3 'INTEGER')"));
     }
 
     public void testSelectFromWhereLike() {
         SQLTemplate query = translateSelect("select p from Painting p where p.paintingTitle like 'Stuff'");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
         assertTrue(sql, sql.endsWith(" WHERE t0.PAINTING_TITLE "
                 + "LIKE #bind('Stuff' 'VARCHAR')"));
     }
@@ -240,7 +233,6 @@
         SQLTemplate query = translateSelect("select p from Painting p where p.paintingTitle NOT like 'Stuff'");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "));
         assertTrue(sql, sql.endsWith(" WHERE t0.PAINTING_TITLE "
                 + "NOT LIKE #bind('Stuff' 'VARCHAR')"));
     }
@@ -253,17 +245,15 @@
                 "select a from Artist a where a.artistName = ?1 or a.artistName = ?2",
                 params);
         String sql = query.getDefaultTemplate();
-
-        assertTrue(sql, sql.startsWith("SELECT "));
         assertTrue(sql, sql
-                .endsWith("t0.ARTIST_NAME = #bind($id1) OR t0.ARTIST_NAME = #bind($id2)"));
+                .endsWith("t0.ARTIST_NAME = #bind($id2) OR t0.ARTIST_NAME = #bind($id3)"));
     }
 
     public void testMax() {
         SQLTemplate query = translateSelect("select max(p.estimatedPrice) from Painting p");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "
+        assertTrue(sql, sql.startsWith("SELECT${marker0} "
                 + "#result('MAX(t0.ESTIMATED_PRICE)' 'java.math.BigDecimal' 'sc0') "
                 + "FROM PAINTING t0"));
     }
@@ -275,7 +265,7 @@
         assertTrue(
                 sql,
                 sql
-                        .startsWith("SELECT "
+                        .startsWith("SELECT${marker0} "
                                 + "#result('SUM(DISTINCT t0.ESTIMATED_PRICE)' 'java.math.BigDecimal' 'sc0') "
                                 + "FROM PAINTING t0"));
     }
@@ -284,7 +274,7 @@
         SQLTemplate query = translateSelect("select p.estimatedPrice, p.toArtist.artistName from Painting p");
         String sql = query.getDefaultTemplate();
 
-        assertTrue(sql, sql.startsWith("SELECT "
+        assertTrue(sql, sql.startsWith("SELECT${marker0} "
                 + "#result('t0.ESTIMATED_PRICE' 'java.math.BigDecimal' 'sc0' 'sc0' 3), "
                 + "#result('t1.ARTIST_NAME' 'java.lang.String' 'sc1' 'sc1' 1) FROM"));
     }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLConditionsTest.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLConditionsTest.xml?view=diff&rev=562960&r1=562959&r2=562960
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLConditionsTest.xml (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/resources/dml/access.DataContextEJBQLConditionsTest.xml Sun Aug  5 14:07:54 2007
@@ -119,6 +119,43 @@
 		insert into ARTIST (ARTIST_ID, ARTIST_NAME) values (33003, 'D')
 		</value></constructor-arg>
 	</bean>
+	
+	
+	<bean id="P9" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+		<constructor-arg type="java.lang.Class">
+			<value>org.apache.art.Painting</value>
+		</constructor-arg>
+		<constructor-arg>
+			<value>
+				INSERT INTO PAINTING (PAINTING_ID, ARTIST_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+				VALUES (33009, 33001, 'X', 5000)
+			</value>
+		</constructor-arg>
+	</bean>
+	
+	<bean id="P10" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+		<constructor-arg type="java.lang.Class">
+			<value>org.apache.art.Painting</value>
+		</constructor-arg>
+		<constructor-arg>
+			<value>
+				INSERT INTO PAINTING (PAINTING_ID, ARTIST_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+				VALUES (33010, 33001, 'Y', 5000)
+			</value>
+		</constructor-arg>
+	</bean>
+	
+	<bean id="P11" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+		<constructor-arg type="java.lang.Class">
+			<value>org.apache.art.Painting</value>
+		</constructor-arg>
+		<constructor-arg>
+			<value>
+				INSERT INTO PAINTING (PAINTING_ID, ARTIST_ID, PAINTING_TITLE, ESTIMATED_PRICE)
+				VALUES (33011, 33002, 'Z', 5000)
+			</value>
+		</constructor-arg>
+	</bean>
 
 	<!-- ======================================= -->
 	<!-- Data Sets -->
@@ -145,6 +182,19 @@
 				<ref bean="A1" />
 				<ref bean="A2" />
 				<ref bean="A3" />
+			</list>
+		</constructor-arg>
+	</bean>
+	
+	<bean id="prepareCollection" class="java.util.ArrayList">
+		<constructor-arg>
+			<list>
+				<ref bean="A1" />
+				<ref bean="A2" />
+				<ref bean="A3" />
+				<ref bean="P9" />
+				<ref bean="P10" />
+				<ref bean="P11" />
 			</list>
 		</constructor-arg>
 	</bean>