openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fayw...@apache.org
Subject svn commit: r804011 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ openjpa-kernel/src/main/java/o...
Date Thu, 13 Aug 2009 20:01:38 GMT
Author: faywang
Date: Thu Aug 13 20:01:38 2009
New Revision: 804011

URL: http://svn.apache.org/viewvc?rev=804011&view=rev
Log:
OPENJPA-1185: check in embeddable in subquery support on behalf of Catalina

Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ConstPath.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/CandidatePath.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Path.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/SubQ.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Subquery.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ConstPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ConstPath.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ConstPath.java
(original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ConstPath.java
Thu Aug 13 20:01:38 2009
@@ -226,6 +226,10 @@
         return null;
     }
     
-    public void setSubqueryContext(Context conext) {
+    public void setSubqueryContext(Context conext, String correlationVar) {
+    }
+
+    public String getCorrelationVar() {
+        return null;
     }
 }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
(original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
Thu Aug 13 20:01:38 2009
@@ -117,6 +117,7 @@
             action.op = Action.VAR;
             action.data = var.getName();
             _schemaAlias = other._schemaAlias;
+            _correlationVar = other._correlationVar;
         }
         _actions.add(action);
         _cast = var.getType(); // initial type is var type
@@ -146,11 +147,12 @@
         return _schemaAlias;
     }
     
