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