You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2009/06/26 23:21:12 UTC

svn commit: r788874 - in /openjpa/branches/subquery: 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...

Author: fancy
Date: Fri Jun 26 21:21:10 2009
New Revision: 788874

URL: http://svn.apache.org/viewvc?rev=788874&view=rev
Log:
subquery eval from clause first

Modified:
    openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
    openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java
    openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java
    openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
    openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java
    openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Context.java
    openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java
    openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java
    openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java

Modified: openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java (original)
+++ openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java Fri Jun 26 21:21:10 2009
@@ -494,13 +494,12 @@
                     prevaction != null && prevaction.data != null &&
                     sel.ctx().getVariable(action.var) == null) {
                     System.out.println("action var="+action.var);
-                    sel.setSchemaAlias(action.var);
-                    pstate.joins = pstate.joins.
-                        setCorrelatedVariable(action.var);
-                    isCorrelatedPath = true;
+                    isCorrelatedPath = 
+                        pstate.joins.isCorrelatedVariable(action.var);
                 }
-                else
-                pstate.joins = pstate.joins.setVariable((String) action.data);
+                if (!isCorrelatedPath)
+                    pstate.joins = pstate.joins.
+                        setVariable((String) action.data);
             }
             else if (action.op == Action.SUBQUERY) {
                 pstate.joins = pstate.joins.setSubselect((String) action.data);
@@ -596,7 +595,7 @@
                 false);
         if (isCorrelatedPath) {
             // check if there are joins that belong to parent
-            pstate.joins.copyToParent();
+            pstate.joins.moveJoinsToParent();
         }
         return pstate;
     }

Modified: openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java (original)
+++ openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java Fri Jun 26 21:21:10 2009
@@ -889,11 +889,11 @@
         public void appendTo(SQLBuffer buf) {
         }
 
-        public Joins setCorrelatedVariable(String var) {
-            return this;
+        public boolean isCorrelatedVariable(String var) {
+            return false;
         }
 
-        public void copyToParent() {
+        public void moveJoinsToParent() {
         }
     }
 }

Modified: openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java (original)
+++ openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java Fri Jun 26 21:21:10 2009
@@ -74,6 +74,11 @@
      */
     public Joins setVariable(String var);
 
+    /**
+     * Set subquery context when traversing into the next join is
+     * in transition from parent context to subquery.
+     * @param context
+     */
     public void setContext(Context context);
     
     /**
@@ -82,10 +87,11 @@
     public Joins setSubselect(String alias);
 
     /**
-     * Set the variable name being traversed into with the next join.
+     * Return true if the variable name being traversed into
+     * with the next join is a correlated variable.
      */
-    public Joins setCorrelatedVariable(String var);
+    public boolean isCorrelatedVariable(String var);
 
-    public void copyToParent();
+    public void moveJoinsToParent();
 
 }

Modified: openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ openjpa/branches/subquery/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Fri Jun 26 21:21:10 2009
@@ -2551,14 +2551,11 @@
         public void setContext(Context context) {
         }
         
-        public Joins setCorrelatedVariable(String var) {
-            // TODO Auto-generated method stub
-            return null;
+        public boolean isCorrelatedVariable(String var) {
+            return false;
         }
 
-        public void copyToParent() {
-            // TODO Auto-generated method stub
-            
+        public void moveJoinsToParent() {
         }
     }
 
@@ -2609,10 +2606,13 @@
             return this;
         }
 
-        public Joins setCorrelatedVariable(String var) {
-            setVariable(var);
-            this.correlatedVar = var;
-            return this;
+        public boolean isCorrelatedVariable(String var) {
+            boolean isCorrelated = getSelect().ctx().getVariable(var) == null;
+            if (isCorrelated) {
+                setVariable(var);
+                this.correlatedVar = var;
+            }
+            return isCorrelated;
         }
 
         public void setContext(Context context) {
@@ -2676,9 +2676,7 @@
                 + String.valueOf(path);
         }
 
-        public void copyToParent() {
-            // TODO Auto-generated method stub
-            
+        public void moveJoinsToParent() {
         }
     }
 
@@ -2885,7 +2883,7 @@
             }
         }
 
-        public void copyToParent() {
+        public void moveJoinsToParent() {
             if (_joins == null)   // add this line
                 return;           // add this line
            if (_sel._parent._joins == null) 
@@ -3122,12 +3120,15 @@
         }
     }
 