-    public void setSubqueryContext(Context context) {
+    public void setSubqueryContext(Context context, String correlationVar) {
         Action action = lastFieldAction();
         if (action == null)
             return;
         action.context = context;
+        _correlationVar = correlationVar;
     }
     
     /**
@@ -317,11 +319,8 @@
                     if (pstate.field.isElementCollection() && pstate.field.getElement().isEmbedded())
{
                         Strategy strategy = pstate.field.getStrategy();
                         if (strategy instanceof HandlerCollectionTableFieldStrategy) {
-                            if (pstate.compareEqual)
-                                return pstate.field.getJoinForeignKey().getColumns();
                             return ((HandlerCollectionTableFieldStrategy) strategy).
-                                getElementColumns(elem.getTypeMapping());
-                            
+                                getElementColumns(elem.getTypeMapping());               
            
                         }
                     }
                     if (pstate.joinedRel && elem.getTypeCode() == JavaTypes.PC)
@@ -475,7 +474,6 @@
 
     public ExpState initialize(Select sel, ExpContext ctx, int flags) {
         PathExpState pstate = new PathExpState(sel.newJoins());
-        pstate.compareEqual = (flags & Val.CMP_EQUAL) != 0 ? true : false;
         boolean key = false;
         boolean forceOuter = false;
         ClassMapping rel = _candidate;
@@ -501,7 +499,6 @@
                 if (sel.getParent() != null && action.var != null &&
                     prevaction != null && prevaction.data != null &&
                     sel.ctx().getVariable(action.var) == null) {
-                    //System.out.println("Correlated action var="+action.var);
                     isCorrelatedPath = true;
                     pstate.joins = pstate.joins.setCorrelatedVariable(action.var);
                 } else 
@@ -748,7 +745,6 @@
         public Column[] cols = null;
         public boolean joinedRel = false;
         public boolean isEmbedElementColl = false;
-        public boolean compareEqual = false;
         
         public PathExpState(Joins joins) {
             super(joins);
@@ -827,6 +823,7 @@
 
     public void selectColumns(Select sel, ExpContext ctx, ExpState state, 
         boolean pks) {
+        sel.setSchemaAlias(_schemaAlias);
         ClassMapping mapping = getClassMapping(state);
         PathExpState pstate = (PathExpState) state;
         if (mapping == null || !pstate.joinedRel ||

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java
(original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SubQ.java
Thu Aug 13 20:01:38 2009
@@ -46,7 +46,7 @@
 
     private final ClassMapping _candidate;
     private final boolean _subs;
-    private final String _subqAlias;
+    private String _subqAlias;
     private final SelectConstructor _cons = new SelectConstructor();
 
     private Class _type = null;
@@ -81,6 +81,10 @@
     public boolean getSubs() {
         return _subs;
     }
+
+    public void setSubqAlias(String subqAlias) {
+        _subqAlias = subqAlias;
+    }
     
     public String getSubqAlias() {
         return _subqAlias;

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
(original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
Thu Aug 13 20:01:38 2009
@@ -2193,6 +2193,19 @@
                 if (itr.hasNext())
                     fromSQL.append(", ");
             }
+            if (aliases.size() < 2 && sel.getParent() != null) {
+                // subquery may contain correlated joins
+                Iterator itr = sel.getJoinIterator();
+                while (itr.hasNext()) {
+                    Join join = (Join) itr.next();
+                    // append where clause
+                    if (join.isCorrelated() && join.getForeignKey() != null) {
+                        SQLBuffer where = new SQLBuffer(this);
+                        where.append("(").append(toTraditionalJoin(join)).append(")");
+                        sel.where(where.getSQL());
+                    }                
+                }
+            }
         } else {
             Iterator itr = sel.getJoinIterator();
             boolean first = true;
@@ -2200,11 +2213,16 @@
                 Join join = (Join) itr.next();
                 if (correlatedJoinCondition(join, sel))
                     continue;
-                fromSQL.append(toSQL92Join(sel, join, forUpdate,
-                    first));
+
+                if (join.isCorrelated())
+                    toCorrelatedJoin(sel, join, forUpdate, first);                    
+                else    
+                    fromSQL.append(toSQL92Join(sel, join, forUpdate,
+                        first));
                 first = false;
                 if (itr.hasNext() && join.isCorrelated()) {
-                    fromSQL.append(", ");
+                    if (fromSQL.getSQL().length() > 0)
+                        fromSQL.append(", ");
                     first = true;
                 }
             }
@@ -2212,9 +2230,11 @@
             for (Iterator itr2 = aliases.iterator(); itr2.hasNext();) {
                 String tableAlias = itr2.next().toString();
                 if (fromSQL.getSQL().indexOf(tableAlias) == -1) {
-                    if (!first)
+                    if (!first && fromSQL.getSQL().length() > 0)
                         fromSQL.append(", ");
                     fromSQL.append(tableAlias);
+                    if (forUpdate && tableForUpdateClause != null)
+                        fromSQL.append(" ").append(tableForUpdateClause);
                     first = false;
                 }
             }
@@ -2233,8 +2253,9 @@
         //the where clause in the subquery
         while (itr.hasNext()) {
             Join join1 = (Join) itr.next();
-            if (join == join1)
+            if (join == join1 && !join.isForeignKeyInversed()) {
                 continue;
+            }
             if (join.getIndex2() == join1.getIndex1() ||
                 join.getIndex2() == join1.getIndex2()) {
                 skip = true;
@@ -2356,8 +2377,8 @@
     public SQLBuffer toSQL92Join(Select sel, Join join, boolean forUpdate,
         boolean first) {
         SQLBuffer buf = new SQLBuffer(this);
-        boolean corelated = join.isCorrelated();
-        if (first && !corelated) {
+
+        if (first) {
             buf.append(join.getTable1()).append(" ").
                 append(join.getAlias1());
             if (forUpdate && tableForUpdateClause != null)
@@ -2365,33 +2386,36 @@
         }
 
         buf.append(" ");
-        if (!corelated) {
-            if (join.getType() == Join.TYPE_OUTER)
-                buf.append(outerJoinClause);
-            else if (join.getType() == Join.TYPE_INNER)
-                buf.append(innerJoinClause);
-            else // cross
-                buf.append(crossJoinClause);
-            buf.append(" ");
-        }
+        if (join.getType() == Join.TYPE_OUTER)
+            buf.append(outerJoinClause);
+        else if (join.getType() == Join.TYPE_INNER)
+            buf.append(innerJoinClause);
+        else // cross
+            buf.append(crossJoinClause);
+        buf.append(" ");
 
         buf.append(join.getTable2()).append(" ").append(join.getAlias2());
         if (forUpdate && tableForUpdateClause != null)
             buf.append(" ").append(tableForUpdateClause);
 
-        if (!corelated) {
-            if (join.getForeignKey() != null)
-                buf.append(" ON ").append(toTraditionalJoin(join));
-            else if (requiresConditionForCrossJoin &&
-                    join.getType() == Join.TYPE_CROSS)
-                buf.append(" ON (1 = 1)");
-        } else if (join.getForeignKey() != null){
+        if (join.getForeignKey() != null)
+            buf.append(" ON ").append(toTraditionalJoin(join));
+        else if (requiresConditionForCrossJoin &&
+                join.getType() == Join.TYPE_CROSS)
+            buf.append(" ON (1 = 1)");
+        
+        return buf;
+    }
+
+    private SQLBuffer toCorrelatedJoin(Select sel, Join join, boolean forUpdate,
+        boolean first) {
+        if (join.getForeignKey() != null){
             SQLBuffer where = new SQLBuffer(this);
             where.append("(").append(toTraditionalJoin(join)).append(")");
             sel.where(where.getSQL());
         }
 
-        return buf;
+        return null;
     }
 
     /**

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Join.java Thu Aug
13 20:01:38 2009
@@ -154,6 +154,7 @@
         join._target = _target;
         join._subs = _subs;
         join._joins = _joins;
+        join._correlated = _correlated;
         return join;
     }
 
@@ -180,6 +181,8 @@
             typeString = "inner";
         else
             typeString = "outer";
+        if (_correlated)
+            typeString += " &";
         return "<" + System.identityHashCode(this) + "> t"
             + _alias1 + "->t" + _alias2 + " (" + typeString + ")";
     }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Thu
Aug 13 20:01:38 2009
@@ -2845,7 +2845,8 @@
             // update the path with the relation name before getting pk alias
             this.append(name);
             this.append(var);
-            this.append(correlatedVar);
+            if (var == null)
+                this.append(correlatedVar);
             context = ctx; 
             
             if (toMany) {

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java
Thu Aug 13 20:01:38 2009
@@ -158,8 +158,12 @@
     protected Value getVariable(String id, boolean bind) {
         // check for already constructed var
         if (isSeenVariable(id))
-            return (Value) _seenVars.get(id);
+            return getVariable(id);
 
+        return createVariable(id, bind);
+    }
+
+    protected Value createVariable(String id, boolean bind) {
         // create and cache var
         Class<?> type = getDeclaredVariableType(id);
 
@@ -547,6 +551,6 @@
      * @param id
      * @return
      */
-    protected abstract Value getSeenVariable(String id);
+    protected abstract Value getVariable(String id);
 }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/CandidatePath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/CandidatePath.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/CandidatePath.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/CandidatePath.java
