You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2008/12/09 01:17:23 UTC
svn commit: r724564 - in /openjpa/trunk:
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/
openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/
Author: ppoddar
Date: Mon Dec 8 16:17:23 2008
New Revision: 724564
URL: http://svn.apache.org/viewvc?rev=724564&view=rev
Log:
OPENJPA-806: Refactor different domain paths into a single list in QueryDefinitionImpl.
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractDomainObject.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractPath.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AliasContext.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OperatorPath.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryDefinitionImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RootPath.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/Visitable.java
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java Mon Dec 8 16:17:23 2008
@@ -118,7 +118,9 @@
.where(photo.key().like("egret"));
- String jpql = "select i.name, VALUE(p) from Item i join i.photos p where KEY(p) like 'egret'";
+ String jpql = "select i.name, VALUE(p)"
+ + " from Item i join i.photos p"
+ + " where KEY(p) like 'egret'";
compare(jpql, qdef);
}
@@ -444,6 +446,33 @@
compare(jpql, e);
}
+ public void testCorrelatedSubquerySpecialCase1() {
+ DomainObject o = qb.createQueryDefinition(Order.class);
+ DomainObject a = qb.createSubqueryDefinition(o.get("customer").get("accounts"));
+ o.select(o)
+ .where(o.literal(10000).lessThan(a.select(a.get("balance")).all()));
+
+ String jpql = "select o from Order o"
+ + " where 10000 < ALL "
+ + " (select a.balance from o.customer c join o.customer.accounts a)";
+
+ compare(jpql, o);
+ }
+
+ public void testCorrelatedSubquerySpecialCase2() {
+ DomainObject o = qb.createQueryDefinition(Order.class);
+ DomainObject c = o.join("customer");
+ DomainObject a = qb.createSubqueryDefinition(c.get("accounts"));
+ o.select(o)
+ .where(o.literal(10000).lessThan(a.select(a.get("balance")).all()));
+
+ String jpql = "select o from Order o JOIN o.customer c"
+ + " where 10000 < ALL "
+ + " (select a.balance from c.accounts a)";
+
+ compare(jpql, o);
+ }
+
public void testRecursiveDefinitionIsNotAllowed() {
DomainObject q = qb.createQueryDefinition(Customer.class);
q.where(q.exists().and(q.get("name").equal("wrong")));
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractDomainObject.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractDomainObject.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractDomainObject.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractDomainObject.java Mon Dec 8 16:17:23 2008
@@ -18,7 +18,6 @@
*/
package org.apache.openjpa.persistence.query;
-import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@@ -43,39 +42,13 @@
*/
public abstract class AbstractDomainObject extends AbstractPath
implements DomainObject {
- private final QueryDefinitionImpl _owner;
- private List<JoinPath> _joins;
- private List<FetchPath> _fetchJoins;
protected AbstractDomainObject(QueryDefinitionImpl owner,
AbstractPath parent, PathOperator op, Object part2) {
- super(parent, op, part2);
- _owner = owner;
+ super(owner, parent, op, part2);
}
/**
- * Gets the QueryDefinition that created this path.
- * @return
- */
- public QueryDefinitionImpl getOwner() {
- return _owner;
- }
-
- /**
- * Gets the fetch joins associated with this path. Can be null.
- */
- public List<FetchPath> getFetchJoins() {
- return _fetchJoins;
- }
-
- /**
- * Gets the joins associated with this path. Can be null.
- */
- public List<JoinPath> getJoins() {
- return _joins;
- }
-
- /**
* Adding a root adds a root domain to the owning query.
*/
public DomainObject addRoot(Class cls) {
@@ -100,49 +73,32 @@
* Derives a path from this path by joining the given field.
* Also the joined path becomes a domain of the owning query.
*/
- public DomainObject join(String attribute) {
- return join(attribute, PathOperator.INNER);
+ public DomainObject join(String attr) {
+ return _owner.addDomain(new JoinPath(this, PathOperator.INNER, attr));
}
/**
* Derives a path from this path by outer joining the given field.
* Also the joined path becomes a domain of the owning query.
*/
- public DomainObject leftJoin(String attribute) {
- return join(attribute, PathOperator.OUTER);
- }
-
- protected DomainObject join(String attr, PathOperator joinType) {
- JoinPath join = new JoinPath(this, joinType, attr);
- if (_joins == null) {
- _joins = new ArrayList<JoinPath>();
- }
- _joins.add(join);
- return join;
+ public DomainObject leftJoin(String attr) {
+ return _owner.addDomain(new JoinPath(this, PathOperator.OUTER, attr));
}
/**
* Derives a path from this path by fetch joining the given field.
*/
- public FetchJoinObject joinFetch(String attribute) {
- return fetchJoin(attribute, PathOperator.FETCH_INNER);
+ public FetchJoinObject joinFetch(String attr) {
+ return _owner.addDomain(new FetchPath(this, PathOperator.FETCH_INNER,
+ attr));
}
/**
* Derives a path from this path by fetch joining the given field.
*/
- public FetchJoinObject leftJoinFetch(String attribute) {
- return fetchJoin(attribute, PathOperator.FETCH_OUTER);
- }
-
- private FetchJoinObject fetchJoin(String attr, PathOperator joinType) {
- NavigationPath path = new NavigationPath(_owner, this, attr);
- FetchPath join = new FetchPath(path, joinType);
- if (_fetchJoins == null) {
- _fetchJoins = new ArrayList<FetchPath>();
- }
- _fetchJoins.add(join);
- return join;
+ public FetchJoinObject leftJoinFetch(String attr) {
+ return _owner.addDomain(new FetchPath(this, PathOperator.FETCH_OUTER,
+ attr));
}
/**
@@ -376,19 +332,4 @@
public QueryDefinition where(Predicate predicate) {
return _owner.where(predicate);
}
-
- // -----------------------------------------------------------------------
- // contract for conversion to JPQL.
- // -----------------------------------------------------------------------
- /**
- * Sets alias for this domain and all its joins.
- */
- public void setAlias(AliasContext ctx) {
- ctx.getAlias(this);
- if (_joins != null)
- for (JoinPath join : _joins)
- join.setAlias(ctx);
- }
-
-
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractPath.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractPath.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractPath.java Mon Dec 8 16:17:23 2008
@@ -18,6 +18,8 @@
*/
package org.apache.openjpa.persistence.query;
+import java.util.LinkedList;
+
import javax.persistence.Aggregate;
import javax.persistence.Expression;
import javax.persistence.PathExpression;
@@ -45,8 +47,10 @@
protected final AbstractPath _parent;
protected final Object _part2;
protected final PathOperator _operator;
+ protected final QueryDefinitionImpl _owner;
- protected AbstractPath(AbstractPath parent, PathOperator op, Object part2) {
+ protected AbstractPath(QueryDefinitionImpl owner, AbstractPath parent, PathOperator op, Object part2) {
+ _owner = owner;
_parent = parent;
_part2 = part2;
_operator = op;
@@ -55,6 +59,10 @@
// ------------------------------------------------------------------------
// Path related functions.
// ------------------------------------------------------------------------
+
+ final QueryDefinitionImpl getOwner() {
+ return _owner;
+ }
/**
* Gets the parent from which this receiver has been derived. Can be null
* for a root path.
@@ -112,4 +120,17 @@
public Expression type() {
return new TypeExpression(this);
}
+
+ LinkedList<AbstractPath> split() {
+ return _split(this, new LinkedList<AbstractPath>());
+ }
+
+ private LinkedList<AbstractPath> _split(AbstractPath path,
+ LinkedList<AbstractPath> list) {
+ if (path == null)
+ return list;
+ _split(path.getParent(), list);
+ list.add(path);
+ return list;
+ }
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java Mon Dec 8 16:17:23 2008
@@ -39,10 +39,6 @@
throw new UnsupportedOperationException(this.getClass().getName());
}
- public void setAlias(AliasContext ctx) {
- throw new UnsupportedOperationException(this.getClass().getName());
- }
-
public String asJoinable(AliasContext ctx) {
throw new UnsupportedOperationException(this.getClass().getName());
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AliasContext.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AliasContext.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AliasContext.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AliasContext.java Mon Dec 8 16:17:23 2008
@@ -49,7 +49,13 @@
String alias = _aliases.get(path);
if (alias != null)
return alias;
- alias = path.getAliasHint(this).substring(0,1).toLowerCase();
+ return setAlias(path);
+ }
+
+ public String setAlias(ExpressionImpl path) {
+ if (_aliases.containsKey(path))
+ return _aliases.get(path);
+ String alias = path.getAliasHint(this).substring(0,1).toLowerCase();
int i = 2;
while (_aliases.containsValue(alias)) {
alias = alias.substring(0,1) + i;
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java Mon Dec 8 16:17:23 2008
@@ -462,14 +462,7 @@
//
// Visitable/Selectable implementation
//
- public void setAlias(AliasContext ctx) {
- ctx.getAlias(this);
- }
-
public String getAliasHint(AliasContext ctx) {
return "o";
}
-
- public abstract String asExpression(AliasContext ctx);
- public abstract String asProjection(AliasContext ctx);
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java Mon Dec 8 16:17:23 2008
@@ -18,6 +18,8 @@
*/
package org.apache.openjpa.persistence.query;
+import static org.apache.openjpa.persistence.query.PathOperator.NAVIGATION;
+
import javax.persistence.FetchJoinObject;
/**
@@ -26,18 +28,21 @@
* @author Pinaki Poddar
*
*/
-public class FetchPath extends AbstractVisitable
+public class FetchPath extends AbstractDomainObject
implements FetchJoinObject, Visitable {
- private NavigationPath _path;
- private PathOperator _joinType;
-
-
- FetchPath(NavigationPath path, PathOperator joinType) {
- _path = path;
- _joinType = joinType;
+ FetchPath(AbstractDomainObject parent, PathOperator joinType, String attr) {
+ super(parent.getOwner(), parent, joinType, attr);
}
- public String asExpression(AliasContext ctx) {
- return _joinType + " " + _path.asExpression(ctx);
+ @Override
+ public String asJoinable(AliasContext ctx) {
+ StringBuffer tmp = new StringBuffer(getOperator().toString());
+ tmp.append(getParent().asProjection(ctx))
+ .append(NAVIGATION)
+ .append(getLastSegment())
+ .append(" ");
+
+ return tmp.toString();
}
+
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java Mon Dec 8 16:17:23 2008
@@ -49,17 +49,12 @@
@Override
public String asJoinable(AliasContext ctx) {
- StringBuffer tmp = new StringBuffer(getOperator().toString());
- tmp.append(getParent().asProjection(ctx))
+ return new StringBuffer(getOperator().toString())
+ .append(getParent().asProjection(ctx))
.append(NAVIGATION)
.append(getLastSegment())
.append(" ")
- .append(ctx.getAlias(this));
-
- if (getJoins() != null)
- for (JoinPath join : getJoins())
- tmp.append(join.asJoinable(ctx));
- return tmp.toString();
+ .append(ctx.getAlias(this)).toString();
}
@Override
@@ -75,4 +70,9 @@
return ctx.getAlias(this);
return getParent().asProjection(ctx) + NAVIGATION + getLastSegment();
}
+
+ public String toString() {
+ return getOperator() + getParent().toString() + "*" + getLastSegment();
+ }
+
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java Mon Dec 8 16:17:23 2008
@@ -38,6 +38,11 @@
}
@Override
+ public String getAliasHint(AliasContext ctx) {
+ return getLastSegment();
+ }
+
+ @Override
public String asProjection(AliasContext ctx) {
AbstractPath parent = getParent();
if (ctx.hasAlias(parent))
@@ -59,4 +64,9 @@
public String asJoinable(AliasContext ctx) {
return asProjection(ctx) + " " + ctx.getAlias(this);
}
+
+ public String toString() {
+ return getParent().toString()+"."+getLastSegment();
+ }
+
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OperatorPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OperatorPath.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OperatorPath.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OperatorPath.java Mon Dec 8 16:17:23 2008
@@ -55,4 +55,9 @@
public String asJoinable(AliasContext ctx) {
throw new UnsupportedOperationException();
}
+
+ public String toString() {
+ return getOperator() + "(" + getParent().toString() + ")";
+ }
+
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java Mon Dec 8 16:17:23 2008
@@ -18,17 +18,12 @@
*/
package org.apache.openjpa.persistence.query;
-import java.io.Serializable;
-
import javax.persistence.DomainObject;
import javax.persistence.PathExpression;
import javax.persistence.QueryBuilder;
import javax.persistence.QueryDefinition;
-import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
/**
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryDefinitionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryDefinitionImpl.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryDefinitionImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryDefinitionImpl.java Mon Dec 8 16:17:23 2008
@@ -23,7 +23,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Date;
+import java.util.LinkedList;
import java.util.List;
import javax.persistence.CaseExpression;
@@ -79,16 +82,34 @@
public DomainObject addSubqueryRoot(PathExpression path) {
AbstractPath impl = (AbstractPath)path;
- AbstractDomainObject newRoot = new NavigationPath(this,
- impl.getParent(), impl.getLastSegment().toString());
- addDomain(newRoot);
+ LinkedList<AbstractPath> paths = impl.split();
+ QueryDefinitionImpl owner = impl.getOwner();
+ int i = 0;
+ while (i < paths.size() && owner.hasDomain(paths.get(i))) {
+ i++;
+ }
+
+ AbstractPath next = paths.get(i);
+ DomainObject newRoot = new NavigationPath(this,
+ next.getParent(), next.getLastSegment().toString());
+ addDomain((AbstractDomainObject)newRoot);
+ i++;
+ for (; i < paths.size(); i++) {
+ next = paths.get(i);
+ newRoot = newRoot.join(next.getLastSegment().toString());
+ }
return newRoot;
}
- protected void addDomain(AbstractDomainObject path) {
+ boolean hasDomain(PathExpression path) {
+ return _domains != null && _domains.contains(path);
+ }
+
+ protected <T extends AbstractDomainObject> T addDomain(T path) {
if (_domains == null)
_domains = new ArrayList<AbstractDomainObject>();
_domains.add(path);
+ return path;
}
public Subquery all() {
@@ -138,6 +159,8 @@
public QueryDefinition groupBy(PathExpression... pathExprs) {
if (_groupBys == null) {
_groupBys = new ArrayList<PathExpression>();
+ } else {
+ _groupBys.clear();
}
for (PathExpression e : pathExprs)
_groupBys.add(e);
@@ -147,6 +170,8 @@
public QueryDefinition groupBy(List<PathExpression> pathExprList) {
if (_groupBys == null) {
_groupBys = new ArrayList<PathExpression>();
+ } else {
+ _groupBys.clear();
}
for (PathExpression e : pathExprList)
_groupBys.add(e);
@@ -336,38 +361,17 @@
return _projections;
}
- /**
- *
- */
@Override
public String asExpression(AliasContext ctx) {
ctx.push(this);
StringBuffer buffer = new StringBuffer();
registerDomains(ctx);
-
- fillBuffer(_distinct ? "SELECT DISTINCT " : "SELECT ", buffer, ctx,
- getProjections(), Visit.PROJECTION);
- buffer.append(" FROM ");
- for (int i=0; _domains != null && i < _domains.size(); i++) {
- buffer.append(_domains.get(i).asJoinable(ctx));
- fillBuffer(" ", buffer, ctx, _domains.get(i).getJoins(),
- Visit.JOINABLE);
- fillBuffer(" ", buffer, ctx, _domains.get(i).getFetchJoins(),
- Visit.EXPRESSION);
- if (i != _domains.size()-1)
- buffer.append(",");
- }
- if (_where != null) {
- buffer.append(" WHERE ")
- .append(((Visitable)_where).asExpression(ctx));
- }
-
+ String select = _distinct ? "SELECT DISTINCT " : "SELECT ";
+ fillBuffer(select, buffer, ctx, getProjections(), Visit.PROJECTION);
+ fillBuffer(" FROM ", buffer, ctx, _domains, Visit.JOINABLE);
+ fillBuffer(" WHERE ", buffer, ctx, _where);
fillBuffer(" GROUP BY ", buffer, ctx, _groupBys, Visit.EXPRESSION);
-
- if (_having != null) {
- buffer.append(" HAVING ")
- .append(((Visitable)_having).asExpression(ctx));
- }
+ fillBuffer(" HAVING ", buffer, ctx, _having);
fillBuffer(" ORDER BY ", buffer, ctx, _orderBys, Visit.EXPRESSION);
return buffer.toString();
@@ -391,28 +395,50 @@
case EXPRESSION : buffer.append(v.asExpression(ctx))
.append(i != list.size()-1 ? ", " : " ");
break;
- case JOINABLE : buffer.append(v.asJoinable(ctx));
+ case JOINABLE : buffer.append(v.asJoinable(ctx))
+ .append(i > 0 && v instanceof RootPath ?
+ "," : " ");
break;
}
}
}
+ public void fillBuffer(String header, StringBuffer buffer, AliasContext ctx,
+ Predicate p) {
+ if (p == null)
+ return;
+ Visitable v = (Visitable)p;
+ buffer.append(header);
+ buffer.append(v.asExpression(ctx));
+ }
+
/**
- * Registers each domain with an alias.
- * @param ctx
+ * Registers each domain with an alias. Also set alias for order by items
+ * that are projected.
*/
private void registerDomains(AliasContext ctx) {
if (_domains != null) {
+ Collections.sort(_domains, new DomainSorter());
for (AbstractDomainObject domain : _domains) {
- domain.setAlias(ctx);
+ ctx.setAlias(domain);
}
}
if (_orderBys != null) {
for (OrderableItem o : _orderBys) {
ExpressionImpl e = o.getExpression();
if (_projections != null && _projections.contains(e))
- e.setAlias(ctx);
+ ctx.setAlias(e);
}
}
}
+
+ static class DomainSorter implements Comparator<AbstractDomainObject> {
+ static List<Class> _order = Arrays.asList(new Class[] {
+ RootPath.class, NavigationPath.class, OperatorPath.class,
+ JoinPath.class, FetchPath.class, } );
+
+ public int compare(AbstractDomainObject a, AbstractDomainObject b) {
+ return _order.indexOf(a.getClass()) - _order.indexOf(b.getClass());
+ }
+ }
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RootPath.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RootPath.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RootPath.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RootPath.java Mon Dec 8 16:17:23 2008
@@ -38,4 +38,8 @@
public String asProjection(AliasContext ctx) {
return ctx.getAlias(this);
}
+
+ public String toString() {
+ return getLastSegment().getSimpleName();
+ }
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/Visitable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/Visitable.java?rev=724564&r1=724563&r2=724564&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/Visitable.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/Visitable.java Mon Dec 8 16:17:23 2008
@@ -29,24 +29,23 @@
*/
public interface Visitable extends Serializable {
/**
- * Get a JPQL fragment as used in a WHERE clause.
+ * Get a JPQL fragment as used in WHERE clause.
*/
String asExpression(AliasContext ctx);
/**
- * Gets the string representation in a SELECT projection.
+ * Gets the string representation in SELECT projection.
*/
String asProjection(AliasContext ctx);
/**
- * Sets alias.
+ * Gets the string representation in FROM clause.
*/
- void setAlias(AliasContext ctx);
+ String asJoinable(AliasContext ctx);
+ /**
+ * Gets the hint to be used while creating alias.
+ */
String getAliasHint(AliasContext ctx);
-
- String asJoinable(AliasContext ctx);
-
-
}