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/05/19 00:23:04 UTC
svn commit: r776117 - in /openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/
openjpa-persistence-jdbc/...
Author: fancy
Date: Mon May 18 22:23:04 2009
New Revision: 776117
URL: http://svn.apache.org/viewvc?rev=776117&view=rev
Log:
OPENJPA-1094 JPA2 Query support KEY to appear in subquery
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ContainsExpression.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/MapKey.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/kernel/exps/Variable.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java?rev=776117&r1=776116&r2=776117&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java Mon May 18 22:23:04 2009
@@ -21,6 +21,7 @@
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
+import org.apache.openjpa.kernel.exps.Path;
import org.apache.openjpa.kernel.exps.Value;
/**
@@ -109,5 +110,9 @@
public Value getSelectAs() {
return _alias != null ? this : null;
}
+
+ public Path getPath() {
+ return null;
+ }
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ContainsExpression.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ContainsExpression.java?rev=776117&r1=776116&r2=776117&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ContainsExpression.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ContainsExpression.java Mon May 18 22:23:04 2009
@@ -42,7 +42,7 @@
Val val1 = getValue1();
if (contains != null && val1 instanceof PCPath) {
PCPath sql = (PCPath) val1;
- String path = sql.getPath();
+ String path = sql.getPCPathString();
// update the count for this path
Integer count = (Integer) contains.get(path);
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/MapKey.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/MapKey.java?rev=776117&r1=776116&r2=776117&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/MapKey.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/MapKey.java Mon May 18 22:23:04 2009
@@ -124,4 +124,11 @@
public void setMetaData(ClassMetaData meta) {
_meta = meta;
}
+
+ public Object toDataStoreValue(Select sel, ExpContext ctx, ExpState state,
+ Object val) {
+ KeyExpState estate = (KeyExpState) state;
+ return _key.toDataStoreValue(sel, ctx,
+ estate.key, val);
+ }
}
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=776117&r1=776116&r2=776117&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 Mon May 18 22:23:04 2009
@@ -218,7 +218,7 @@
return xpath.toString();
}
- public String getPath() {
+ public String getPCPathString() {
if (_actions == null)
return (_varName == null) ? "" : _varName + ".";
@@ -293,10 +293,14 @@
case JavaTypes.COLLECTION:
ValueMapping elem = pstate.field.getElementMapping();
if (pstate.field.isElementCollection() &&
- pstate.field.getElement().isEmbedded())
- return ((HandlerCollectionTableFieldStrategy)
- pstate.field.getStrategy()).getElementColumns(
- elem.getTypeMapping());
+ pstate.field.getElement().isEmbedded()) {
+ Strategy strategy = pstate.field.getStrategy();
+ if (strategy instanceof
+ HandlerCollectionTableFieldStrategy)
+ return ((HandlerCollectionTableFieldStrategy)
+ strategy).getElementColumns(
+ elem.getTypeMapping());
+ }
if (pstate.joinedRel && elem.getTypeCode() == JavaTypes.PC)
return elem.getTypeMapping().getPrimaryKeyColumns();
if (elem.getColumns().length > 0)
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=776117&r1=776116&r2=776117&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 Mon May 18 22:23:04 2009
@@ -69,7 +69,7 @@
}
public Class getType() {
- if (_exps != null) {
+ if (_exps != null && _type == null) {
if (_exps.projections.length == 0)
return _candidate.getDescribedType();
if (_exps.projections.length == 1)
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Variable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Variable.java?rev=776117&r1=776116&r2=776117&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Variable.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Variable.java Mon May 18 22:23:04 2009
@@ -24,6 +24,7 @@
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
+import org.apache.openjpa.kernel.exps.Path;
import org.apache.openjpa.meta.ClassMetaData;
/**
@@ -75,6 +76,10 @@
return _path;
}
+ public Path getPath() {
+ return _path;
+ }
+
/**
* Set the path this variable is aliased to.
*/
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java?rev=776117&r1=776116&r2=776117&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Val.java Mon May 18 22:23:04 2009
@@ -131,4 +131,8 @@
public Value getSelectAs() {
return _alias != null ? this : null;
}
+
+ public Path getPath() {
+ return null;
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java?rev=776117&r1=776116&r2=776117&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Value.java Mon May 18 22:23:04 2009
@@ -88,4 +88,6 @@
* Return 'this' concrete class if alias is set, otherwise null
*/
public Value getSelectAs();
+
+ public Path getPath();
}
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=776117&r1=776116&r2=776117&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 Mon May 18 22:23:04 2009
@@ -651,7 +651,13 @@
// clause, since we might be in a subquery against a collection
if (isPath(left)) {
Path path = getPath(left);
- setCandidate(getFieldType(path.last()), alias);
+ 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());
@@ -1491,6 +1497,14 @@
private Value validateMapPath(JPQLNode node, JPQLNode id) {
Path path = (Path) getValue(id);
FieldMetaData fld = path.last();
+
+ if (fld == null && ctx().subquery != null) {
+ Value var = getVariable(id.text, false);
+ if (var != null) {
+ path = factory.newPath(var);
+ fld = path.last();
+ }
+ }
if (fld != null) {
// validate the field is of type java.util.Map
@@ -1503,7 +1517,11 @@
throw parseException(EX_USER, "bad-qualified-identifier",
new Object[]{ id.text, oper}, null);
}
- }
+ }
+ else
+ throw parseException(EX_USER, "unknown-type",
+ new Object[]{ id.text}, null);
+
return path;
}
@@ -1517,7 +1535,9 @@
FieldMetaData fld = path.last();
path = (Path) factory.getKey(path);
ClassMetaData meta = fld.getKey().getTypeMetaData();
- if (inWhereClause && meta != null)
+ if (inWhereClause && meta != null &&
+ fld.isElementCollection() &&
+ fld.getElement().getEmbeddedMetaData() != null)
// check basic type
throw parseException(EX_USER, "bad-general-identifier",
new Object[]{ id.text, "KEY" }, null);
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java?rev=776117&r1=776116&r2=776117&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java Mon May 18 22:23:04 2009
@@ -746,6 +746,18 @@
assertEmployee(e);
}
tran.commit();
+ em.clear();
+ // test range variable over element collection
+ String[] query = {
+ "select e from Employee e, in (e.nickNames) n " +
+ " where n like '%1'",
+ };
+ for (int i = 0; i < query.length; i++) {
+ es = em.createQuery(query[i]).getResultList();
+ for (Employee e : es){
+ assertEmployee(e);
+ }
+ }
em.close();
}
@@ -2145,6 +2157,25 @@
}
tran.commit();
+
+ String query[] = {
+ "select d from Department1 d join d.empMap e " +
+ " where KEY(e) > 1 order by d",
+ "select d from Department1 d join d.empMap e" +
+ " where d.deptId = KEY(e) order by d",
+ "select d from Department1 d " +
+ " where d.deptId < ANY " +
+ " (select KEY(e) from in(d.empMap) e) " +
+ " order by d",
+ "select d from Department1 d " +
+ " where d.deptId < SOME " +
+ " (select KEY(e) from Department1 d1, in(d1.empMap) e) " +
+ " order by d",
+ };
+ for (int i = 0; i < query.length; i++) {
+ ds1 = em.createQuery(query[i]).getResultList();
+ assertDepartment1(ds1.get(0));
+ }
em.close();
}
@@ -2290,6 +2321,66 @@
}
tran.commit();
+
+ String imageKey1 = (String) is1.get(0).getImages().
+ keySet().toArray()[0];
+ String imageKey2 = (String) is2.get(0).getImages().
+ keySet().toArray()[0];
+ String imageKey3 = (String) is3.get(0).getImages().
+ keySet().toArray()[0];
+ String[] query = {
+ "select i from Item1 i" +
+ " where ?1 = any " +
+ " (select KEY(e) from Item1 i, in(i.images) e) " +
+ " order by i",
+ "select i from Item2 i" +
+ " where ?1 = any " +
+ " (select KEY(e) from Item2 i, in(i.images) e) " +
+ " order by i",
+ "select i from Item3 i" +
+ " where ?1 = any " +
+ " (select KEY(e) from Item3 i, in(i.images) e) " +
+ " order by i",
+ "select i from Item1 i" +
+ " where exists " +
+ " (select e from Item1 i, in(i.images) e" +
+ " where ?1 = KEY(e)) " +
+ " order by i",
+ "select i from Item2 i" +
+ " where exists " +
+ " (select e from Item2 i, in(i.images) e" +
+ " where ?1 = KEY(e)) " +
+ " order by i",
+ "select i from Item3 i" +
+ " where exists " +
+ " (select e from Item3 i, in(i.images) e" +
+ " where ?1 = KEY(e)) " +
+ " order by i",
+ };
+
+ for (int i = 0; i < query.length; i++) {
+ Query q = em.createQuery(query[i]);
+ switch (i) {
+ case 0:
+ case 3:
+ q.setParameter(1, imageKey1);
+ is1 = q.getResultList();
+ assertItem1(is1.get(0));
+ break;
+ case 1:
+ case 4:
+ q.setParameter(1, imageKey2);
+ is2 = q.getResultList();
+ assertItem2(is2.get(0));
+ break;
+ case 2:
+ case 5:
+ q.setParameter(1, imageKey3);
+ is3 = q.getResultList();
+ assertItem3(is3.get(0));
+ break;
+ }
+ }
em.close();
}
@@ -2308,6 +2399,56 @@
assertCompany2(c);
}
tran.commit();
+
+ em.clear();
+ // test KEY(e) appeared in subquery
+ Division d1 = (Division) ((Company1) cs1.get(0)).getOrganization().
+ keySet().toArray()[0];
+ Division d2 = (Division) ((Company2) cs2.get(0)).getOrganization().
+ keySet().toArray()[0];
+ String[] query = {
+ "select c from Company1 c, in(c.organization) d " +
+ " where KEY(d) = ?1",
+ "select c from Company1 c " +
+ " where ?1 = " +
+ " (select KEY(d) from Company1 c, in(c.organization) d" +
+ " where d.id = 1)" +
+ " order by c ",
+ "select c from Company2 c" +
+ " where ?1 = " +
+ " (select KEY(d) from Company2 c, in(c.organization) d" +
+ " where d.id = 3)" +
+ " order by c ",
+ "select c from Company1 c where exists" +
+ " (select d from in(c.organization) d" +
+ " where KEY(d) = ?1)" +
+ " order by c ",
+ "select c from Company2 c where exists" +
+ " (select d from in(c.organization) d" +
+ " where KEY(d) = ?1)" +
+ " order by c ",
+ };
+
+ for (int i = 0; i < query.length; i++) {
+ Query q = em.createQuery(query[i]);
+ switch (i) {
+ case 0:
+ case 1:
+ case 3:
+ q.setParameter(1, d1);
+ cs1 = q.getResultList();
+ if (cs1.size() > 0)
+ assertCompany1(cs1.get(0));
+ break;
+ case 2:
+ case 4:
+ q.setParameter(1, d2);
+ cs2 = q.getResultList();
+ if (cs2.size() > 0)
+ assertCompany2(cs2.get(0));
+ break;
+ }
+ }
em.close();
}