OPENJPA-1013: subquery support

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@781621 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Fay Wang 2009-06-03 23:44:58 +00:00
parent b99931efa8
commit be8b9808f6
18 changed files with 1829 additions and 1473 deletions

View File

@ -439,14 +439,16 @@ public class JDBCExpressionFactory
if (val instanceof Lit) {
Lit lit = (Lit) val;
StringBuffer value = new StringBuffer();
if (lit.getParseType() == Literal.TYPE_SQ_STRING)
int pType = lit.getParseType();
if (pType == Literal.TYPE_SQ_STRING ||
pType == Literal.TYPE_STRING)
value.append("'").append(lit.getValue().toString()).append("'");
else if (lit.getParseType() == Literal.TYPE_BOOLEAN) {
else if (pType == Literal.TYPE_BOOLEAN) {
if ((Boolean) lit.getValue())
value.append("1");
else
value.append("0");
} else if (lit.getParseType() == Literal.TYPE_ENUM) {
} else if (pType == Literal.TYPE_ENUM) {
lit.setRaw(true);
return val;
} else

View File

@ -25,6 +25,7 @@ import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* Used for testing Criteria API.
* The fields are sometimes not declared as there is no validation yet during

View File

@ -19,12 +19,25 @@
package org.apache.openjpa.persistence.criteria;
public class CustomerDetails {
int id;
long id;
int status;
int quantity;
public CustomerDetails() {}
public CustomerDetails(long id, int status) {
this.id = id;
this.status = status;
}
public CustomerDetails(long id, int status, int quantity) {
this.id = id;
this.status = status;
this.quantity = quantity;
}
public int getStatus() {
return status;
}
@ -33,11 +46,11 @@ public class CustomerDetails {
this.status = status;
}
public int getId() {
public long getId() {
return id;
}
public void setId(int id) {
public void setId(long id) {
this.id = id;
}

View File

@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.criteria;
public class CustomerFullName {
public String firstName;
public String lastName;
public CustomerFullName() {}
public CustomerFullName(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}

View File

@ -266,7 +266,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure(message="JPQL generates two queries, Criteria only one")
public void testNullExprUsingCriteria() {
String query =
"SELECT o.name FROM CompUser o WHERE o.age IS NOT NULL AND " +
@ -289,7 +288,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure(message="Invalid SQL for Criteria")
public void testNullExpr2UsingCriteria() {
String query =
"SELECT o.name FROM CompUser o WHERE o.address.country IS NULL";
@ -407,12 +405,10 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure(message="new() in projection is badly broken")
public void testConstructorExprUsingCriteria() {
String query =
"SELECT NEW org.apache.openjpa.persistence.common.apps.MaleUser(" +
"c.name, " +
"c.computerName, c.address, c.age, c.userid)" +
"c.name, c.computerName, c.address, c.age, c.userid)" +
" FROM CompUser c WHERE c.name = 'Seetha'";
CriteriaQuery q = cb.create();
q = cb.create();
@ -433,11 +429,10 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testConcatSubStringFunc1() {
String query = "select " +
"CONCAT('Ablahum', SUBSTRING(e.name, LOCATE('e', e.name), 4)) " +
"From CompUer e WHERE e.name='Seetha'";
"From CompUser e WHERE e.name='Seetha'";
CriteriaQuery q = cb.create();
q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
@ -455,16 +450,16 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testConcatSubStringFunc2() {
String query = "select e.address From CompUser e where " +
"e.computerName = " +
"e.name = 'Seetha' AND e.computerName = " +
"CONCAT('Ablahum', SUBSTRING(e.name, LOCATE('e', e.name), 4)) ";
CriteriaQuery q = cb.create();
q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
q.select(e.get(CompUser_.address));
q.where(cb.equal(
q.where(cb.and(cb.equal(e.get(CompUser_.name), "Seetha"),
cb.equal(
e.get(CompUser_.computerName),
cb.concat("Ablahum",
cb.substring(
@ -472,13 +467,12 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
cb.locate(e.get(CompUser_.name), "e"),
cb.literal(4)
)
))
)))
);
assertEquivalence(q, query);
em.clear();
}
@AllowFailure
public void testConcatSubStringFunc3() {
String query = "select " +
"CONCAT('XYZ', SUBSTRING(e.name, LOCATE('e', e.name))) " +
@ -499,31 +493,31 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testConcatSubStringFunc4() {
String query = "select e.nicknames from CompUser e where e.name = " +
String query = "select e.age from CompUser e where " +
"e.name = 'Seetha' AND e.computerName = " +
"CONCAT('XYZ', SUBSTRING(e.name, LOCATE('e', e.name))) ";
CriteriaQuery q = cb.create();
q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
q.select(e.get(CompUser_.nicknames));
q.where(cb.equal(
e.get(CompUser_.name),
q.select(e.get(CompUser_.age));
q.where(cb.and(cb.equal(e.get(CompUser_.name), "Seetha"),
cb.equal(
e.get(CompUser_.computerName),
cb.concat("XYZ",
cb.substring(
e.get(CompUser_.name),
cb.locate(e.get(CompUser_.name), "e")
)
))
)))
);
assertEquivalence(q, query);
em.clear();
}
@AllowFailure
public void testConcatFunc() {
String query = "select " +
"CONCAT('', '') From CompUser WHERE e.name='Seetha'";
"CONCAT('', '') From CompUser e WHERE e.name='Seetha'";
CriteriaQuery q = cb.create();
q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
@ -533,7 +527,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testTrimFunc1() {
String query = "select Trim(e.computerName) From CompUser e " +
"WHERE e.name='Shannon '";
@ -546,20 +539,18 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testTrimFunc2() {
String query = "select e.name From CompUser e where Trim(e.name) =" +
"'Shannon'";
String query = "select e.computerName From CompUser e where " +
"Trim(e.name) = 'Shannon '";
CriteriaQuery q = cb.create();
q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
q.where(cb.equal(cb.trim(e.get(CompUser_.computerName)), "Shannon"));
q.select(e.get(CompUser_.name));
q.where(cb.equal(cb.trim(e.get(CompUser_.name)), "Shannon"));
q.select(e.get(CompUser_.computerName));
assertEquivalence(q, query);
em.clear();
}
@AllowFailure
public void testLowerFunc1() {
String query = "select LOWER(e.name) From CompUser e WHERE " +
"e.computerName='UNIX'";
@ -572,7 +563,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testLowerFunc2() {
String query = "select e.age From CompUser e where LOWER(e.name)" +
" ='ugo'";
@ -585,7 +575,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testUpperFunc1() {
String query = "select UPPER(e.name) From CompUser e WHERE " +
"e.computerName='PC'";
@ -598,33 +587,31 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testUpperFunc2() {
String query = "select e.nicknames from CompUser e where " +
String query = "select e.age from CompUser e where " +
"UPPER(e.name)='UGO'";
CriteriaQuery q = cb.create();
q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
q.where(cb.equal(cb.upper(e.get(CompUser_.name)), "UGO"));
q.select(e.get(CompUser_.nicknames));
q.select(e.get(CompUser_.age));
assertEquivalence(q, query);
em.clear();
}
@AllowFailure
public void testLengthFunc() {
String query = "SELECT o.name FROM CompUser o " +
"WHERE LENGTH(o.address.country) = 3";
CriteriaQuery q = cb.create();
q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
q.where(cb.equal(cb.length(e.get(CompUser_.name)), 3));
q.where(cb.equal(cb.length(e.get(CompUser_.address).
get(Address_.country)), 3));
q.select(e.get(CompUser_.name));
assertEquivalence(q, query);
em.clear();
}
@AllowFailure
public void testArithmFunc1() {
String query =
"select ABS(e.age) From CompUser e WHERE e.name='Seetha'";
@ -637,7 +624,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testArithmFunc2() {
String query =
"select SQRT(e.age) From CompUser e WHERE e.name='Seetha'";
@ -677,7 +663,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testGroupByHavingClause() {
String query =
"SELECT c.name FROM CompUser c GROUP BY c.name HAVING c.name " +
@ -690,18 +675,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
q.having(cb.like(e.get(CompUser_.name), "S%"));
q.select(e.get(CompUser_.name));
assertEquivalence(q, query);
List result = em.createQuery(q).getResultList();
assertNotNull(result);
assertEquals(3, result.size());
assertTrue(result.contains("Shannon "));
assertTrue(result.contains("Shade"));
assertTrue(result.contains("Seetha"));
em.clear();
}
@AllowFailure
public void testOrderByClause() {
String query =
"SELECT c.name FROM CompUser c WHERE c.name LIKE 'S%' " +
@ -714,18 +690,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
q.select(e.get(CompUser_.name));
q.orderBy(cb.asc(e.get(CompUser_.name)));
assertEquivalence(q, query);
List result = em.createQuery(q).getResultList();
assertNotNull(result);
assertEquals(3, result.size());
assertTrue(result.contains("Shannon "));
assertTrue(result.contains("Seetha"));
assertTrue(result.contains("Shade"));
em.clear();
}
@AllowFailure
public void testAVGAggregFunc() {
//To be Tested: AVG, COUNT, MAX, MIN, SUM
String query = "SELECT AVG(e.age) FROM CompUser e";
@ -734,16 +701,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
Root<CompUser> e = q.from(CompUser.class);
q.select(cb.avg(e.get(CompUser_.age)));
assertEquivalence(q, query);
List result = em.createQuery(q).getResultList();
assertNotNull(result);
assertEquals(1, result.size());
assertTrue(result.contains(25));
em.clear();
}
@AllowFailure
public void testCOUNTAggregFunc() {
String query = "SELECT COUNT(c.name) FROM CompUser c";
@ -752,16 +712,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
Root<CompUser> e = q.from(CompUser.class);
q.select(cb.count(e.get(CompUser_.name)));
assertEquivalence(q, query);
List result = em.createQuery(q).getResultList();
assertNotNull(result);
assertEquals(1, result.size());
assertTrue(result.contains(6l));
em.clear();
}
@AllowFailure
public void testMAXAggregFunc() {
String query = "SELECT DISTINCT MAX(c.age) FROM CompUser c";
@ -770,16 +723,10 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
Root<CompUser> e = q.from(CompUser.class);
q.select(cb.max(e.get(CompUser_.age))).distinct(true);
assertEquivalence(q, query);
List result = em.createQuery(q).getResultList();
assertNotNull(result);
assertEquals(1, result.size());
assertTrue(result.contains(36));
em.clear();
}
@AllowFailure
@AllowFailure(message="criteria does not generate Optimize for 1 row")
public void testMINAggregFunc() {
String query = "SELECT DISTINCT MIN(c.age) FROM CompUser c";
@ -788,16 +735,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
Root<CompUser> e = q.from(CompUser.class);
q.select(cb.min(e.get(CompUser_.age))).distinct(true);
assertEquivalence(q, query);
List result = em.createQuery(q).getResultList();
assertNotNull(result);
assertEquals(1, result.size());
assertTrue(result.contains(10));
em.clear();
}
@AllowFailure
public void testSUMAggregFunc() {
String query = "SELECT SUM(c.age) FROM CompUser c";
@ -806,12 +746,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
Root<CompUser> e = q.from(CompUser.class);
q.select(cb.sum(e.get(CompUser_.age)));
assertEquivalence(q, query);
List result = em.createQuery(q).getResultList();
assertNotNull(result);
assertEquals(1, result.size());
assertTrue(result.contains(153l));
em.clear();
}
@ -861,7 +795,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testTypeExpression4() {
String query = "SELECT e FROM CompUser e where TYPE(e) = MaleUser";
CriteriaQuery q = cb.create();
@ -873,7 +806,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testTypeExpression5() {
String query = "SELECT e FROM CompUser e where TYPE(e) in (MaleUser)";
CriteriaQuery q = cb.create();
@ -885,7 +817,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testTypeExpression6() {
String query = "SELECT e FROM CompUser e where TYPE(e) not in " +
"(MaleUser, FemaleUser)";
@ -910,7 +841,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testTypeExpression8() {
String query = "SELECT MaleUser FROM Address a";
CriteriaQuery q = cb.create();
@ -921,7 +851,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testTypeExpression9() {
String query = "SELECT "
+ " CASE TYPE(e) WHEN FemaleUser THEN 'Female' "
@ -935,9 +864,7 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
em.clear();
}
@AllowFailure
public void testCoalesceExpressions() {
startTx(em);
String query = "SELECT e.name, "
+ "COALESCE (e.address.country, 'Unknown')"
+ " FROM CompUser e ORDER BY e.name DESC";
@ -949,18 +876,10 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
.value("Unknown"));
q.orderBy(cb.desc(e.get(CompUser_.name)));
assertEquivalence(q, query);
List rs = em.createQuery(q).getResultList();
Object[] result = (Object[]) rs.get(rs.size() - 1);
assertEquals("the name is not famzy", "Famzy", result[0]);
assertEquals("Unknown", result[1]);
endTx(em);
em.clear();
}
@AllowFailure
public void testNullIfExpressions() {
startTx(em);
String query = "SELECT e.name, NULLIF (e.address.country, 'USA')"
+ " FROM CompUser e ORDER BY e.name DESC";
CriteriaQuery q = cb.create();
@ -969,22 +888,14 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
Address_.country), "USA"));
q.orderBy(cb.desc(e.get(CompUser_.name)));
assertEquivalence(q, query);
List rs = em.createQuery(q).getResultList();
Object[] result = (Object[]) rs.get(1);
assertEquals("the name is not shannon ", "Shannon ", result[0]);
assertNull("is not null", result[1]);
endTx(em);
em.clear();
}
@AllowFailure
public void testSimpleCaseExpression1() {
String query = "SELECT e.name, e.age+1 as cage, "
String query = "SELECT e.name, e.age+1, "
+ "CASE e.address.country WHEN 'USA' THEN 'us' "
+ " ELSE 'non-us' END as d2, e.address.country "
+ " FROM CompUser e ORDER BY cage, d2 DESC";
+ " ELSE 'non-us' END, e.address.country "
+ " FROM CompUser e";
CriteriaQuery q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
Expression<Integer> cage = cb.sum(e.get(CompUser_.age), 1);
@ -993,21 +904,15 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
"us").otherwise("non-us");
q.select(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get(
Address_.country));
q.orderBy(cb.asc(cage), cb.desc(d2));
assertEquivalence(q, query);
List rs = em.createQuery(q).getResultList();
Object[] result = (Object[]) rs.get(rs.size() - 1);
assertEquals("the name is not seetha", "Seetha", result[0]);
}
@AllowFailure
public void testSimpleCaseExpression2() {
String query = "SELECT e.name, e.age+1 as cage, "
String query = "SELECT e.name, e.age+1, "
+ "CASE e.address.country WHEN 'USA'"
+ " THEN 'United-States' "
+ " ELSE e.address.country END as d2," + " e.address.country "
+ " FROM CompUser e ORDER BY cage, d2 DESC";
+ " ELSE e.address.country END," + " e.address.country "
+ " FROM CompUser e";
CriteriaQuery q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
Expression cage = cb.sum(e.get(CompUser_.age), 1);
@ -1017,42 +922,29 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
e.get(CompUser_.address).get(Address_.country));
q.select(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get(
Address_.country));
q.orderBy(cb.asc(cage), cb.desc(d2));
assertEquivalence(q, query);
List rs = em.createQuery(q).getResultList();
Object[] result = (Object[]) rs.get(rs.size() - 1);
assertEquals("the name is not seetha", "Seetha", result[0]);
}
@AllowFailure
public void testSimpleCaseExpression3() {
String query = "SELECT e.name, "
+ " CASE TYPE(e) WHEN FemaleUser THEN 'Female' "
+ " ELSE 'Male' END as result"
+ " ELSE 'Male' END"
+ " FROM CompUser e WHERE e.name like 'S%' "
+ " ORDER BY e.name DESC";
CriteriaQuery q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
q.select(cb.selectCase(e.type()).when(FemaleUser.class, "Female")
q.select(e.get(CompUser_.name),
cb.selectCase(e.type()).when(FemaleUser.class, "Female")
.otherwise("Male"));
q.where(cb.like(e.get(CompUser_.name), "S%"));
q.orderBy(cb.asc(e.get(CompUser_.name)));
q.orderBy(cb.desc(e.get(CompUser_.name)));
assertEquivalence(q, query);
List rs = em.createQuery(q).getResultList();
Object[] result = (Object[]) rs.get(0);
assertEquals("the result is not female", "Female", result[1]);
assertEquals("the name is not shannon", "Shannon ", result[0]);
result = (Object[]) rs.get(2);
assertEquals("the result is not male", "Male", result[1]);
assertEquals("the name is not seetha", "Seetha", result[0]);
}
@AllowFailure
public void testSimpleCaseExpression4() {
// boolean literal in case expression
String query = "SELECT e.name, CASE e.address.country WHEN 'USA'"
+ " THEN true ELSE false END as b,"
+ " e.address.country FROM CompUser e order by b";
+ " THEN true ELSE false END,"
+ " e.address.country FROM CompUser e";
CriteriaQuery q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
Expression b = cb.selectCase(
@ -1060,21 +952,14 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
true).otherwise(false);
q.select(e.get(CompUser_.name), b, e.get(CompUser_.address).get(
Address_.country));
q.where(cb.like(e.get(CompUser_.name), "S%"));
q.orderBy(cb.asc(b));
assertEquivalence(q, query);
List rs = em.createQuery(q).getResultList();
Object[] result = (Object[]) rs.get(rs.size() - 1);
assertEquals(result[1], 1);
}
@AllowFailure
public void testGeneralCaseExpression1() {
String query = "SELECT e.name, e.age, "
+ " CASE WHEN e.age > 30 THEN e.age - 1 "
+ " WHEN e.age < 15 THEN e.age + 1 ELSE e.age + 0 "
+ " END AS cage FROM CompUser e ORDER BY cage";
+ " END FROM CompUser e";
CriteriaQuery q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
Expression cage = cb.selectCase().when(cb.gt(e.get(CompUser_.age), 30),
@ -1083,18 +968,16 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
cb.sum(e.get(CompUser_.age), 1)).otherwise(
cb.sum(e.get(CompUser_.age), 0));
q.select(e.get(CompUser_.name), e.get(CompUser_.age), cage);
q.orderBy(cb.asc(cage));
assertEquivalence(q, query);
}
@AllowFailure
public void testGeneralCaseExpression2() {
String query = "SELECT e.name, e.age+1 as cage, "
String query = "SELECT e.name, e.age+1, "
+ "CASE WHEN e.address.country = 'USA' "
+ " THEN 'United-States' "
+ " ELSE 'Non United-States' END as d2,"
+ " ELSE 'Non United-States' END,"
+ " e.address.country "
+ " FROM CompUser e ORDER BY cage, d2 DESC";
+ " FROM CompUser e";
CriteriaQuery q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
Expression d2 = cb.selectCase()
@ -1106,28 +989,20 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
Expression cage = cb.sum(e.get(CompUser_.age), 1);
q.select(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get(
Address_.country));
q.orderBy(cb.asc(cage), cb.desc(d2));
assertEquivalence(q, query);
List rs = em.createQuery(q).getResultList();
Object[] result = (Object[]) rs.get(rs.size() - 1);
assertEquals("the name is not seetha", "Seetha", result[0]);
assertEquals("the country is not 'Non United-States'",
"Non United-States", result[2]);
}
@AllowFailure
public void testGeneralCaseExpression3() {
String query = " select e.name, "
+ "CASE WHEN e.age = 11 THEN "
+ "org.apache.openjpa.persistence.criteria.CompUser$" +
"CreditRating.POOR"
+ "org.apache.openjpa.persistence.criteria.CompUser$"
+ "CreditRating.POOR"
+ " WHEN e.age = 35 THEN "
+ "org.apache.openjpa.persistence.criteria.CompUser$" +
"CreditRating.GOOD"
+ "org.apache.openjpa.persistence.criteria.CompUser$"
+ "CreditRating.GOOD"
+ " ELSE "
+ "org.apache.openjpa.persistence.criteria.CompUser$" +
"CreditRating.EXCELLENT"
+ "org.apache.openjpa.persistence.criteria.CompUser$"
+ "CreditRating.EXCELLENT"
+ " END FROM CompUser e ORDER BY e.age";
CriteriaQuery q = cb.create();
Root<CompUser> e = q.from(CompUser.class);
@ -1139,10 +1014,6 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
q.orderBy(cb.asc(e.get(CompUser_.age)));
assertEquivalence(q, query);
List rs = em.createQuery(q).getResultList();
Object[] result = (Object[]) rs.get(0);
assertEquals("the name is not Jacob", "Jacob", result[0]);
assertEquals("the credit rating is not 'POOR'", "POOR", result[1]);
}
// not sure how to write CriteriaQuery for
@ -1153,14 +1024,14 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
+ "where e.creditRating = "
+ "(select "
+ "CASE WHEN e1.age = 11 THEN "
+ "org.apache.openjpa.persistence.criteria.CompUser$" +
"CreditRating.POOR"
+ "org.apache.openjpa.persistence.criteria.CompUser$"
+ "CreditRating.POOR"
+ " WHEN e1.age = 35 THEN "
+ "org.apache.openjpa.persistence.criteria.CompUser$" +
"CreditRating.GOOD"
+ "org.apache.openjpa.persistence.criteria.CompUser$"
+ "CreditRating.GOOD"
+ " ELSE "
+ "org.apache.openjpa.persistence.criteria.CompUser$" +
"CreditRating.EXCELLENT"
+ "org.apache.openjpa.persistence.criteria.CompUser$"
+ "CreditRating.EXCELLENT"
+ " END from CompUser e1"
+ " where e.userid = e1.userid) ORDER BY e.age";
CriteriaQuery q = cb.create();

View File

@ -193,8 +193,8 @@ public class TestTypesafeCriteria extends CriteriaTest {
Join<Customer, Order> order = cust.join(Customer_.orders);
Join<Order, LineItem> item = order.join(Order_.lineItems);
c.select(cust.get(Customer_.name))
.where(cb.equal(item.get(LineItem_.product).
get(Product_.productType), "printer"));
.where(cb.equal(item.get(LineItem_.product)
.get(Product_.productType), "printer"));
assertEquivalence(c, jpql);
}
@ -278,61 +278,60 @@ public class TestTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql);
}
// @AllowFailure(message = "broken")
// public void testExpressionInProjection() {
// String jpql = "SELECT o.quantity, o.totalCost*1.08 AS taxedCost, "
// + "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a"
// + "WHERE a.state = 'CA' AND a.county = 'Santa Clara'";
// CriteriaQuery q = cb.create();
// Root<Customer> cust = q.from(Customer.class);
// Join<Customer, Order> order = cust.join(Customer_.orders);
// Join<Customer, Address> address = cust.join(Customer_.address);
// q.where(cb.equal(address.get(Address_.state), "CA"), cb.equal(address
// .get(Address_.county), "Santa Clara"));
// q.select(order.get(Order_.quantity), cb.prod(order
// .get(Order_.totalCost), 1.08), address.get(Address_.zipCode));
//
// assertEquivalence(q, jpql);
// }
@AllowFailure(message = "broken")
public void testExpressionInProjection() {
String jpql = "SELECT o.quantity, o.totalCost*1.08 AS taxedCost, "
+ "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a"
+ "WHERE a.state = 'CA' AND a.county = 'Santa Clara'";
CriteriaQuery q = cb.create();
Root<Customer> cust = q.from(Customer.class);
Join<Customer, Order> order = cust.join(Customer_.orders);
Join<Customer, Address> address = cust.join(Customer_.address);
q.where(cb.equal(address.get(Address_.state), "CA"), cb.equal(address
.get(Address_.county), "Santa Clara"));
q.select(order.get(Order_.quantity), cb.prod(order
.get(Order_.totalCost), 1.08), address.get(Address_.zipCode));
// @AllowFailure(message =
// "Type expression was working with Fay. Now refactored and broken")
// public void testTypeExpression() {
// String jpql = "SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt";
// CriteriaQuery q = cb.create();
// Root<Employee> emp = q.from(Employee.class);
// q.select(emp.type()).where(cb.notEqual(emp.type(), Exempt.class));
//
// assertEquivalence(q, jpql);
// }
assertEquivalence(q, jpql);
}
// @AllowFailure(message = "Index expression not implemented")
// public void testIndexExpressionAndLietral() {
// String jpql = "SELECT w.name FROM Course c JOIN c.studentWaitList w "
// + "WHERE c.name = 'Calculus' AND INDEX(w) = 0";
// CriteriaQuery q = cb.create();
// Root<Course> course = q.from(Course.class);
// ListJoin<Course, Student> w = course.join(Course_.studentWaitList);
// q.where(cb.equal(course.get(Course_.name), "Calculus"),
// cb.equal(w.index(), 0)).select(w.get(Student_.name));
//
// assertEquivalence(q, jpql);
// }
public void testTypeExpression() {
String jpql = "SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt";
CriteriaQuery q = cb.create();
Root<Employee> emp = q.from(Employee.class);
q.select(emp.type()).where(cb.notEqual(emp.type(), Exempt.class));
// @AllowFailure(message = "SQL for Criteria has extra join")
// public void testAggregateInProjection() {
// String jpql = "SELECT SUM(i.price) FROM Order o JOIN o.lineItems i JOIN "
// + "o.customer c WHERE c.lastName = 'Smith' AND c.firstName = 'John'";
// CriteriaQuery q = cb.create();
// Root<Order> o = q.from(Order.class);
// Join<Order, LineItem> i = o.join(Order_.lineItems);
// Join<Order, Customer> c = o.join(Order_.customer);
// q.where(cb.equal(c.get(Customer_.lastName), "Smith"), cb.equal(c
// .get(Customer_.firstName), "John"));
// q.select(cb.sum(i.get(LineItem_.price)));
//
// assertEquivalence(q, jpql);
// }
assertEquivalence(q, jpql);
}
@AllowFailure(message = "Index expression not implemented")
public void testIndexExpressionAndLietral() {
String jpql = "SELECT w.name FROM Course c JOIN c.studentWaitList w "
+ "WHERE c.name = 'Calculus' AND INDEX(w) = 0";
CriteriaQuery q = cb.create();
Root<Course> course = q.from(Course.class);
ListJoin<Course, Student> w = course.join(Course_.studentWaitList);
q.where(cb.equal(course.get(Course_.name), "Calculus"),
cb.equal(w.index(), 0)).select(w.get(Student_.name));
assertEquivalence(q, jpql);
}
@AllowFailure(message = "SQL for Criteria has extra join")
public void testAggregateInProjection() {
String jpql = "SELECT SUM(i.price) FROM Order o JOIN o.lineItems i " +
"JOIN o.customer c WHERE c.lastName = 'Smith' AND " +
"c.firstName = 'John'";
CriteriaQuery q = cb.create();
Root<Order> o = q.from(Order.class);
Join<Order, LineItem> i = o.join(Order_.lineItems);
Join<Order, Customer> c = o.join(Order_.customer);
q.where(cb.equal(c.get(Customer_.lastName), "Smith"), cb.equal(c
.get(Customer_.firstName), "John"));
q.select(cb.sum(i.get(LineItem_.price)));
assertEquivalence(q, jpql);
}
public void testSizeExpression() {
String jpql = "SELECT SIZE(d.employees) FROM Department d "
@ -365,68 +364,48 @@ public class TestTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql);
}
// @AllowFailure(message = "Extra Joins created")
// public void testExpression1() {
// String jpql = "SELECT o.quantity, o.totalCost*1.08 AS taxedCost, "
// + "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a "
// + "WHERE a.state = 'CA' AND a.county = 'Santa Clara'";
// CriteriaQuery q = cb.create();
// Root<Customer> cust = q.from(Customer.class);
// Join<Customer, Order> order = cust.join(Customer_.orders);
// Join<Customer, Address> address = cust.join(Customer_.address);
// q.where(cb.equal(address.get(Address_.state), "CA"), cb.equal(address
// .get(Address_.county), "Santa Clara"));
// q.select(order.get(Order_.quantity), cb.prod(order
// .get(Order_.totalCost), 1.08), address.get(Address_.zipCode));
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message = "Type expression in projection not implemented")
// public void testExpression2() {
// String jpql = "SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt";
// CriteriaQuery q = cb.create();
// Root<Employee> emp = q.from(Employee.class);
// q.select(emp.type()).where(cb.notEqual(emp.type(), Exempt.class));
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message = "Index expression not implemented")
// public void testExpression3() {
// String jpql = "SELECT w.name FROM Course c JOIN c.studentWaitList w "
// + "WHERE c.name = 'Calculus' AND INDEX(w) = 0";
// CriteriaQuery q = cb.create();
// Root<Course> course = q.from(Course.class);
// ListJoin<Course, Student> w = course.join(Course_.studentWaitList);
// q.where(cb.equal(course.get(Course_.name), "Calculus"),
// cb.equal(w.index(), 0)).select(w.get(Student_.name));
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message = "Generates extra Join")
// public void testExpression4() {
// String jpql = "SELECT SUM(i.price) FROM Order o JOIN o.lineItems i JOIN "
// + "o.customer c WHERE c.lastName = 'Smith' AND c.firstName = 'John'";
// CriteriaQuery q = cb.create();
// Root<Order> o = q.from(Order.class);
// Join<Order, LineItem> i = o.join(Order_.lineItems);
// Join<Order, Customer> c = o.join(Order_.customer);
// q.where(cb.equal(c.get(Customer_.lastName), "Smith"), cb.equal(c
// .get(Customer_.firstName), "John"));
// q.select(cb.sum(i.get(LineItem_.price)));
//
// assertEquivalence(q, jpql);
// }
public void testExpression5() {
String jpql = "SELECT SIZE(d.employees) FROM Department d "
+ "WHERE d.name = 'Sales'";
@AllowFailure(message = "Extra Joins created")
public void testExpression1() {
String jpql = "SELECT o.quantity, o.totalCost*1.08 AS taxedCost, "
+ "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a "
+ "WHERE a.state = 'CA' AND a.county = 'Santa Clara'";
CriteriaQuery q = cb.create();
Root<Department> d = q.from(Department.class);
q.where(cb.equal(d.get(Department_.name), "Sales"));
q.select(cb.size(d.get(Department_.employees)));
Root<Customer> cust = q.from(Customer.class);
Join<Customer, Order> order = cust.join(Customer_.orders);
Join<Customer, Address> address = cust.join(Customer_.address);
q.where(cb.equal(address.get(Address_.state), "CA"), cb.equal(address
.get(Address_.county), "Santa Clara"));
q.select(order.get(Order_.quantity), cb.prod(order
.get(Order_.totalCost), 1.08), address.get(Address_.zipCode));
assertEquivalence(q, jpql);
}
@AllowFailure(message = "Index expression not implemented")
public void testExpression3() {
String jpql = "SELECT w.name FROM Course c JOIN c.studentWaitList w "
+ "WHERE c.name = 'Calculus' AND INDEX(w) = 0";
CriteriaQuery q = cb.create();
Root<Course> course = q.from(Course.class);
ListJoin<Course, Student> w = course.join(Course_.studentWaitList);
q.where(cb.equal(course.get(Course_.name), "Calculus"),
cb.equal(w.index(), 0)).select(w.get(Student_.name));
assertEquivalence(q, jpql);
}
@AllowFailure(message = "Generates extra Join")
public void testExpression4() {
String jpql = "SELECT SUM(i.price) FROM Order o JOIN o.lineItems i " +
"JOIN o.customer c WHERE c.lastName = 'Smith' AND " +
"c.firstName = 'John'";
CriteriaQuery q = cb.create();
Root<Order> o = q.from(Order.class);
Join<Order, LineItem> i = o.join(Order_.lineItems);
Join<Order, Customer> c = o.join(Order_.customer);
q.where(cb.equal(c.get(Customer_.lastName), "Smith"), cb.equal(c
.get(Customer_.firstName), "John"));
q.select(cb.sum(i.get(LineItem_.price)));
assertEquivalence(q, jpql);
}
@ -492,7 +471,6 @@ public class TestTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql);
}
// @AllowFailure(message = "Parameters not implemented")
public void testParameters1() {
String jpql = "SELECT c FROM Customer c Where c.status = :stat";
CriteriaQuery q = cb.create();
@ -527,21 +505,22 @@ public class TestTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql, new Object[] { 1 });
}
// @AllowFailure(message="add QuotedNumbersInQueries=true otherwise " +
// "AbstractExpressionBuilder.convertTypes() compliants")
// public void testParameters4() {
// String jpql = "SELECT c FROM Customer c Where c.status = ?1 AND "
// + "c.name = ?2";
// CriteriaQuery q = cb.create();
// Root<Customer> c = q.from(Customer.class);
// Parameter<Integer> param1 = cb.parameter(Integer.class);
// Parameter<Integer> param2 = cb.parameter(Integer.class);
// q.select(c).where(
// cb.and(cb.equal(c.get(Customer_.status), param1), cb.equal(c
// .get(Customer_.name), param2)));
// assertEquivalence(q, jpql, new Object[] { 1, "test" });
// }
@AllowFailure(message="add QuotedNumbersInQueries=true otherwise " +
"AbstractExpressionBuilder.convertTypes() compliants")
public void testParameters4() {
String jpql = "SELECT c FROM Customer c Where c.status = ?1 AND "
+ "c.name = ?2";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
Parameter<Integer> param1 = cb.parameter(Integer.class);
Parameter<Integer> param2 = cb.parameter(Integer.class);
q.select(c).where(
cb.and(cb.equal(c.get(Customer_.status), param1), cb.equal(c
.get(Customer_.name), param2)));
assertEquivalence(q, jpql, new Object[] { 1, "test" });
}
@AllowFailure(message = "Criteria API does not allow collection parameter")
public void testParameters5() {
String jpql = "SELECT c FROM Customer c Where c.status IN (:coll)";
CriteriaQuery q = cb.create();
@ -551,143 +530,172 @@ public class TestTypesafeCriteria extends CriteriaTest {
List vals = new ArrayList();
vals.add(1);
vals.add(2);
// assertEquivalence(q, jpql, new String[] {"coll"}, new Object[]
// {vals});
assertEquivalence(q, jpql, new String[] {"coll"},
new Object[] {vals});
}
// @AllowFailure(message="Value() expression not implemented")
// public void testSelectList1() {
// String jpql = "SELECT v.location.street, KEY(i).title, VALUE(i) FROM "
// + "VideoStore v JOIN v.videoInventory i WHERE v.location.zipCode = "
// + "'94301' AND VALUE(i) > 0";
// CriteriaQuery q = cb.create();
// Root<VideoStore> v = q.from(VideoStore.class);
// MapJoin<VideoStore, Movie, Integer> inv = v
// .join(VideoStore_.videoInventory);
// q.where(cb.equal(v.get(VideoStore_.location).get(Address_.zipCode),
// "94301"), cb.gt(inv.value(), 0));
// q.select(v.get(VideoStore_.location).get(Address_.street), inv.key()
// .get(Movie_.title), inv.value());
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="new() in projection is broken")
// public void testSelectList2() {
// String jpql =
// "SELECT NEW CustomerDetails(c.id, c.status, o.quantity) FROM "
// + "Customer c JOIN c.orders o WHERE o.quantity > 100";
// CriteriaQuery q = cb.create();
// Root<Customer> c = q.from(Customer.class);
// Join<Customer, Order> o = c.join(Customer_.orders);
// q.where(cb.gt(o.get(Order_.quantity), 100));
// q.select(cb.select(CustomerDetails.class, c.get(Customer_.id), c
// .get(Customer_.status), o.get(Order_.quantity)));
//
// assertEquivalence(q, jpql);
// }
@AllowFailure(message="Value() expression not implemented")
public void testSelectList1() {
String jpql = "SELECT v.location.street, KEY(i).title, VALUE(i) FROM "
+ "VideoStore v JOIN v.videoInventory i WHERE v.location.zipCode = "
+ "'94301' AND VALUE(i) > 0";
CriteriaQuery q = cb.create();
Root<VideoStore> v = q.from(VideoStore.class);
MapJoin<VideoStore, Movie, Integer> inv = v
.join(VideoStore_.videoInventory);
q.where(cb.equal(v.get(VideoStore_.location).get(Address_.zipCode),
"94301"), cb.gt(inv.value(), 0));
q.select(v.get(VideoStore_.location).get(Address_.street), inv.key()
.get(Movie_.title), inv.value());
// @AllowFailure(message="Subqueries not implemented")
// public void testSubqueries1() {
// String jpql = "SELECT goodCustomer FROM Customer goodCustomer WHERE "
// + "goodCustomer.balanceOwed < (SELECT AVG(c.balanceOwed) "
// + " FROM "
// + "Customer c)";
// CriteriaQuery q = cb.create();
// Root<Customer> goodCustomer = q.from(Customer.class);
// Subquery<Double> sq = q.subquery(Double.class);
// Root<Customer> c = sq.from(Customer.class);
// q.where(cb.lt(goodCustomer.get(Customer_.balanceOwed), sq.select(cb
// .avg(c.get(Customer_.balanceOwed)))));
// q.select(goodCustomer);
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="Subqueries not implemented")
// public void testSubqueries2() {
// String jpql = "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ("
// + "SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp ="
// + " emp.spouse)";
// CriteriaQuery q = cb.create();
// Root<Employee> emp = q.from(Employee.class);
// Subquery<Employee> sq = q.subquery(Employee.class);
// Root<Employee> spouseEmp = sq.from(Employee.class);
// sq.select(spouseEmp);
// sq.where(cb.equal(spouseEmp, emp.get(Employee_.spouse)));
// q.where(cb.exists(sq));
// q.select(emp).distinct(true);
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="Subqueries not implemented")
// public void testSubqueries3() {
// String jpql = "SELECT emp FROM Employee emp WHERE emp.salary > ALL ("
// + "SELECT m.salary FROM Manager m WHERE m.department = "
// + "emp.department)";
// CriteriaQuery q = cb.create();
// Root<Employee> emp = q.from(Employee.class);
// q.select(emp);
// Subquery<BigDecimal> sq = q.subquery(BigDecimal.class);
// Root<Manager> m = sq.from(Manager.class);
// sq.select(m.get(Manager_.salary));
// sq.where(cb.equal(m.get(Manager_.department), emp
// .get(Employee_.department)));
// q.where(cb.gt(emp.get(Employee_.salary), cb.all(sq)));
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="Subqueries not implemented")
// public void testSubqueries4() {
// String jpql = "SELECT c FROM Customer c WHERE "
// + "(SELECT COUNT(o) FROM c.orders o) > 10";
// CriteriaQuery q = cb.create();
// Root<Customer> c1 = q.from(Customer.class);
// q.select(c1);
// Subquery<Long> sq3 = q.subquery(Long.class);
// Root<Customer> c2 = sq3.correlate(c1);
// Join<Customer, Order> o = c2.join(Customer_.orders);
// q.where(cb.gt(sq3.select(cb.count(o)), 10));
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="Subqueries not implemented")
// public void testSubqueries5() {
// String jpql = "SELECT o FROM Order o WHERE 10000 < ALL ("
// + "SELECT a.balance FROM o.customer c JOIN c.accounts a)";
// CriteriaQuery q = cb.create();
// Root<Order> o = q.from(Order.class);
// q.select(o);
// Subquery<Integer> sq = q.subquery(Integer.class);
// Root<Order> osq = sq.correlate(o);
// Join<Order, Customer> c = osq.join(Order_.customer);
// Join<Customer, Account> a = c.join(Customer_.accounts);
// sq.select(a.get(Account_.balance));
// q.where(cb.lt(cb.literal(10000), cb.all(sq)));
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="Subqueries not implemented")
// public void testSubqueries6() {
// String jpql = "SELECT o FROM Order o JOIN o.customer c WHERE 10000 < "
// + "ALL (SELECT a.balance FROM c.accounts a)";
// CriteriaQuery q = cb.create();
// Root<Order> o = q.from(Order.class);
// q.select(o);
// Join<Order, Customer> c = o.join(Order_.customer);
// Subquery<Integer> sq = q.subquery(Integer.class);
// Join<Order, Customer> csq = sq.correlate(c);
// Join<Customer, Account> a = csq.join(Customer_.accounts);
// sq.select(a.get(Account_.balance));
// q.where(cb.lt(cb.literal(10000), cb.all(sq)));
//
// assertEquivalence(q, jpql);
// }
assertEquivalence(q, jpql);
}
public void testNewConstruct() {
String jpql = "SELECT NEW CustomerDetails(c.id, c.status) FROM "
+ "Customer c";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
q.select(cb.select(CustomerDetails.class, c.get(Customer_.id),
c.get(Customer_.status))
);
assertEquivalence(q, jpql);
}
@AllowFailure(message="new() in projection with join is broken")
public void testNewConstruct1() {
String jpql =
"SELECT NEW CustomerDetails(c.id, c.status, o.quantity) FROM "
+ "Customer c JOIN c.orders o WHERE o.quantity > 100";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders);
q.where(cb.gt(o.get(Order_.quantity), 100));
q.select(cb.select(CustomerDetails.class, c.get(Customer_.id), c
.get(Customer_.status), o.get(Order_.quantity)));
assertEquivalence(q, jpql);
}
@AllowFailure(message="JPQL does not support multiple constructors")
public void testNewConstruct2() {
String jpql = "SELECT NEW CustomerDetails(c.id, c.status), " +
"NEW CustomerFullName(c.firstName, c.lastName) FROM "
+ "Customer c";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
q.select(cb.select(CustomerDetails.class, c.get(Customer_.id),
c.get(Customer_.status)),
cb.select(CustomerFullName.class, c.get(Customer_.firstName),
c.get(Customer_.lastName))
);
assertEquivalence(q, jpql);
}
public void testSubqueries1() {
String jpql = "SELECT goodCustomer FROM Customer goodCustomer WHERE "
+ "goodCustomer.balanceOwed < (SELECT AVG(c.balanceOwed) "
+ " FROM "
+ "Customer c)";
CriteriaQuery q = cb.create();
Root<Customer> goodCustomer = q.from(Customer.class);
Subquery<Double> sq = q.subquery(Double.class);
Root<Customer> c = sq.from(Customer.class);
q.where(cb.lt(goodCustomer.get(Customer_.balanceOwed), sq.select(cb
.avg(c.get(Customer_.balanceOwed)))));
q.select(goodCustomer);
assertEquivalence(q, jpql);
}
@AllowFailure(message="SQL is incorrect for JPQL, correct for Criteria")
public void testSubqueries2() {
String jpql = "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ("
+ "SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp ="
+ " emp.spouse)";
CriteriaQuery q = cb.create();
Root<Employee> emp = q.from(Employee.class);
Subquery<Employee> sq = q.subquery(Employee.class);
Root<Employee> spouseEmp = sq.from(Employee.class);
sq.select(spouseEmp);
sq.where(cb.equal(spouseEmp, emp.get(Employee_.spouse)));
q.where(cb.exists(sq));
q.select(emp).distinct(true);
assertEquivalence(q, jpql);
}
public void testSubqueries3() {
String jpql = "SELECT emp FROM Employee emp WHERE emp.salary > ALL ("
+ "SELECT m.salary FROM Manager m WHERE m.department = "
+ "emp.department)";
CriteriaQuery q = cb.create();
Root<Employee> emp = q.from(Employee.class);
q.select(emp);
Subquery<BigDecimal> sq = q.subquery(BigDecimal.class);
Root<Manager> m = sq.from(Manager.class);
sq.select(m.get(Manager_.salary));
sq.where(cb.equal(m.get(Manager_.department), emp
.get(Employee_.department)));
q.where(cb.gt(emp.get(Employee_.salary), cb.all(sq)));
assertEquivalence(q, jpql);
}
@AllowFailure(message="SQL is incorrect for JPQL, correct for " +
"Criteria is correct with redundant outer joins")
public void testSubqueries4() {
String jpql = "SELECT c FROM Customer c WHERE "
+ "(SELECT COUNT(o) FROM c.orders o) > 10";
CriteriaQuery q = cb.create();
Root<Customer> c1 = q.from(Customer.class);
q.select(c1);
Subquery<Long> sq3 = q.subquery(Long.class);
Root<Customer> c2 = sq3.correlate(c1);
Join<Customer, Order> o = c2.join(Customer_.orders);
q.where(cb.gt(sq3.select(cb.count(o)), 10));
assertEquivalence(q, jpql);
}
@AllowFailure(message="Subqueries not implemented")
public void testSubqueries5() {
String jpql = "SELECT o FROM Order o WHERE 10000 < ALL ("
+ "SELECT a.balance FROM o.customer c JOIN c.accounts a)";
CriteriaQuery q = cb.create();
Root<Order> o = q.from(Order.class);
q.select(o);
Subquery<Integer> sq = q.subquery(Integer.class);
Root<Order> osq = sq.correlate(o);
Join<Order, Customer> c = osq.join(Order_.customer);
Join<Customer, Account> a = c.join(Customer_.accounts);
sq.select(a.get(Account_.balance));
q.where(cb.lt(cb.literal(10000), cb.all(sq)));
assertEquivalence(q, jpql);
}
@AllowFailure(message="Subqueries not implemented")
public void testSubqueries6() {
String jpql = "SELECT o FROM Order o JOIN o.customer c WHERE 10000 < "
+ "ALL (SELECT a.balance FROM c.accounts a)";
CriteriaQuery q = cb.create();
Root<Order> o = q.from(Order.class);
q.select(o);
Join<Order, Customer> c = o.join(Order_.customer);
Subquery<Integer> sq = q.subquery(Integer.class);
Join<Order, Customer> csq = sq.correlate(c);
Join<Customer, Account> a = csq.join(Customer_.accounts);
sq.select(a.get(Account_.balance));
q.where(cb.lt(cb.literal(10000), cb.all(sq)));
assertEquivalence(q, jpql);
}
public void testGroupByAndHaving() {
String jpql = "SELECT c.status, AVG(c.filledOrderCount), COUNT(c) FROM "
@ -702,137 +710,84 @@ public class TestTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql);
}
// @AllowFailure(message="AbstractExpressionExecutor.assertNotContainer()
// not happy")
// public void testOrdering() {
// String jpql = "SELECT c FROM Customer c JOIN c.orders o "
// + "JOIN c.address a WHERE a.state = 'CA' ORDER BY o.quantity DESC, "
// + "o.totalCost";
// CriteriaQuery q = cb.create();
// Root<Customer> c = q.from(Customer.class);
// Join<Customer, Order> o = c.join(Customer_.orders);
// Join<Customer, Address> a = c.join(Customer_.address);
// q.where(cb.equal(a.get(Address_.state), "CA"));
// q.orderBy(cb.desc(o.get(Order_.quantity)), cb.asc(o
// .get(Order_.totalCost)));
// q.select(o);
//
// assertEquivalence(q, jpql);
//
// jpql = "SELECT o.quantity, a.zipCode FROM Customer c JOIN c.orders "
// + "JOIN c.address a WHERE a.state = 'CA' ORDER BY o.quantity, "
// + "a.zipCode";
// q = cb.create();
// Root<Customer> c1 = q.from(Customer.class);
// Join<Customer, Order> o1 = c1.join(Customer_.orders);
// Join<Customer, Address> a1 = c1.join(Customer_.address);
// q.where(cb.equal(a1.get(Address_.state), "CA"));
// q.orderBy(cb.asc(o1.get(Order_.quantity)), cb.asc(a1
// .get(Address_.zipCode)));
// q.select(o1.get(Order_.quantity), a1.get(Address_.zipCode));
//
// assertEquivalence(q, jpql);
//
// jpql = "SELECT o.quantity, o.cost * 1.08 AS taxedCost, a.zipCode "
// + "FROM Customer c JOIN c.orders o JOIN c.address a "
// + "WHERE a.state = 'CA' AND a.county = 'Santa Clara' "
// + "ORDER BY o.quantity, taxedCost, a.zipCode";
// q = cb.create();
// Root<Customer> c2 = q.from(Customer.class);
// Join<Customer, Order> o2 = c2.join(Customer_.orders);
// Join<Customer, Address> a2 = c2.join(Customer_.address);
// q.where(cb.equal(a.get(Address_.state), "CA"), cb.equal(a
// .get(Address_.county), "Santa Clara"));
// q.orderBy(cb.asc(o.get(Order_.quantity)), cb.asc(cb.prod(
// o.get(Order_.totalCost), 1.08)),
// cb.asc(a.get(Address_.zipCode)));
// q.select(o.get(Order_.quantity), cb.prod(
// o.get(Order_.totalCost), 1.08), a.get(Address_.zipCode));
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="AbstractExpressionExecutor.assertNotContainer()"+
// "not happy")
// public void testOrdering1() {
// String jpql = "SELECT o FROM Customer c JOIN c.orders o "
// + "JOIN c.address a WHERE a.state = 'CA' ORDER BY o.quantity DESC, "
// + "o.totalCost";
// CriteriaQuery q = cb.create();
// Root<Customer> c = q.from(Customer.class);
// Join<Customer, Order> o = c.join(Customer_.orders);
// Join<Customer, Address> a = c.join(Customer_.address);
// q.where(cb.equal(a.get(Address_.state), "CA"));
// q.orderBy(cb.desc(o.get(Order_.quantity)), cb.asc(o
// .get(Order_.totalCost)));
// q.select(o);
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="The JPQL is broken!")
// public void testOrdering2() {
// String jpql = "SELECT o.quantity, a.zipCode FROM Customer c "
// + "JOIN c.orders JOIN c.address a WHERE a.state = 'CA' "
// + "ORDER BY o.quantity, a.zipCode";
// CriteriaQuery q = cb.create();
// Root<Customer> c = q.from(Customer.class);
// Join<Customer, Order> o = c.join(Customer_.orders);
// Join<Customer, Address> a = c.join(Customer_.address);
// q.where(cb.equal(a.get(Address_.state), "CA"));
// q.orderBy(cb.asc(o.get(Order_.quantity)), cb.asc(a
// .get(Address_.zipCode)));
// q.select(o.get(Order_.quantity), a.get(Address_.zipCode));
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="QueryExpression.ordering not initialized")
// public void testOrdering3() {
// String jpql = "SELECT o.quantity, o.totalCost * 1.08 AS taxedCost, "
// + "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a "
// + "WHERE a.state = 'CA' AND a.county = 'Santa Clara' "
// + "ORDER BY o.quantity, taxedCost, a.zipCode";
// CriteriaQuery q = cb.create();
// Root<Customer> c = q.from(Customer.class);
// Join<Customer, Order> o = c.join(Customer_.orders);
// Join<Customer, Address> a = c.join(Customer_.address);
// q.where(cb.equal(a.get(Address_.state), "CA"), cb.equal(a
// .get(Address_.county), "Santa Clara"));
// q.orderBy(cb.asc(o.get(Order_.quantity)), cb.asc(cb.prod(
// o.get(Order_.totalCost), 1.08)),
// cb.asc(a.get(Address_.zipCode)));
// q.select(o.get(Order_.quantity), cb.prod(
// o.get(Order_.totalCost), 1.08), a.get(Address_.zipCode));
//
// assertEquivalence(q, jpql);
// }
//
//
// @AllowFailure(message="QueryExpression.ordering not initialized")
// public void testOrdering4() {
// String jpql = "SELECT c FROM Customer c "
// + "ORDER BY c.name DESC, c.status";
// CriteriaQuery q = cb.create();
// Root<Customer> c = q.from(Customer.class);
// q.orderBy(cb.desc(c.get(Customer_.name)), cb.asc(c
// .get(Customer_.status)));
// q.select(c);
//
// assertEquivalence(q, jpql);
// }
//
// @AllowFailure(message="QueryExpression.ordering not initialized")
// public void testOrdering5() {
// String jpql = "SELECT c.firstName, c.lastName, c.balanceOwed "
// + "FROM Customer c ORDER BY c.name DESC, c.status";
// CriteriaQuery q = cb.create();
// Root<Customer> c = q.from(Customer.class);
// q.orderBy(cb.desc(c.get(Customer_.name)), cb.asc(c
// .get(Customer_.status)));
// q.select(c.get(Customer_.firstName), c.get(Customer_.lastName), c
// .get(Customer_.balanceOwed));
//
// assertEquivalence(q, jpql);
// }
@AllowFailure(message="AbstractExpressionExecutor.assertNotContainer()"+
"not happy")
public void testOrdering1() {
String jpql = "SELECT o FROM Customer c JOIN c.orders o "
+ "JOIN c.address a WHERE a.state = 'CA' ORDER BY o.quantity DESC, "
+ "o.totalCost";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders);
Join<Customer, Address> a = c.join(Customer_.address);
q.where(cb.equal(a.get(Address_.state), "CA"));
q.orderBy(cb.desc(o.get(Order_.quantity)), cb.asc(o
.get(Order_.totalCost)));
q.select(o);
assertEquivalence(q, jpql);
}
@AllowFailure
public void testOrdering2() {
String jpql = "SELECT o.quantity, a.zipCode FROM Customer c "
+ "JOIN c.orders o JOIN c.address a WHERE a.state = 'CA' "
+ "ORDER BY o.quantity, a.zipCode";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders);
Join<Customer, Address> a = c.join(Customer_.address);
q.where(cb.equal(a.get(Address_.state), "CA"));
q.orderBy(cb.asc(o.get(Order_.quantity)), cb.asc(a
.get(Address_.zipCode)));
q.select(o.get(Order_.quantity), a.get(Address_.zipCode));
assertEquivalence(q, jpql);
}
@AllowFailure
public void testOrdering3() {
String jpql = "SELECT o.quantity, o.totalCost * 1.08 AS taxedCost, "
+ "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a "
+ "WHERE a.state = 'CA' AND a.county = 'Santa Clara' "
+ "ORDER BY o.quantity, taxedCost, a.zipCode";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders);
Join<Customer, Address> a = c.join(Customer_.address);
q.where(cb.equal(a.get(Address_.state), "CA"), cb.equal(a
.get(Address_.county), "Santa Clara"));
q.orderBy(cb.asc(o.get(Order_.quantity)), cb.asc(cb.prod(
o.get(Order_.totalCost), 1.08)),
cb.asc(a.get(Address_.zipCode)));
q.select(o.get(Order_.quantity), cb.prod(
o.get(Order_.totalCost), 1.08), a.get(Address_.zipCode));
assertEquivalence(q, jpql);
}
public void testOrdering4() {
String jpql = "SELECT c FROM Customer c "
+ "ORDER BY c.name DESC, c.status";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
q.orderBy(cb.desc(c.get(Customer_.name)), cb.asc(c
.get(Customer_.status)));
q.select(c);
assertEquivalence(q, jpql);
}
public void testOrdering5() {
String jpql = "SELECT c.firstName, c.lastName, c.balanceOwed "
+ "FROM Customer c ORDER BY c.name DESC, c.status";
CriteriaQuery q = cb.create();
Root<Customer> c = q.from(Customer.class);
q.orderBy(cb.desc(c.get(Customer_.name)), cb.asc(c
.get(Customer_.status)));
q.select(c.get(Customer_.firstName), c.get(Customer_.lastName), c
.get(Customer_.balanceOwed));
assertEquivalence(q, jpql);
}
}