Thu Aug 13 20:01:38 2009
@@ -42,6 +42,7 @@
     implements Path {
 
     protected LinkedList _actions = null;
+    protected String _correlationVar = null;
 
     /**
      * Traverse into the given field of the current object, and update
@@ -204,6 +205,10 @@
         return null;
     }
     
-    public void setSubqueryContext(Context conext) {
+    public void setSubqueryContext(Context conext, String correlationVar) {
+    }
+
+    public String getCorrelationVar() {
+        return _correlationVar;
     }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Path.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Path.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Path.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Path.java Thu
Aug 13 20:01:38 2009
@@ -77,5 +77,7 @@
         
     public String getSchemaAlias();
     
-    public void setSubqueryContext(Context context);
+    public void setSubqueryContext(Context context, String correlationVar);
+
+    public String getCorrelationVar();
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/SubQ.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/SubQ.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/SubQ.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/SubQ.java Thu
Aug 13 20:01:38 2009
@@ -35,10 +35,12 @@
     private static final Localizer _loc = Localizer.forPackage(Subquery.class);
 
     private final String _alias;
+    private String _subqAlias = null;
     private Class _type = null;
 
     public SubQ(String alias) {
         _alias = alias;
+        _subqAlias = alias;
     }
 
     public Object getSelect() {
@@ -49,6 +51,14 @@
         return _alias;
     }
 
+    public void setSubqAlias(String subqAlias) {
+        _subqAlias = subqAlias;
+    }
+
+    public String getSubqAlias() {
+        return _subqAlias;
+    }
+
     public void setQueryExpressions(QueryExpressions q) {
     }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Subquery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Subquery.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Subquery.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Subquery.java
Thu Aug 13 20:01:38 2009
@@ -32,6 +32,16 @@
      */
     public String getCandidateAlias();
 
+    /*
+     * Set the candidate alias for this subquery.
+     */
+    public void setSubqAlias(String subqAlias);
+
+    /*
+     * Return the subqAlias
+     */
+    public String getSubqAlias();
+
     /**
      * Set the parsed subquery.
      */

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=804011&r1=804010&r2=804011&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
Thu Aug 13 20:01:38 2009
@@ -31,12 +31,15 @@
 import java.util.TreeSet;
 
 import org.apache.commons.collections.map.LinkedMap;
+import org.apache.openjpa.conf.Compatibility;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.BrokerFactory;
 import org.apache.openjpa.kernel.ExpressionStoreQuery;
 import org.apache.openjpa.kernel.QueryContext;
 import org.apache.openjpa.kernel.QueryOperations;
 import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.kernel.BrokerFactory;
 import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
+import org.apache.openjpa.kernel.exps.Context;
 import org.apache.openjpa.kernel.exps.Expression;
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
 import org.apache.openjpa.kernel.exps.Literal;
@@ -46,10 +49,9 @@
 import org.apache.openjpa.kernel.exps.Resolver;
 import org.apache.openjpa.kernel.exps.Subquery;
 import org.apache.openjpa.kernel.exps.Value;
-import org.apache.openjpa.kernel.exps.Context;
+import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.lib.util.Localizer.Message;
-import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.JavaTypes;
@@ -57,8 +59,7 @@
 import org.apache.openjpa.meta.ValueMetaData;
 import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.UserException;
-import org.apache.openjpa.conf.Compatibility;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
+
 import serp.util.Numbers;
 
 /**
@@ -83,6 +84,7 @@
     private final Stack<Context> contexts = new Stack<Context>();
     private LinkedMap parameterTypes;
     private int aliasCount = 0;
+    private boolean inAssignSubselectProjection = false;
 
     /**
      * Constructor.
@@ -147,7 +149,11 @@
         // we might be referencing a collection field of a subquery's parent
         if (isPath(node)) {
             Path path = getPath(node);
-            return getFieldType(path.last());
+            FieldMetaData fmd = path.last();
+            cmd = getFieldType(fmd);
+            if (cmd == null && fmd.isElementCollection())
+                cmd = fmd.getDefiningMetaData();
+            return cmd;
         }
 
         // now run again to throw the correct exception
@@ -322,6 +328,22 @@
         return result.toString();
     }
 
+    private Expression assignSubselectProjection(JPQLNode node,
+        QueryExpressions exps) {
+        inAssignSubselectProjection = true;
+        exps.projections = new Value[1];
+        exps.projectionClauses = new String[1];
+        exps.projectionAliases = new String[1];
+
+        Value val = getValue(node);
+        exps.projections[0] = val;
+        exps.projectionClauses[0] = 
+            projectionClause(node.id == JJTSCALAREXPRESSION ?
+                firstChild(node) : node);
+        inAssignSubselectProjection = false;
+        return null;
+    }
+
     private Expression assignProjections(JPQLNode parametersNode,
         QueryExpressions exps) {
         int count = parametersNode.getChildCount();
@@ -334,7 +356,7 @@
             JPQLNode parent = parametersNode.getChild(i);
             JPQLNode node = firstChild(parent);
             JPQLNode aliasNode = parent.children.length > 1 ? right(parent)
-                : null;; 
+                : null; 
             Value proj = getValue(node);
             String alias = aliasNode == null ? nextAlias()
                  : aliasNode.text;
@@ -467,6 +489,10 @@
             int selectCount = expNode.getChildCount();
             JPQLNode selectChild = firstChild(expNode);
 
+            if (selectClause.parent.id == JJTSUBSELECT) {
+                exps.distinct &= ~QueryExpressions.DISTINCT_AUTO;
+                return assignSubselectProjection(onlyChild(selectChild), exps);
+            }
             // if we are selecting just one thing and that thing is the
             // schema's alias, then do not treat it as a projection
             if (selectCount == 1 && selectChild != null &&
@@ -579,21 +605,10 @@
         return exp;
     }
 
-    private Expression bindVariableForKeyPath(Path path, String alias,
-        Expression exp) {
-        if (alias != null && ctx().findVariable(alias) == null) {
-            // subquery may have KEY range over a variable 
-            // that is not defined.
-            JPQLNode key = root().findChildByID(JJTKEY, true);
-            if (key != null && firstChild(key).text.equalsIgnoreCase(alias)) {
-                Value var = getVariable(alias, true);
-                exp = and(exp, factory.bindVariable(var, path));
-            }
-        }
-        return exp;
-    }
-
     private Expression getSubquery(String alias, Path path, Expression exp) {
+        Value var = getVariable(alias, true);
+        // this bind is for validateMapPath to resolve alias
+        Expression bindVar = factory.bindVariable(var, path);
         FieldMetaData fmd = path.last();
         ClassMetaData candidate = getFieldType(fmd);
         if (candidate == null && fmd.isElementCollection())
@@ -607,11 +622,19 @@
             subquery = factory.newSubquery(candidate, true, alias);
             subContext.setSubquery(subquery);
         }
+        else {
+            subquery.setSubqAlias(alias);
+        }
+
         Path subpath = factory.newPath(subquery);
+        subpath.setSchemaAlias(path.getCorrelationVar());
         subpath.setMetaData(candidate);
         subquery.setMetaData(candidate);
-        exp = bindVariableForKeyPath(path, alias, exp);
-        exp =  and(exp, factory.equal(path, subpath));
+        if (fmd.isElementCollection())
+            exp = and(exp, bindVar);
+        else
+            exp = and(exp, factory.equal(path, subpath));
+
         return exp;
     }
 
@@ -776,6 +799,9 @@
         if (id == null)
             return null;
 
+        if (bind && getDefinedVariable(id) == null)
+            return createVariable(id, bind);
+
         return super.getVariable(id.toLowerCase(), bind);
     }
 
@@ -1414,7 +1440,6 @@
 
     private Value getSubquery(JPQLNode node) {
         final boolean subclasses = true;
-        String alias = nextAlias();
 
         // parse the subquery
         ParsedJPQL parsed = new ParsedJPQL(node.parser.jpql, node);
@@ -1424,7 +1449,7 @@
         ClassMetaData candidate = getCandidateMetaData(node);
         Subquery subq = subContext.getSubquery();
         if (subq == null) {
-            subq = factory.newSubquery(candidate, subclasses, alias);
+            subq = factory.newSubquery(candidate, subclasses, nextAlias());
             subContext.setSubquery(subq);
         }
         subq.setMetaData(candidate);
@@ -1543,7 +1568,10 @@
             Value thiz = null;
             if (ctx().subquery == null || 
                 ctx().getSchema(name.toLowerCase()) == null) {
-                thiz = factory.getThis();
+                if (ctx().subquery != null && inAssignSubselectProjection)
+                    thiz = factory.newPath(ctx().subquery);
+                else
+                    thiz = factory.getThis();
             } else {
                 thiz = factory.newPath(ctx().subquery);
             }
@@ -1775,7 +1803,6 @@
             if (ctx().subquery != null) {
                 path = factory.newPath(ctx().subquery);
                 path.setMetaData(ctx().subquery.getMetaData());
-                factory.bindVariable(val, path);
             } else {
                 path = factory.newPath();
                 path.setMetaData(ctx().meta);
@@ -1803,7 +1830,7 @@
             path = (Path) traversePath(path, node.children[i].text, pcOnly,
                 allowNull);
             if (ctx().getParent() != null && ctx().getVariable(path.getSchemaAlias())
== null) {
-                path.setSubqueryContext(ctx());
+                path.setSubqueryContext(ctx(), name);
             }
         
             // all traversals but the first one will always be inner joins
@@ -1957,7 +1984,7 @@
         ctx().addVariable(id, var);
     }
 
-    protected Value getSeenVariable(String var) {
+    protected Value getVariable(String var) {
         Context c = ctx();
         Value v = c.getVariable(var);
         if (v != null)



Mime
View raw message