-    public Joins setCorrelatedVariable(String var) {
-        _correlatedVar = var;
-        return this;
+    public boolean isCorrelatedVariable(String var) {
+        boolean isCorrelated = //_ctx.getVariable(_schemaAlias) == null &&
+            _ctx.getVariable(var) == null;
+        if (isCorrelated)
+            _correlatedVar = var;
+        return isCorrelated;
     }
 
-    public void copyToParent() {
+    public void moveJoinsToParent() {
     }
 }
 

Modified: openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java (original)
+++ openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java Fri Jun 26 21:21:10 2009
@@ -156,11 +156,6 @@
      * Returns a value for the given id.
      */
     protected Value getVariable(String id, boolean bind) {
-        // check for already constructed var
-        Value var = getSeenVariable(id);
-        if (var != null)
-            return var;
-
         // create and cache var
         Class<?> type = getDeclaredVariableType(id);
 
@@ -175,6 +170,7 @@
             addSchemaToContext(id, meta);
         }
 
+        Value var = null;
         if (bind)
             var = factory.newBoundVariable(id, type);
         else

Modified: openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Context.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Context.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Context.java (original)
+++ openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Context.java Fri Jun 26 21:21:10 2009
@@ -35,10 +35,11 @@
     public ClassMetaData meta;
     public String schemaAlias;
     public Subquery subquery;
+    public Expression from = null;
     private Context parent = null;
     private Context subsel = null;
     private Object select = null;
-    private int aliasCount = -1;
+    private int aliasCount = -1; 
     private Map<String,Value> variables = new HashMap<String,Value>();
     private Map<String,ClassMetaData> schemas =
         new HashMap<String,ClassMetaData>();
@@ -128,6 +129,10 @@
         return parent;
     }
 
+    public void setParent(Context parent) {
+        this.parent = parent;
+    }
+
     public void addVariable(String id, Value var) {
         variables.put(id.toLowerCase(), var);
     }