View File

@ -96,7 +96,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
}
public <Y> Expression<Y> all(Subquery<Y> subquery) {
throw new AbstractMethodError();
return new Expressions.All<Y>(subquery);
}
public Predicate and(Predicate... restrictions) {
@ -108,7 +108,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
}
public <Y> Expression<Y> any(Subquery<Y> subquery) {
throw new AbstractMethodError();
return new Expressions.Any<Y>(subquery);
}
public Order asc(Expression<?> x) {
@ -208,15 +208,19 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
}
public Predicate equal(Expression<?> x, Expression<?> y) {
if (y == null)
return new Expressions.IsNull((ExpressionImpl<?> )x);
return new Expressions.Equal(x, y);
}
public Predicate equal(Expression<?> x, Object y) {
if (y == null)
return new Expressions.IsNull((ExpressionImpl<?> )x);
return new Expressions.Equal(x, y);
}
public Predicate exists(Subquery<?> subquery) {
throw new AbstractMethodError();
return new Expressions.Exists(subquery);
}
public <T> Expression<T> function(String name, Class<T> type,
@ -326,7 +330,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
}
public Expression<Integer> length(Expression<String> x) {
throw new AbstractMethodError();
return new Expressions.Length(x);
}
@ -385,29 +389,29 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
public Expression<Integer> locate(Expression<String> x,
Expression<String> pattern) {
throw new AbstractMethodError();
return new Expressions.Locate(x, pattern);
}
public Expression<Integer> locate(Expression<String> x, String pattern) {
throw new AbstractMethodError();
return new Expressions.Locate(x, pattern);
}
public Expression<Integer> locate(Expression<String> x,
Expression<String> pattern, Expression<Integer> from) {
throw new AbstractMethodError();
return new Expressions.Locate(x, pattern, from);
}
public Expression<Integer> locate(Expression<String> x, String pattern,
int from) {
throw new AbstractMethodError();
return new Expressions.Locate(x, pattern, from);
}
public Expression<String> lower(Expression<String> x) {
throw new AbstractMethodError();
return new Expressions.Lower(x);
}
@ -486,12 +490,12 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
}
public <Y> Expression<Y> nullif(Expression<Y> x, Expression<?> y) {
throw new AbstractMethodError();
return new Expressions.Nullif(x, y);
}
public <Y> Expression<Y> nullif(Expression<Y> x, Y y) {
throw new AbstractMethodError();
return new Expressions.Nullif(x, y);
}
@ -563,7 +567,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
}
public <Y> Expression<Y> some(Subquery<Y> subquery) {
throw new AbstractMethodError();
return new Expressions.Some<Y>(subquery);
}
public Expression<Double> sqrt(Expression<? extends Number> x) {
@ -572,7 +576,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
public Expression<String> substring(Expression<String> x,
Expression<Integer> from) {
return new Expressions.Substring(x);
return new Expressions.Substring(x, from);
}
public Expression<String> substring(Expression<String> x, int from) {
@ -665,7 +669,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
}
public Expression<String> upper(Expression<String> x) {
throw new AbstractMethodError();
return new Expressions.Upper(x);
}

View File

@ -0,0 +1,235 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.criteria;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.QueryExpressions;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.meta.Types;
/**
* Subquery is an expression as its selection item.
*
*/
public class CriteriaExpressionBuilder {
private int aliasCount = 0;
private CriteriaQueryImpl criteriaQuery = null;
public CriteriaExpressionBuilder(CriteriaQueryImpl criteriaQuery) {
this.criteriaQuery = criteriaQuery;
}
public QueryExpressions getQueryExpressions(ExpressionFactory factory,
CriteriaQueryImpl q) {
QueryExpressions exps = new QueryExpressions();
evalAccessPaths(exps, factory, q);
//exps.alias = null; // String
exps.ascending = new boolean[]{false};
evalDistinct(exps, factory, q);
evalFetchJoin(exps, factory, q);
evalFilter(exps, factory, q);
evalGrouping(exps, factory, q);
evalOrdering(exps, factory, q);
//exps.operation = QueryOperations.OP_SELECT;
evalProjections(exps, factory, q);
//exps.range = null; // Value[]
//exps.resultClass = null; // Class
if (q.getParameterTypes() != null)
exps.parameterTypes = q.getParameterTypes();
return exps;
}
protected void evalAccessPaths(QueryExpressions exps,
ExpressionFactory factory, CriteriaQueryImpl q) {
Set<Root<?>> roots = q.getRoots();
if (roots != null) {
exps.accessPath = new ClassMetaData[roots.size()];
int i = 0;
for (Root<?> r : roots)
exps.accessPath[i++] = ((Types.Managed<?>)r.getModel()).meta;
}
}
protected void evalOrdering(QueryExpressions exps,
ExpressionFactory factory, CriteriaQueryImpl q) {
List<Order> orders = q.getOrderList();
MetamodelImpl model = q.getMetamodel();
if (orders == null)
return;
int ordercount = orders.size();
exps.ordering = new Value[ordercount];
exps.orderingClauses = new String[ordercount];
exps.orderingAliases = new String[ordercount];
exps.ascending = new boolean[ordercount];
for (int i = 0; i < ordercount; i++) {
OrderImpl order = (OrderImpl)orders.get(i);
//Expression<? extends Comparable> expr = order.getExpression();
Expression expr = order.getExpression5();
exps.ordering[i] = Expressions.toValue(
(ExpressionImpl<?>)expr, factory, model, q);
//exps.orderingClauses[i] = assemble(firstChild);
//exps.orderingAliases[i] = firstChild.text;
exps.ascending[i] = order.isAscending();
}
}
protected void evalGrouping(QueryExpressions exps,
ExpressionFactory factory, CriteriaQueryImpl q) {
// exps.grouping = null; // Value[]
// exps.groupingClauses = null; // String[]
List<Expression<?>> groups = q.getGroupList();
MetamodelImpl model = q.getMetamodel();
PredicateImpl having = q.getGroupRestriction();
if (groups == null)
return;
int groupByCount = groups.size();
exps.grouping = new Value[groupByCount];
for (int i = 0; i < groupByCount; i++) {
Expression<?> groupBy = groups.get(i);
exps.grouping[i] = Expressions.toValue(
(ExpressionImpl<?>)groupBy, factory, model, q);;
}
exps.having = having == null ? factory.emptyExpression()
: having.toKernelExpression(factory, model, q);
}
protected void evalDistinct(QueryExpressions exps,
ExpressionFactory factory, CriteriaQueryImpl q) {
Boolean distinct = q.getDistinct();
if (distinct == null) {
exps.distinct = QueryExpressions.DISTINCT_FALSE;
} else if (distinct) {
exps.distinct = QueryExpressions.DISTINCT_TRUE
| QueryExpressions.DISTINCT_AUTO;
}
//exps.distinct &= ~QueryExpressions.DISTINCT_AUTO;
}
protected void evalFilter(QueryExpressions exps, ExpressionFactory factory,
CriteriaQueryImpl q) {
Set<Root<?>> roots = q.getRoots();
MetamodelImpl model = q.getMetamodel();
PredicateImpl where = q.getRestriction();
q.assertRoot();
org.apache.openjpa.kernel.exps.Expression filter = null;
for (Root<?> root : roots) {
if (root.getJoins() != null) {
for (Join<?, ?> join : root.getJoins()) {
filter = and(factory, ((ExpressionImpl<?>)join)
.toKernelExpression(factory, model, q), filter);
}
}
if (((RootImpl<?>)root).getCorrelatedParent() != null) {
filter = and(factory, ((RootImpl<?>)root)
.toKernelExpression(factory, model, q), filter);
}
}
if (where != null) {
filter = and(factory, where.toKernelExpression
(factory, model, q), filter);
}
if (filter == null)
filter = factory.emptyExpression();
exps.filter = filter;
}
protected void evalProjections(QueryExpressions exps,
ExpressionFactory factory, CriteriaQueryImpl q) {
List<Selection<?>> selections = q.getSelectionList();
MetamodelImpl model = q.getMetamodel();
// TODO: fill in projection clauses
// exps.projectionClauses = null; // String[]
if (isDefaultProjection(selections, q)) {
exps.projections = new Value[0];
return ;
}
exps.projections = new Value[selections.size()];
List<Value> projections = new ArrayList<Value>();
List<String> aliases = new ArrayList<String>();
getProjections(exps, selections, projections, aliases, factory, q,
model);
exps.projections = projections.toArray(new Value[0]);
exps.projectionAliases = aliases.toArray(new String[0]);
}
private void getProjections(QueryExpressions exps,
List<Selection<?>> selections, List projections, List aliases,
ExpressionFactory factory, CriteriaQueryImpl q, MetamodelImpl model) {
for (Selection<?> s : selections) {
List<Selection<?>> sels = ((SelectionImpl)s).getSelections();
if (sels == null) {
projections.add(((ExpressionImpl<?>)s).
toValue(factory, model, q));
aliases.add(nextAlias());
} else {
// this is for constructor expression in the selection
exps.resultClass = s.getJavaType();
getProjections(exps, sels, projections, aliases, factory, q,
model);
}
}
}
protected boolean isDefaultProjection(List<Selection<?>> selections,
CriteriaQueryImpl q) {
return selections == null
|| (selections.size() == 1 && selections.get(0) == q.getRoot());
}
protected void evalFetchJoin(QueryExpressions exps,
ExpressionFactory factory, CriteriaQueryImpl q) {
//exps.fetchInnerPaths = null; // String[]
//exps.fetchPaths = null; // String[]
}
protected org.apache.openjpa.kernel.exps.Expression and (
ExpressionFactory factory,
org.apache.openjpa.kernel.exps.Expression e1,
org.apache.openjpa.kernel.exps.Expression e2) {
return e1 == null ? e2 : e2 == null ? e1 : factory.and(e1, e2);
}
protected String nextAlias() {
return "jpqlalias" + (++aliasCount);
}
}

View File

@ -20,7 +20,6 @@ package org.apache.openjpa.persistence.criteria;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@ -28,7 +27,6 @@ import java.util.Set;
import javax.persistence.Parameter;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
@ -37,14 +35,8 @@ import javax.persistence.criteria.Subquery;
import javax.persistence.metamodel.Entity;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Path;
import org.apache.openjpa.kernel.exps.QueryExpressions;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.persistence.meta.Members;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.meta.Types;
@ -69,16 +61,28 @@ public class CriteriaQueryImpl implements CriteriaQuery {
private List<Selection<?>> _selections;
private List<Expression<?>> _groups;
private PredicateImpl _having;
private List<Subquery<?>> _subqueries;
private Boolean _distinct;
private LinkedMap _parameterTypes;
private Class _resultClass;
private Value[] _projections;
private int _aliasCount = 0;
private CriteriaExpressionBuilder _exprBuilder;
private SubqueryImpl _context;
public CriteriaQueryImpl(MetamodelImpl model) {
this._model = model;
}
public void setContext(SubqueryImpl context) {
_context = context;
}
public SubqueryImpl getContext() {
return _context;
}
public MetamodelImpl getMetamodel() {
return _model;
}
public CriteriaQuery distinct(boolean distinct) {
_distinct = distinct;
return this;
@ -154,7 +158,7 @@ public class CriteriaQueryImpl implements CriteriaQuery {
return _groups;
}
public Predicate getGroupRestriction() {
public PredicateImpl getGroupRestriction() {
return _having;
}
@ -166,6 +170,10 @@ public class CriteriaQueryImpl implements CriteriaQuery {
return _roots;
}
public void setRoots (Set<Root<?>> roots) {
this._roots = roots;
}
public Root<?> getRoot() {
assertRoot();
return _roots.iterator().next();
@ -175,9 +183,16 @@ public class CriteriaQueryImpl implements CriteriaQuery {
return _distinct;
}
public Boolean getDistinct() {
return _distinct;
}
public <U> Subquery<U> subquery(Class<U> type) {
// TODO Auto-generated method stub
return null;
if (_subqueries == null)
_subqueries = new ArrayList<Subquery<?>>();
Subquery<U> subquery = new SubqueryImpl(type, this);
_subqueries.add(subquery);
return subquery;
}
public LinkedMap getParameterTypes() {
@ -188,12 +203,8 @@ public class CriteriaQueryImpl implements CriteriaQuery {
_parameterTypes = parameterTypes;
}
public void setResultClass(Class resultClass) {
_resultClass = resultClass;
}
public void setProjections(Value[] projections) {
_projections = projections;
public CriteriaExpressionBuilder getExprBuilder() {
return _exprBuilder;
}
/**
@ -201,242 +212,12 @@ public class CriteriaQueryImpl implements CriteriaQuery {
* receiver with the help of the given {@link ExpressionFactory}.
*/
QueryExpressions getQueryExpressions(ExpressionFactory factory) {
QueryExpressions exps = new QueryExpressions();
evalAccessPaths(exps, factory);
// exps.alias = null; // String
exps.ascending = new boolean[]{false};
evalDistinct(exps, factory);
evalFetchJoin(exps, factory);
evalFilter(exps, factory);
evalGrouping(exps, factory);
exps.having = _having == null ? factory.emptyExpression()
: _having.toKernelExpression(factory, _model, this);
evalOrdering(exps, factory);
// exps.operation = QueryOperations.OP_SELECT;
// exps.parameterTypes = null; // LinkedMap<>
evalProjections(exps, factory);
evalProjection(exps, factory);
// exps.range = null; // Value[]
// exps.resultClass = null; // Class
if (_parameterTypes != null)
exps.parameterTypes = _parameterTypes;
exps.resultClass = _resultClass;
return exps;
_exprBuilder = new CriteriaExpressionBuilder(this);
return _exprBuilder.getQueryExpressions(factory, this);
}
void evalAccessPaths(QueryExpressions exps, ExpressionFactory factory) {
if (_roots != null) {
exps.accessPath = new ClassMetaData[_roots.size()];
int i = 0;
for (Root<?> r : _roots)
exps.accessPath[i++] = ((Types.Managed<?>)r.getModel()).meta;
}
}
void evalOrdering(QueryExpressions exps, ExpressionFactory factory) {
if (_orders == null)
return;
int ordercount = _orders.size();
exps.ordering = new Value[ordercount];
exps.orderingClauses = new String[ordercount];
exps.orderingAliases = new String[ordercount];
exps.ascending = new boolean[ordercount];
for (int i = 0; i < ordercount; i++) {
OrderImpl order = (OrderImpl)_orders.get(i);
//Expression<? extends Comparable> expr = order.getExpression();
Expression expr = order.getExpression5();
exps.ordering[i] = Expressions.toValue(
(ExpressionImpl<?>)expr, factory, _model, this);
//exps.orderingClauses[i] = assemble(firstChild);
//exps.orderingAliases[i] = firstChild.text;
exps.ascending[i] = order.isAscending();
}
}
void evalGrouping(QueryExpressions exps, ExpressionFactory factory) {
// exps.grouping = null; // Value[]
// exps.groupingClauses = null; // String[]
if (_groups == null)
return;
int groupByCount = _groups.size();
exps.grouping = new Value[groupByCount];
for (int i = 0; i < groupByCount; i++) {
Expression<?> groupBy = _groups.get(i);
exps.grouping[i] = Expressions.toValue(
(ExpressionImpl<?>)groupBy, factory, _model, this);;
}
}
void evalProjections(QueryExpressions exps, ExpressionFactory factory) {
// TODO: fill in projection aliases and clauses
// exps.projectionAliases = null; // String[]
// exps.projectionClauses = null; // String[]
if (isDefaultProjection()) {
exps.projections = new Value[0];
return ;
}
exps.projections = new Value[_selections.size()];
int i = 0;
for (Selection<?> s : _selections) {
exps.projections[i++] = ((ExpressionImpl<?>)s)
.toValue(factory, _model, this);
}
return;
}
boolean isDefaultProjection() {
return _selections == null
|| (_selections.size() == 1 && _selections.get(0) == getRoot());
}
void evalDistinct(QueryExpressions exps, ExpressionFactory factory) {
if (_distinct == null) {
exps.distinct = QueryExpressions.DISTINCT_FALSE;
} else if (_distinct) {
exps.distinct = QueryExpressions.DISTINCT_TRUE
| QueryExpressions.DISTINCT_AUTO;
}
exps.distinct &= ~QueryExpressions.DISTINCT_AUTO;
}
void evalFilter(QueryExpressions exps, ExpressionFactory factory) {
assertRoot();
org.apache.openjpa.kernel.exps.Expression filter = null;
for (Root<?> root : _roots) {
if (root.getJoins() != null) {
for (Join<?, ?> join : root.getJoins()) {
filter = and(factory, ((ExpressionImpl<?>)join)
.toKernelExpression(factory, _model, this), filter);
}
}
}
if (_where != null) {
filter = and(factory, _where.toKernelExpression
(factory, _model, this), filter);
}
if (filter == null)
filter = factory.emptyExpression();
exps.filter = filter;
}
void evalProjection(QueryExpressions exps, ExpressionFactory factory) {
Value [] projs = toValues(exps, factory, getSelectionList());
if (projs.length == 1 && projs[0] == null)
exps.projections = _projections;
else
exps.projections = projs;
//exps.projectionClauses = String[];
}
Value[] toValues(QueryExpressions exps, ExpressionFactory factory,
List<Selection<?>> sels) {
if (sels == null || (sels.size() == 1 && sels.get(0) == getRoot()))
return new Value[0];
Value[] result = new Value[sels.size()];
String[] aliases = new String[sels.size()];
int i = 0;
for (Selection<?> s : sels) {
result[i] = ((SelectionImpl<?>)s).toValue(factory, _model,
this);
aliases[i] = nextAlias();
i++;
}
exps.projectionAliases = aliases;
return result;
}
void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory) {
// exps.fetchInnerPaths = null; // String[]
// exps.fetchPaths = null; // String[]
}
org.apache.openjpa.kernel.exps.Expression and(ExpressionFactory factory,
org.apache.openjpa.kernel.exps.Expression e1,
org.apache.openjpa.kernel.exps.Expression e2) {
return e1 == null ? e2 : e2 == null ? e1 : factory.and(e1, e2);
}
void assertRoot() {
public void assertRoot() {
if (_roots == null || _roots.isEmpty())
throw new IllegalStateException("no root is set");
}
void setImplicitTypes(Value val1, Value val2, Class<?> expected) {
Class<?> c1 = (val1 == null ? null : val1.getType());
Class<?> c2 = (val2 == null ? null : val2.getType());
boolean o1 = c1 == AbstractExpressionBuilder.TYPE_OBJECT;
boolean o2 = c2 == AbstractExpressionBuilder.TYPE_OBJECT;
if (o1 && !o2) {
val1.setImplicitType(c2);
if (val1.getMetaData() == null && !val1.isXPath())
val1.setMetaData(val2.getMetaData());
} else if (!o1 && o2) {
val2.setImplicitType(c1);
if (val2.getMetaData() == null && !val1.isXPath())
val2.setMetaData(val1.getMetaData());
} else if (o1 && o2 && expected != null) {
// we never expect a pc type, so don't bother with metadata
val1.setImplicitType(expected);
val2.setImplicitType(expected);
} else if (c1 != null && c2 != null &&
AbstractExpressionBuilder.isNumeric(c1)
!= AbstractExpressionBuilder.isNumeric(c2)) {
AbstractExpressionBuilder.convertTypes(val1, val2);
}
// as well as setting the types for conversions, we also need to
// ensure that any parameters are declared with the correct type,
// since the JPA spec expects that these will be validated
org.apache.openjpa.kernel.exps.Parameter param =
val1 instanceof org.apache.openjpa.kernel.exps.Parameter ?
(org.apache.openjpa.kernel.exps.Parameter) val1
: val2 instanceof org.apache.openjpa.kernel.exps.Parameter ?
(org.apache.openjpa.kernel.exps.Parameter) val2 : null;
Path path = val1 instanceof Path ? (Path) val1
: val2 instanceof Path ? (Path) val2 : null;
// we only check for parameter-to-path comparisons
if (param == null || path == null || _parameterTypes == null)
return;
FieldMetaData fmd = path.last();
if (fmd == null)
return;
//TODO:
//if (expected == null)
// checkEmbeddable(path);
Class<?> type = path.getType();
if (type == null)
return;
Object paramKey = param.getParameterKey();
if (paramKey == null)
return;
// make sure we have already declared the parameter
if (_parameterTypes.containsKey(paramKey))
_parameterTypes.put(paramKey, type);
}
private String nextAlias() {
return "jpqlalias" + (++_aliasCount);
}
}

View File

@ -21,7 +21,6 @@ package org.apache.openjpa.persistence.criteria;
import java.util.Collection;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.QueryBuilder.In;
@ -41,13 +40,13 @@ public abstract class ExpressionImpl<X> extends SelectionImpl<X>
implements Expression<X> {
Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
throw new AbstractMethodError(this.getClass().getName());
}
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
throw new AbstractMethodError(this.getClass().getName());
}

View File

@ -23,22 +23,21 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.QueryBuilder;
import javax.persistence.criteria.Subquery;
import javax.persistence.criteria.QueryBuilder.Trimspec;
import org.apache.openjpa.persistence.meta.Types;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Literal;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.meta.Types;
import serp.util.Numbers;
public class Expressions {
/**
@ -47,10 +46,10 @@ public class Expressions {
* Also sets the alias of the resulting value.
*/
static Value toValue(ExpressionImpl<?> e, ExpressionFactory factory,
MetamodelImpl model, CriteriaQuery q) {
MetamodelImpl model, CriteriaQueryImpl q) {
Value v = e == null ? factory.getNull() : e.toValue(factory, model, q);
v.setImplicitType(e.getJavaType());
v.setAlias(e.getAlias());
//v.setImplicitType(e.getJavaType());
//v.setAlias(e.getAlias());
return v;
}
@ -110,6 +109,11 @@ public class Expressions {
e1 = (ExpressionImpl<?>)x;
e2 = (ExpressionImpl<?>)y;
}
@Override
public PredicateImpl clone() {
return new BinaryLogicalExpression(e1, e2);
}
}
@ -120,7 +124,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.abs(Expressions.toValue(e, factory, model, q));
}
}
@ -139,7 +143,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
Value v = factory.count(Expressions.toValue(e, factory, model, q));
return _distinct ? factory.distinct(v) : v;
}
@ -152,7 +156,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.avg(Expressions.toValue(e, factory, model, q));
}
}
@ -164,7 +168,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.sqrt(Expressions.toValue(e, factory, model, q));
}
}
@ -176,7 +180,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.max(Expressions.toValue(e, factory, model, q));
}
}
@ -188,7 +192,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.min(Expressions.toValue(e, factory, model, q));
}
}
@ -204,7 +208,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.size(Expressions.toValue(e, factory, model, q));
}
}
@ -218,7 +222,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.type(Expressions.toValue(e, factory, model, q));
}
}
@ -231,7 +235,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.cast(Expressions.toValue(e, factory, model, q), b);
}
}
@ -250,7 +254,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.concat(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
@ -268,6 +272,10 @@ public class Expressions {
this.len = (ExpressionImpl<Integer>)len;
}
public Substring(Expression<String> s, Expression<Integer> from) {
this(s, (ExpressionImpl<Integer>)from, null);
}
public Substring(Expression<String> s) {
this(s, (Expression<Integer>)null, (Expression<Integer>)null);
}
@ -282,7 +290,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return JPQLExpressionBuilder.convertSubstringArguments(factory,
Expressions.toValue(e, factory, model, q),
from == null ? null : from.toValue(factory, model, q),
@ -290,6 +298,55 @@ public class Expressions {
}
}
public static class Locate extends ExpressionImpl<Integer> {
private ExpressionImpl<String> pattern;
private ExpressionImpl<Integer> from;
private ExpressionImpl<String> path;
public Locate(Expression<String> x, Expression<String> y,
Expression<Integer> from) {
super(Integer.class);
path = (ExpressionImpl<String>)x;
pattern = (ExpressionImpl<String>)y;
this.from = (ExpressionImpl<Integer>)from;
}
public Locate(Expression<String> x, Expression<String> y) {
this(x, y, null);
}
public Locate(Expression<String> x, String y) {
this(x, new Constant<String>(y), null);
}
public Locate(String x, Expression<String> y) {
this(new Constant<String>(x), y, null);
}
public Locate(Expression<String> x, String y,
int from) {
this(x, new Constant<String>(y), new Constant<Integer>(from));
}
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
Value locateSearch = path.toValue(factory, model, q);
Value locateFromIndex = (from == null ?
null : Expressions.toValue(from, factory, model, q));
Value locatePath = Expressions.toValue(pattern, factory, model, q);
return factory.add(factory.indexOf(locateSearch,
locateFromIndex == null ? locatePath
: factory.newArgumentList(locatePath,
factory.subtract(locateFromIndex,
factory.newLiteral(Numbers.valueOf(1),
Literal.TYPE_NUMBER)))),
factory.newLiteral(Numbers.valueOf(1),
Literal.TYPE_NUMBER));
}
}
public static class Trim extends BinarayFunctionalExpression<String> {
static Expression<Character> defaultTrim = new Constant<Character>
(Character.class, new Character(' '));
@ -323,7 +380,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
Boolean spec = null;
if (ts != null) {
switch (ts) {
@ -338,8 +395,6 @@ public class Expressions {
}
}
public static class Sum<N extends Number>
extends BinarayFunctionalExpression<N> {
public Sum(Expression<? extends Number> x,
@ -351,7 +406,6 @@ public class Expressions {
this(x, (Expression<? extends Number>)null);
}
public Sum(Expression<? extends Number> x, Number y) {
this(x, new Constant<Number>(Number.class, y));
}
@ -362,7 +416,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return (e2 == null)
? factory.sum(Expressions.toValue(e1, factory, model, q))
: factory.add(
@ -388,7 +442,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.multiply(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
@ -412,7 +466,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.subtract(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
@ -437,15 +491,13 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.divide(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
}
}
public static class Mod extends BinarayFunctionalExpression<Integer> {
public Mod(Expression<Integer> x, Expression<Integer> y) {
super(Integer.class, x,y);
@ -459,7 +511,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.mod(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
@ -473,7 +525,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.getCurrentDate();
}
}
@ -485,7 +537,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.getCurrentTime();
}
}
@ -498,13 +550,12 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.getCurrentTimestamp();
}
}
public static class Equal extends BinaryLogicalExpression {
boolean negate;
public <X,Y> Equal(Expression<X> x, Expression<Y> y) {
super(x,y);
}
@ -513,23 +564,20 @@ public class Expressions {
this(x, new Constant<Object>(Object.class, y));
}
@Override
public PredicateImpl clone() {
return new Equal(e1, e2);
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
boolean isTypeExpr = false;
Value val1 = Expressions.toValue(e1, factory, model, q);
Value val2 = Expressions.toValue(e2, factory, model, q);
// if (e1 instanceof TypePathImpl) {
// PathImpl path = (PathImpl)e1;
// isTypeExpr = path.isTypeExpr();
// if (isTypeExpr) {
// ((Constant)e2).setTypeLit(isTypeExpr);
// val2 = Expressions.toValue(e2, factory, model, q);
// Class clzz = (Class)((Literal)val2).getValue();
// val2.setMetaData(((Types.Managed)model.type(clzz)).meta);
// }
// }
((CriteriaQueryImpl)q).setImplicitTypes(val1, val2, null);
JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null,
((CriteriaQueryImpl)q).getParameterTypes(), null);
return isNegated() ? factory.notEqual(val1, val2)
: factory.equal(val1, val2);
}
@ -546,10 +594,13 @@ public class Expressions {
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
return factory.greaterThan(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
Value val1 = Expressions.toValue(e1, factory, model, q);
Value val2 = Expressions.toValue(e2, factory, model, q);
JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null,
((CriteriaQueryImpl)q).getParameterTypes(), null);
return factory.greaterThan(val1, val2);
}
}
@ -564,14 +615,16 @@ public class Expressions {
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
return factory.greaterThanEqual(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
Value val1 = Expressions.toValue(e1, factory, model, q);
Value val2 = Expressions.toValue(e2, factory, model, q);
JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null,
((CriteriaQueryImpl)q).getParameterTypes(), null);
return factory.greaterThanEqual(val1, val2);
}
}
public static class LessThan extends BinaryLogicalExpression {
public <X,Y> LessThan(Expression<X> x, Expression<Y> y) {
super(x,y);
@ -583,10 +636,13 @@ public class Expressions {
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
return factory.lessThan(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
Value val1 = Expressions.toValue(e1, factory, model, q);
Value val2 = Expressions.toValue(e2, factory, model, q);
JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null,
((CriteriaQueryImpl)q).getParameterTypes(), null);
return factory.lessThan(val1, val2);
}
}
@ -601,11 +657,13 @@ public class Expressions {
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
return factory.lessThanEqual(
Expressions.toValue(e1, factory, model, q),
Expressions.toValue(e2, factory, model, q));
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
Value val1 = Expressions.toValue(e1, factory, model, q);
Value val2 = Expressions.toValue(e2, factory, model, q);
JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null,
((CriteriaQueryImpl)q).getParameterTypes(), null);
return factory.lessThanEqual(val1, val2);
}
}
@ -634,7 +692,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
int literalType = Literal.TYPE_UNKNOWN;
if (arg != null) {
Class<?> literalClass = arg.getClass();
@ -650,11 +708,16 @@ public class Expressions {
literalType = Literal.TYPE_CLASS;
Literal lit = factory.newTypeLiteral(arg,
Literal.TYPE_CLASS);
ClassMetaData can =
((Types.Entity<X>)q.getRoot().getModel()).meta;
Class<?> candidate = can.getDescribedType();
if (candidate.isAssignableFrom((Class)arg))
lit.setMetaData(model.repos.getMetaData((Class<?>)arg,
null, true));
else
lit.setMetaData(can);
return lit;
}
}
return factory.newLiteral(arg, literalType);
}
@ -667,7 +730,7 @@ public class Expressions {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.newTypeLiteral(arg, Literal.TYPE_CLASS);
}
}
@ -679,9 +742,15 @@ public class Expressions {
this.collection = (ExpressionImpl<?>)collection;
}
@Override
public PredicateImpl clone() {
return new IsEmpty(collection);
}
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
Value val = Expressions.toValue(collection, factory, model, q);
return (isNegated())
? factory.isNotEmpty(val) : factory.isEmpty(val);
@ -695,7 +764,8 @@ public class Expressions {
@Override
public org.apache.openjpa.kernel.exps.Value toValue(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
Value v = Expressions.toValue(e, factory, model, q);
ClassMetaData meta = ((PathImpl)e)._member.fmd.getElement()
.getTypeMetaData();
@ -707,7 +777,6 @@ public class Expressions {
public static class IsMember<E> extends PredicateImpl {
ExpressionImpl<E> element;
ExpressionImpl<?> collection;
boolean negate;
public IsMember(Class<E> t, Expression<E> element,
Expression<?> collection) {
@ -723,15 +792,15 @@ public class Expressions {
this((Class<E>)element.getClass(), element, collection);
}
public IsMember<E> negate() {
negate = true;
return this;
@Override
public PredicateImpl clone() {
return new IsMember(element, collection);
}
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
return factory.contains(
Expressions.toValue(collection, factory, model, q),
Expressions.toValue(element, factory, model, q));
@ -762,18 +831,25 @@ public class Expressions {
public Like(Expression<String> x, String pattern) {
this(x, new Constant<String>(pattern), null);
}
public Like(Expression<String> x, String pat,
Expression<Character> esc) {
this(x, new Constant<String>(pat), esc);
}
public Like(Expression<String> x, String pat, Character esc) {
this(x, new Constant<String>(pat), new Constant<Character>(esc));
}
@Override
public PredicateImpl clone() {
return new Like(str, pattern, escapeChar);
}
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
String escapeStr = escapeChar == null ? null :
((Character)((Literal)Expressions.toValue(
escapeChar, factory, model, q)).getValue()).toString();
@ -799,7 +875,8 @@ public class Expressions {
}
public Coalesce<T> value(T value) {
return value(new Constant<T>(value));
values.add(new Constant<T>(value));
return this;
}
public Coalesce<T> value(Expression<? extends T> value) {
@ -807,11 +884,10 @@ public class Expressions {
return this;
}
@Override
public org.apache.openjpa.kernel.exps.Value toValue(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
Value[] vs = new Value[values.size()];
int i = 0;
for (Expression<?> e : values)
@ -821,6 +897,34 @@ public class Expressions {
}
}
public static class Nullif<T> extends ExpressionImpl<T> {
private Expression<T> val1;
private Expression<?> val2;
public Nullif(Expression<T> x, Expression<?> y) {
super(x.getJavaType());
val1 = x;
val2 = y;
}
public Nullif(Expression<T> x, T y) {
super(x.getJavaType());
val1 = x;
val2 = new Constant<T>(y);
}
@Override
public org.apache.openjpa.kernel.exps.Value toValue(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
Value value1 = Expressions.toValue((ExpressionImpl<?>)val1,
factory, model, q);
Value value2 = Expressions.toValue((ExpressionImpl<?>)val2,
factory, model, q);
return factory.nullIfExpression(value1, value2);
}
}
public static class IsNull extends PredicateImpl {
ExpressionImpl<?> e;
public IsNull(ExpressionImpl<?> e) {
@ -828,9 +932,15 @@ public class Expressions {
this.e = e;
}
@Override
public PredicateImpl negate() {
return new Expressions.IsNotNull(e);
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
return factory.equal(
Expressions.toValue(e, factory, model, q),
factory.getNull());
@ -844,9 +954,15 @@ public class Expressions {
this.e = e;
}
@Override
public PredicateImpl negate() {
return new Expressions.IsNull(e);
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
return factory.notEqual(
Expressions.toValue(e, factory, model, q),
factory.getNull());
@ -884,7 +1000,8 @@ public class Expressions {
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
org.apache.openjpa.kernel.exps.Expression inExpr =
super.toKernelExpression(factory, model, q);
IsNotNull notNull = new Expressions.IsNotNull(e);
@ -943,7 +1060,7 @@ public class Expressions {
@Override
public org.apache.openjpa.kernel.exps.Value toValue(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
int size = whens.size();
org.apache.openjpa.kernel.exps.Expression[] exps =
new org.apache.openjpa.kernel.exps.Expression[size];
@ -967,7 +1084,7 @@ public class Expressions {
private List<Expression<? extends R>> thens =
new ArrayList<Expression<? extends R>>();
private List<C> whens = new ArrayList<C>();
private List<Expression<C>> whens = new ArrayList<Expression<C>>();
private Expression<? extends R> otherwise;
@ -991,13 +1108,13 @@ public class Expressions {
}
public SimpleCase<C,R> when(C when, Expression<? extends R> then) {
whens.add(when);
whens.add(new Constant<C>(when));
thens.add(then);
return this;
}
public SimpleCase<C,R> when(C when, R then) {
whens.add(when);
whens.add(new Constant<C>(when));
Expression<? extends R> thenExpr =
new Expressions.Constant<R>(then);
thens.add(thenExpr);
@ -1017,19 +1134,18 @@ public class Expressions {
@Override
public org.apache.openjpa.kernel.exps.Value toValue(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
Value caseOperandExpr = Expressions.toValue(
(ExpressionImpl<?>)caseOperand, factory, model, q);
int size = whens.size();
org.apache.openjpa.kernel.exps.Expression[] exps =
new org.apache.openjpa.kernel.exps.Expression[size];
for (int i = 0; i < size; i++) {
org.apache.openjpa.kernel.exps.Literal val = null;
//TODO: Boolean literal, String literal
val = factory.newLiteral(whens.get(i), Literal.TYPE_NUMBER);
Value when = Expressions.toValue(
(ExpressionImpl<C>)whens.get(i), factory, model, q);
Value action = Expressions.toValue(
(ExpressionImpl<?>)thens.get(i), factory, model, q);
exps[i] = factory.whenScalar(val, action);
exps[i] = factory.whenScalar(when, action);
}
Value other = Expressions.toValue(
@ -1037,4 +1153,113 @@ public class Expressions {
return factory.simpleCaseExpression(caseOperandExpr, exps, other);
}
}
public static class Lower extends UnaryFunctionalExpression<String> {
public Lower(Expression<String> x) {
super(String.class, x);
}
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
return factory.toLowerCase(
Expressions.toValue(e, factory, model, q));
}
}
public static class Upper extends UnaryFunctionalExpression<String> {
public Upper(Expression<String> x) {
super(String.class, x);
}
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
return factory.toUpperCase(
Expressions.toValue(e, factory, model, q));
}
}
public static class Length extends UnaryFunctionalExpression<Integer> {
public Length(Expression<String> x) {
super(Integer.class, x);
}
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
return factory.stringLength(
Expressions.toValue(e, factory, model, q));
}
}
public static class Exists extends PredicateImpl {
SubqueryImpl<?> e;
public Exists(Subquery<?> x) {
super();
e = (SubqueryImpl<?>)x;
}
@Override
public PredicateImpl clone() {
return new Exists(e);
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
org.apache.openjpa.kernel.exps.Expression notEmpty =
factory.isNotEmpty(Expressions.toValue(e, factory, model, q));
if (isNegated())
return factory.not(notEmpty);
else
return notEmpty;
}
}
public static class All<X> extends ExpressionImpl<X> {
SubqueryImpl<X> e;
public All(Subquery<X> x) {
super(x.getJavaType());
e = (SubqueryImpl<X>)x;
}
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
return factory.all(Expressions.toValue(e, factory, model, q));
}
}
public static class Any<X> extends ExpressionImpl<X> {
SubqueryImpl<X> e;
public Any(Subquery<X> x) {
super(x.getJavaType());
e = (SubqueryImpl<X>)x;
}
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
return factory.any(Expressions.toValue(e, factory, model, q));
}
}
public static class Some<X> extends ExpressionImpl<X> {
SubqueryImpl<X> e;
public Some(Subquery<X> x) {
super(x.getJavaType());
e = (SubqueryImpl<X>)x;
}
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
//return factory.some(Expressions.toValue(e, factory, model, q));
return null;
}
}
}

View File

@ -20,7 +20,6 @@ package org.apache.openjpa.persistence.criteria;
import javax.persistence.criteria.AbstractCollectionJoin;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
@ -74,7 +73,7 @@ public abstract class Joins {
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery c) {
CriteriaQueryImpl c) {
boolean allowNull = joinType != JoinType.INNER;
org.apache.openjpa.kernel.exps.Path path =
(org.apache.openjpa.kernel.exps.Path)
@ -88,7 +87,8 @@ public abstract class Joins {
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery c) {
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl c) {
org.apache.openjpa.kernel.exps.Value path = this.toValue
(factory, model, c);
ClassMetaData meta = _member.fmd.getDeclaredTypeMetaData();
@ -150,7 +150,7 @@ public abstract class Joins {
*/
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery c) {
CriteriaQueryImpl c) {
boolean allowNull = joinType != JoinType.INNER;
org.apache.openjpa.kernel.exps.Path path =
(org.apache.openjpa.kernel.exps.Path)
@ -169,7 +169,8 @@ public abstract class Joins {
*/
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery c) {
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl c) {
org.apache.openjpa.kernel.exps.Value path = toValue
(factory, model, c);

View File

@ -19,8 +19,9 @@
package org.apache.openjpa.persistence.criteria;
import java.util.Collection;
import javax.persistence.Parameter;
import javax.persistence.criteria.CriteriaQuery;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Value;
@ -57,7 +58,7 @@ public class ParameterImpl<T> extends ExpressionImpl<T> implements Parameter<T>{
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
boolean positional = false;
LinkedMap parameterTypes = ((CriteriaQueryImpl)q).getParameterTypes();
if (parameterTypes == null) {

View File

@ -19,15 +19,16 @@
package org.apache.openjpa.persistence.criteria;
import javax.persistence.criteria.CriteriaQuery;
import java.util.Set;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.AbstractCollection;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Map;
import javax.persistence.metamodel.Member;
import javax.persistence.metamodel.Type;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
@ -78,14 +79,34 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
return _parent;
}
public PathImpl getInnermostParentPath() {
if (_parent == null)
return this;
PathImpl _p = _parent.getInnermostParentPath();
if (_p == null)
return _parent;
else
return _p.getInnermostParentPath();
}
/**
* Convert this path to a kernel path value.
*/
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
CriteriaQueryImpl q) {
Value var = null;
if (_parent != null) {
SubqueryImpl subquery = q.getContext();
PathImpl parent = getInnermostParentPath();
if (subquery != null && inSubquery(parent, subquery)) {
org.apache.openjpa.kernel.exps.Subquery subQ =
subquery.getSubQ();
org.apache.openjpa.kernel.exps.Path path = factory.newPath(subQ);
path.setMetaData(subQ.getMetaData());
boolean allowNull = false;
path.get(_member.fmd, allowNull);
var = path;
} else if (_parent != null) {
org.apache.openjpa.kernel.exps.Path path =
(org.apache.openjpa.kernel.exps.Path)
_parent.toValue(factory, model, q);
@ -105,6 +126,16 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
return var;
}
public static boolean inSubquery(PathImpl parent, SubqueryImpl subquery) {
Set<Root<?>> roots = subquery.getRoots();
for (Root<?> r : roots) {
if (parent == r)
return true;
}
return false;
}
public <Y> Path<Y> get(Attribute<? super X, Y> attr) {
return new PathImpl<X,Y>(this, (Members.Attribute<? super X, Y>)attr,
attr.getJavaType());

View File

@ -21,7 +21,6 @@ package org.apache.openjpa.persistence.criteria;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
@ -29,7 +28,7 @@ import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
public class PredicateImpl extends ExpressionImpl<Boolean>
implements Predicate {
implements Predicate {
List<Expression<Boolean>> _exps;
BooleanOperator _op;
boolean _negated = false;
@ -71,17 +70,21 @@ public class PredicateImpl extends ExpressionImpl<Boolean>
}
public PredicateImpl negate() {
PredicateImpl not = new PredicateImpl(_op);
PredicateImpl not = clone();
not._negated = true;
if (_exps != null)
not._exps = new ArrayList<Expression<Boolean>>(this._exps);
not._op = this._op;
return not;
}
public PredicateImpl clone() {
PredicateImpl clone = new PredicateImpl(_op);
if (_exps != null)
clone._exps = new ArrayList<Expression<Boolean>>(this._exps);
return clone;
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) {
if (_exps == null || _exps.isEmpty())
return factory.emptyExpression();
if (_exps.size() == 1)

View File

@ -19,13 +19,11 @@
package org.apache.openjpa.persistence.criteria;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.Entity;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.persistence.criteria.FromImpl;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.meta.Types;
@ -38,6 +36,7 @@ import org.apache.openjpa.persistence.meta.Types;
*/
public class RootImpl<X> extends FromImpl<X,X> implements Root<X> {
private final Types.Entity<X> _entity;
private RootImpl<X> _correlatedParent;
public RootImpl(Types.Entity<X> type) {
super(type);
@ -48,13 +47,28 @@ public class RootImpl<X> extends FromImpl<X,X> implements Root<X> {
return _entity;
}
public void setCorrelatedParent(RootImpl<X> correlatedParent) {
_correlatedParent = correlatedParent;
}
public RootImpl<X> getCorrelatedParent() {
return _correlatedParent;
}
/**
* Convert this path to a kernel path value.
*/
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery c) {
Value var = factory.newPath();
CriteriaQueryImpl c) {
SubqueryImpl subquery = c.getContext();
Value var = null;
if (subquery != null && PathImpl.inSubquery(this, subquery)) {
org.apache.openjpa.kernel.exps.Subquery subQ =
subquery.getSubQ();
var = factory.newPath(subQ);
} else
var = factory.newPath();
var.setMetaData(_entity.meta);
return var;
}
@ -65,7 +79,7 @@ public class RootImpl<X> extends FromImpl<X,X> implements Root<X> {
*/
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQuery c) {
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl c) {
org.apache.openjpa.kernel.exps.Value path = toValue(factory, model, c);
Value var = factory.newBoundVariable(getAlias(),
@ -73,6 +87,14 @@ public class RootImpl<X> extends FromImpl<X,X> implements Root<X> {
org.apache.openjpa.kernel.exps.Expression exp =
factory.bindVariable(var, path);
if (_correlatedParent == null)
return exp;
org.apache.openjpa.kernel.exps.Value path1 =
_correlatedParent.toValue(factory, model, c);
org.apache.openjpa.kernel.exps.Expression equal =
factory.equal(path1, path);
//return factory.and(exp, equal);
return equal;
}
}

View File

@ -21,13 +21,9 @@ package org.apache.openjpa.persistence.criteria;
import java.util.Arrays;
import java.util.List;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Selection;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.persistence.ResultItemImpl;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
/**
* An item selected in the projection clause of Criteria query.
@ -53,17 +49,4 @@ public class SelectionImpl<X> extends ResultItemImpl<X>
public List<Selection<?>> getSelections() {
return _sels;
}
Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQuery q) {
((CriteriaQueryImpl)q).setResultClass(getJavaType());
Value[] result = new Value[_sels.size()];
int i = 0;
for (Selection<?> s : _sels) {
result[i++] = ((ExpressionImpl<?>)s).toValue(factory, model,
q);
}
((CriteriaQueryImpl)q).setProjections(result);
return null;
}
}

View File

@ -0,0 +1,180 @@
package org.apache.openjpa.persistence.criteria;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.criteria.AbstractQuery;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.SetJoin;
import javax.persistence.criteria.Subquery;
import javax.persistence.metamodel.Entity;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.meta.Types;
import org.apache.openjpa.kernel.exps.QueryExpressions;
import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder;
public class SubqueryImpl<T> extends ExpressionImpl<T> implements Subquery<T> {
private final CriteriaQueryImpl _parent;
private final CriteriaQueryImpl _delegate;
private java.util.Set<Join<?,?>> _joins;
private Expression<T> _select;
private org.apache.openjpa.kernel.exps.Subquery _subq;
public SubqueryImpl(Class<T> cls, CriteriaQueryImpl parent) {
super(cls);
_parent = parent;
_delegate = new CriteriaQueryImpl(parent.getMetamodel());
_delegate.setContext(this);
}
public AbstractQuery getParent() {
return _parent;
}
public Subquery<T> select(Expression<T> expression) {
_select = expression;
_delegate.select(expression);
return this;
}
public Expression<T> getSelection() {
return _select;
}
public <X> Root<X> from(Entity<X> entity) {
return _delegate.from(entity);
}
public <X> Root<X> from(Class<X> entityClass) {
return _delegate.from(entityClass);
}
public Set<Root<?>> getRoots() {
return _delegate.getRoots();
}
public Root<?> getRoot() {
return _delegate.getRoot();
}
public Subquery<T> where(Expression<Boolean> restriction) {
_delegate.where(restriction);
return this;
}
public Subquery<T> where(Predicate... restrictions) {
_delegate.where(restrictions);
return this;
}
public Subquery<T> groupBy(Expression<?>... grouping) {
_delegate.groupBy(grouping);
return this;
}
public Subquery<T> having(Expression<Boolean> restriction) {
_delegate.having(restriction);
return this;
}
public Subquery<T> having(Predicate... restrictions) {
_delegate.having(restrictions);
return this;
}
public Subquery<T> distinct(boolean distinct) {
_delegate.distinct(distinct);
return this;
}
public List<Expression<?>> getGroupList() {
return _delegate.getGroupList();
}
public Predicate getRestriction() {
return _delegate.getRestriction();
}
public Predicate getGroupRestriction() {
return _delegate.getGroupRestriction();
}
public boolean isDistinct() {
return _delegate.isDistinct();
}
public <U> Subquery<U> subquery(Class<U> type) {
return new SubqueryImpl<U>(type, _delegate);
}
public <Y> Root<Y> correlate(Root<Y> root) {
Types.Entity<Y> entity =
(Types.Entity<Y>)((RootImpl<Y>)root).getModel();
RootImpl<Y> corrRoot = new RootImpl<Y>(entity);
corrRoot.setCorrelatedParent((RootImpl<Y>)root);
Set<Root<?>> roots = getRoots();
if (roots == null) {
roots = new LinkedHashSet<Root<?>>();
_delegate.setRoots(roots);
}
roots.add(corrRoot);
return corrRoot;
}
public <X,Y> Join<X,Y> correlate(Join<X,Y> join) {
return join;
}
public <X,Y> CollectionJoin<X,Y> correlate(CollectionJoin<X,Y> join) {
return join;
}
public <X,Y> SetJoin<X,Y> correlate(SetJoin<X,Y> join) {
return join;
}
public <X,Y> ListJoin<X,Y> correlate(ListJoin<X,Y> join) {
return join;
}
public <X,K,V> MapJoin<X,K,V> correlate(MapJoin<X,K,V> join) {
return join;
}
public java.util.Set<Join<?, ?>> getJoins() {
return _joins;
}
public org.apache.openjpa.kernel.exps.Subquery getSubQ() {
return _subq;
}
/**
* Convert this path to a kernel path value.
*/
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl q) {
final boolean subclasses = true;
CriteriaExpressionBuilder queryEval = q.getExprBuilder();
String alias = queryEval.nextAlias();
ClassMetaData candidate =
((Types.Managed<?>)getRoot().getModel()).meta;
_subq = factory.newSubquery(candidate, subclasses, alias);
_subq.setMetaData(candidate);
QueryExpressions subexp = q.getExprBuilder().
getQueryExpressions(factory, _delegate);
_subq.setQueryExpressions(subexp);
if (subexp.projections.length > 0)
JPQLExpressionBuilder.checkEmbeddable(subexp.projections[0], null);
return _subq;
}
}