Modified: openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java (original)
+++ openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java Fri Jun 26 21:21:10 2009
@@ -36,7 +36,7 @@
     implements Value {
 
     private ClassMetaData _meta = null;
-    private String _alias = null;
+    private String _resAlias = null;  // result alias
 
     /**
      * Return this value as a projection on the given candidate.
@@ -121,18 +121,22 @@
     }
 
     public String getAlias() {
-        return _alias;
+        return _resAlias;
     }
 
     public void setAlias(String alias) {
-        _alias = alias;
+        _resAlias = alias;
     }
 
     public Value getSelectAs() {
-        return _alias != null ? this : null;
+        return _resAlias != null ? this : null;
     }
 
     public Path getPath() {
         return null;
     }
+
+    public String getName() {
+        return null;
+    }
 }

Modified: openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java (original)
+++ openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java Fri Jun 26 21:21:10 2009
@@ -90,4 +90,6 @@
     public Value getSelectAs();
 
     public Path getPath();
+
+    public String getName();
 }

Modified: openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=788874&r1=788873&r2=788874&view=diff
==============================================================================
--- openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java (original)
+++ openjpa/branches/subquery/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java Fri Jun 26 21:21:10 2009
@@ -277,7 +277,10 @@
         evalQueryOperation(exps);
 
         Expression filter = null;
-        filter = and(evalFromClause(root().id == JJTSELECT), filter);
+        Expression from = ctx().from;
+        if (from == null)
+            from = evalFromClause(root().id == JJTSELECT);
+        filter = and(from, filter);
         filter = and(evalWhereClause(), filter);
         filter = and(evalSelectClause(exps), filter);
 
@@ -545,12 +548,15 @@
     }
 
     private Expression evalFromClause(boolean needsAlias) {
-        Expression exp = null;
-
         // build up the alias map in the FROM clause
         JPQLNode from = root().findChildByID(JJTFROM, false);
         if (from == null)
             throw parseException(EX_USER, "no-from-clause", null, null);
+        return evalFromClause(from, needsAlias);
+    }
+
+    private Expression evalFromClause(JPQLNode from, boolean needsAlias) {
+        Expression exp = null;
 
         for (int i = 0; i < from.children.length; i++) {
             JPQLNode node = from.children[i];
@@ -575,7 +581,7 @@
 
     private Expression bindVariableForKeyPath(Path path, String alias,
         Expression exp) {
-        if (alias != null && getSeenVariable(alias) == null) {
+        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);
@@ -587,6 +593,26 @@
         return exp;
     }
 
+    private Expression getSubquery(String alias, Path path, Expression exp) {
+        FieldMetaData fmd = path.last();
+        ClassMetaData candidate = getFieldType(fmd);
+        if (candidate == null && fmd.isElementCollection())
+            candidate = fmd.getDefiningMetaData();
+
+        setCandidate(candidate, alias);
+
+        Subquery subquery =
+            factory.newSubquery(candidate, true, alias);
+        
+        Context subContext = ctx();
+        subContext.setSubquery(subquery);
+        Path subpath = factory.newPath(subquery);
+        subpath.setMetaData(candidate);
+        exp = bindVariableForKeyPath(path, alias, exp);
+        exp =  and(exp, factory.equal(path, subpath));
+        return exp;
+    }
+
     /**
      * Adds a join condition to the given expression.
      *
@@ -607,14 +633,16 @@
         JPQLNode alias = node.getChildCount() >= 2 ? right(node) : null;
         // OPENJPA-15 support subquery's from clause do not start with 
         // identification_variable_declaration()
-        if (inner && ctx().subquery != null && ctx().schemaAlias == null) {
-            setCandidate(getFieldType(path.last()), alias.text);
-
-            Path subpath = factory.newPath(ctx().subquery);
-            subpath.setMetaData(ctx().subquery.getMetaData());
-            exp = bindVariableForKeyPath(path, alias.text, exp);
-            exp =  and(exp, factory.equal(path, subpath));
-            return exp;
+        if (inner && ctx().getParent() != null && ctx().schemaAlias == null) {
+//            ClassMetaData candidate = getFieldType(path.last());
+//            setCandidate(candidate, alias.text);
+//
+//            ctx().subquery = factory.newSubquery(candidate, true, alias.text);
+//            Path subpath = factory.newPath(ctx().subquery);
+//            subpath.setMetaData(candidate);
+//            exp = bindVariableForSubPath(path, alias.text, exp);
+//            exp =  and(exp, factory.equal(path, subpath));
+            return getSubquery(alias.text, path, exp);
         }
 
         return addJoin(path, alias, exp);
@@ -675,18 +703,19 @@
             // clause, since we might be in a subquery against a collection
             if (isPath(left)) {
                 Path path = getPath(left);
-                FieldMetaData fmd = path.last();
-                ClassMetaData candidate = getFieldType(fmd);
-
-                if (candidate == null && fmd.isElementCollection())
-                    candidate = fmd.getDefiningMetaData();
-
-                setCandidate(candidate, alias);
-
-                Path subpath = factory.newPath(ctx().subquery);
-                subpath.setMetaData(ctx().subquery.getMetaData());
-                exp = bindVariableForKeyPath(path, alias, exp);
-                return and(exp, factory.equal(path, subpath));
+//                FieldMetaData fmd = path.last();
+//                ClassMetaData candidate = getFieldType(fmd);
+//
+//                if (candidate == null && fmd.isElementCollection())
+//                    candidate = fmd.getDefiningMetaData();
+//
+//                setCandidate(candidate, alias);
+//                exp = bindVariableForSubPath(path, alias, exp);
+//
+//                Path subpath = factory.newPath(ctx().subquery);
+//                subpath.setMetaData(ctx().subquery.getMetaData());
+//                return and(exp, factory.equal(path, subpath));
+                return getSubquery(alias, path, exp);
             } else {
                 // we have an alias: bind it as a variable
                 Value var = getVariable(alias, true);
@@ -765,7 +794,10 @@
         if (id == null)
             return null;
 
-        return super.getVariable(id.toLowerCase(), bind);
+        if (bind)
+            return super.getVariable(id.toLowerCase(), bind);
+        else
+            return ctx().findVariable(id);
     }
 
     protected Value getDefinedVariable(String id) {
@@ -774,7 +806,6 @@
 
     protected boolean isSeenVariable(String var) {
         Context c = ctx().findContext(var);
-        System.out.println("Context.isSeenVariable: ctx="+c);
         if (c != null)
             return true;
         return false;
@@ -1408,12 +1439,23 @@
 
         // parse the subquery
         ParsedJPQL parsed = new ParsedJPQL(node.parser.jpql, node);
-        Context subContxt = new Context(parsed, null, ctx());
+        Context parent = ctx();
+        Context subContext = new Context(parsed, null, ctx());
+        contexts.push(subContext);
+        subContext.setParent(parent);
+
+        // evaluate from clause for resolving variables defined in subquery
+        JPQLNode from = node.getChild(1);
+        subContext.from = evalFromClause(from, true);
+
         ClassMetaData candidate = getCandidateMetaData(node);
-        Subquery subq = factory.newSubquery(candidate, subclasses, alias);
+        Subquery subq = subContext.getSubquery();
+        if (subq == null) {
+            subq = factory.newSubquery(candidate, subclasses, alias);
+            subContext.setSubquery(subq);
+        }
         subq.setMetaData(candidate);
-        subContxt.setSubquery(subq);
-        contexts.push(subContxt);
+        subq.setAlias(alias);
 
         try {
             QueryExpressions subexp = getQueryExpressions();
@@ -1522,14 +1564,14 @@
         if (cmd != null) {
             // handle the case where the class name is the alias
             // for the candidate (we don't use variables for this)
-            //Value thiz = factory.getThis(); //fyw
-            Value thiz = null;
-            if (ctx().subquery == null || 
-                ctx().getSchema(name.toLowerCase()) == null) {
-                thiz = factory.getThis();
-            } else {
-                thiz = factory.newPath(ctx().subquery);
-            }
+            Value thiz = factory.getThis();
+//            Value thiz = null;
+//            if (ctx().subquery == null || 
+//                ctx().getSchema(name.toLowerCase()) == null) {
+//                thiz = factory.getThis();
+//            } else {
+//                thiz = factory.newPath(ctx().subquery);
+//            }
             ((Path)thiz).setSchemaAlias(name);
             thiz.setMetaData(cmd);
             return thiz;
@@ -1946,9 +1988,9 @@
         Value v = c.getVariable(var);
         if (v != null)
             return v;
-        if (c.getSchema(var) != null)
-            // variable is to be defined in this context
-            return null;
+//        if (c.getSchema(var) != null)
+//            // variable is to be defined in this context
+//            return null;
         if (c.getParent() != null)
             return c.getParent().findVariable(var);