From e01390051bc617047b7153868289c11ccb6f4cba Mon Sep 17 00:00:00 2001 From: Pinaki Poddar Date: Thu, 3 Sep 2009 08:52:17 +0000 Subject: [PATCH] OPENJPA-1278,OPENJPA-1276,OPENJPA-1013: Modify negation of predicate logic Promote interfaces from internal implementaion argument to public interfaces Add Fetch Join and logical precedence order to CQL generation git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@810825 13f79535-47bb-0310-9956-ffa450edef68 --- .../openjpa/persistence/criteria/TestCQL.java | 18 ++ .../criteria/TestEmbeddableCriteria.java | 1 - .../persistence/criteria/TestFetchJoin.java | 46 +++ .../criteria/TestTypeSafeCondExpression.java | 8 +- .../criteria/TestTypesafeCriteria.java | 4 +- .../persistence/criteria/AliasContext.java | 7 + .../criteria/CompoundSelections.java | 4 +- .../persistence/criteria/CriteriaBuilder.java | 12 +- .../criteria/CriteriaExpression.java | 4 +- .../criteria/CriteriaExpressionBuilder.java | 100 +++---- .../criteria/CriteriaQueryImpl.java | 83 ++++-- .../persistence/criteria/Expressions.java | 268 ++++++++++-------- .../persistence/criteria/FetchPathImpl.java | 3 + .../persistence/criteria/FromImpl.java | 5 +- .../openjpa/persistence/criteria/Joins.java | 25 +- .../persistence/criteria/OrderImpl.java | 4 +- .../criteria/ParameterExpressionImpl.java | 2 +- .../persistence/criteria/PathImpl.java | 4 +- .../persistence/criteria/PredicateImpl.java | 105 ++++--- .../persistence/criteria/RootImpl.java | 4 +- .../persistence/criteria/SelectionImpl.java | 4 +- .../persistence/criteria/SubqueryImpl.java | 4 +- 22 files changed, 422 insertions(+), 293 deletions(-) create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java index 05f0e668f..80be8fd5d 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java @@ -63,5 +63,23 @@ public class TestCQL extends CriteriaTest { jpql = "SELECT p FROM Person p WHERE (p.name = 'A' OR (p.name = 'B' AND (p.name = 'C' OR p.name = 'D')))"; assertEquivalence(q, jpql); assertEquals(jpql, q.toCQL()); + + // NOT (a OR b) + q.where(cb.or(a, b).negate()); + jpql = "SELECT p FROM Person p WHERE NOT (p.name = 'A' OR p.name = 'B')"; + assertEquivalence(q, jpql); + assertEquals(jpql, q.toCQL()); + + // NOT a + q.where(cb.and(a).negate()); + jpql = "SELECT p FROM Person p WHERE NOT p.name = 'A'"; + assertEquivalence(q, jpql); + assertEquals(jpql, q.toCQL()); + + // NOT a OR NOT b + q.where(cb.or(cb.not(a), cb.not(b))); + jpql = "SELECT p FROM Person p WHERE (p.name <> 'A' OR p.name <> 'B')"; + assertEquivalence(q, jpql); + assertEquals(jpql, q.toCQL()); } } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java index 2799720b7..cb6e0938a 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java @@ -1477,7 +1477,6 @@ public class TestEmbeddableCriteria extends EmbeddableDomainTestCase { assertEquivalence(q, jpql); } - @AllowFailure(message="JPQL parse exception") public void testEmbeddableQuery111() { String jpql = "select i from Item1 i where :image = any(select KEY(e) from i.images e) order by i"; CriteriaQuery q = cb.createQuery(Item1.class); diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java new file mode 100644 index 000000000..b3859b4a8 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java @@ -0,0 +1,46 @@ +/* + * 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 javax.persistence.criteria.JoinType; +import javax.persistence.criteria.Root; + +public class TestFetchJoin extends CriteriaTest { + public void testFetchJoin() { + String jpql = "SELECT e FROM Employee e INNER JOIN FETCH e.department"; + OpenJPACriteriaQuery q = cb.createQuery(Employee.class); + Root e = q.from(Employee.class); + q.select(e); + e.fetch(Employee_.department); + + assertEquivalence(q, jpql); + assertEquals(jpql, q.toCQL()); + } + + public void testLeftFetchJoin() { + String jpql = "SELECT e FROM Employee e LEFT JOIN FETCH e.department"; + OpenJPACriteriaQuery q = cb.createQuery(Employee.class); + Root e = q.from(Employee.class); + q.select(e); + e.fetch(Employee_.department, JoinType.LEFT); + + assertEquivalence(q, jpql); + assertEquals(jpql, q.toCQL()); + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java index 338a2fd39..4fc32dcf4 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java @@ -112,13 +112,13 @@ public class TestTypeSafeCondExpression extends CriteriaTest { public void testLike1() { String jpql = "SELECT o.computerName FROM CompUser o " - + "WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC')"; + + "WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC','Laptop')"; CriteriaQuery cq = cb.createQuery(String.class); Root o = cq.from(CompUser.class); cq.where(cb.and( cb.like(o.get(CompUser_.name),"Sha%"), - cb.in(o.get(CompUser_.computerName)).value("PC").negate() + cb.in(o.get(CompUser_.computerName)).value("PC").value("Laptop").negate() )); cq.select(o.get(CompUser_.computerName)); @@ -128,13 +128,13 @@ public class TestTypeSafeCondExpression extends CriteriaTest { public void testLike2() { String jpql = "SELECT o.computerName FROM CompUser o " - + "WHERE o.name LIKE 'Sha%o_' AND o.computerName NOT IN ('UNIX')"; + + "WHERE o.name LIKE 'Sha%o_' AND o.computerName NOT IN ('UNIX','DOS')"; CriteriaQuery cq = cb.createQuery(String.class); Root o = cq.from(CompUser.class); cq.where(cb.and( cb.like(o.get(CompUser_.name),"Sha%o_"), - cb.in(o.get(CompUser_.computerName)).value("UNIX").negate() + cb.in(o.get(CompUser_.computerName)).value("UNIX").value("DOS").negate() )); cq.select(o.get(CompUser_.computerName)); diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java index b4a5913cc..daa9c1431 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java @@ -1019,7 +1019,7 @@ public class TestTypesafeCriteria extends CriteriaTest { public void testKeys7() { String sql = "SELECT t0.name, t2.id, t2.label FROM CR_ITEM t0 " + "INNER JOIN CR_ITEM_photos t1 ON t0.id = t1.ITEM_ID " - + "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id"; + + "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id WHERE (NOT (1 <> 1))"; CriteriaQuery q = cb.createQuery(Customer.class); Root item = q.from(Item.class); @@ -1178,7 +1178,7 @@ public class TestTypesafeCriteria extends CriteriaTest { public void testValues7() { String sql = "SELECT t0.name, t2.id, t2.label FROM CR_ITEM t0 " + "INNER JOIN CR_ITEM_photos t1 ON t0.id = t1.ITEM_ID " - + "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id"; + + "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id WHERE (NOT (1 <> 1))"; CriteriaQuery q = cb.createQuery(Customer.class); Root item = q.from(Item.class); diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java index 001c51c71..e146c0c8d 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java @@ -18,6 +18,7 @@ */ package org.apache.openjpa.persistence.criteria; +import javax.persistence.criteria.Root; import javax.persistence.criteria.Selection; import org.apache.openjpa.kernel.exps.Value; @@ -58,6 +59,12 @@ public interface AliasContext { */ Value getRegisteredVariable(Selection node); + /** + * Gets the registered root variable for the given node. + * Return null if the node is not registered. + */ + Value getRegisteredRootVariable(Root node); + /** * Gets the registered path value for the given node. * Return null if the node is not registered. diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java index 91e2e33ed..496769bc8 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java @@ -97,7 +97,7 @@ public class CompoundSelections { abstract FillStrategy getFillStrategy(); @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { StringBuilder buffer = new StringBuilder(); for (int i = 0; i < _args.size(); i++) { buffer.append((((CriteriaExpression)_args.get(i)).asValue(q))); @@ -158,7 +158,7 @@ public class CompoundSelections { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return new StringBuilder("NEW ").append(getJavaType().getName()).append("(") .append(super.asValue(q)).append(")"); } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java index 52ea7cc39..88b7aca8c 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java @@ -392,6 +392,10 @@ public class CriteriaBuilder implements OpenJPACriteriaBuilder, ExpressionParser } public Expression literal(T value) { + if (Boolean.TRUE.equals(value)) + return (Expression)PredicateImpl.TRUE; + if (Boolean.FALSE.equals(value)) + return (Expression)PredicateImpl.FALSE; return new Expressions.Constant(value); } @@ -452,15 +456,15 @@ public class CriteriaBuilder implements OpenJPACriteriaBuilder, ExpressionParser } public Predicate not(Expression restriction) { - return new Expressions.Not(restriction); + return ((Predicate)restriction).negate(); } public Predicate notEqual(Expression x, Expression y) { - return equal(x, y).negate(); + return new Expressions.NotEqual(x, y); } public Predicate notEqual(Expression x, Object y) { - return equal(x, y).negate(); + return new Expressions.NotEqual(x, y); } public Predicate notLike(Expression x, Expression pattern) { @@ -679,7 +683,7 @@ public class CriteriaBuilder implements OpenJPACriteriaBuilder, ExpressionParser } public Predicate isNotNull(Expression x) { - return new Expressions.IsNull((ExpressionImpl )x).negate(); + return new Expressions.IsNotNull((ExpressionImpl )x); } public Predicate isNull(Expression x) { diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java index 3e9ce0db3..633d64456 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java @@ -36,10 +36,10 @@ public interface CriteriaExpression { /** * Get a string representation of this node as a value in the context of the given query. */ - StringBuilder asValue(CriteriaQueryImpl q); + StringBuilder asValue(AliasContext q); /** * Get a string representation of this node as a variable in the context of the given query. */ - StringBuilder asVariable(CriteriaQueryImpl q); + StringBuilder asVariable(AliasContext q); } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java index 8a2495ac6..dd67727da 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java @@ -89,28 +89,21 @@ public class CriteriaExpressionBuilder { protected void evalAccessPaths(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl q) { Set metas = new HashSet(); - Set> roots = q.getRoots(); - if (roots != null) { - MetamodelImpl metamodel = q.getMetamodel(); - for (Root root : roots) { - metas.add(((AbstractManagedType)root.getModel()).meta); - if (root.getJoins() != null) { - for (Join join : root.getJoins()) { - Class cls = join.getAttribute().getJavaType(); - if (join.getAttribute().isAssociation()) { - ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true); - PersistenceType type = MetamodelImpl.getPersistenceType(meta); - if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE) - metas.add(meta); - } - } - if (root.getFetches() != null) { - for (Fetch fetch : root.getFetches()) { - metas.add(metamodel.repos.getMetaData(fetch.getAttribute().getJavaType(), null, false)); - } - } + MetamodelImpl metamodel = q.getMetamodel(); + for (Root root : q.getRoots()) { + metas.add(((AbstractManagedType)root.getModel()).meta); + for (Join join : root.getJoins()) { + Class cls = join.getAttribute().getJavaType(); + if (join.getAttribute().isAssociation()) { + ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true); + PersistenceType type = MetamodelImpl.getPersistenceType(meta); + if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE) + metas.add(meta); } } + for (Fetch fetch : root.getFetches()) { + metas.add(metamodel.repos.getCachedMetaData(fetch.getAttribute().getJavaType())); + } } exps.accessPath = metas.toArray(new ClassMetaData[metas.size()]); } @@ -178,15 +171,9 @@ public class CriteriaExpressionBuilder { } 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; - } + exps.distinct = q.isDistinct() ? QueryExpressions.DISTINCT_TRUE | QueryExpressions.DISTINCT_AUTO + : QueryExpressions.DISTINCT_FALSE; + } protected void evalCrossJoinRoots(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl q) { Set> roots = q.getRoots(); @@ -197,10 +184,11 @@ public class CriteriaExpressionBuilder { for (Root root : roots) { String alias = q.getAlias(root); Value var = factory.newBoundVariable(alias, AbstractExpressionBuilder.TYPE_OBJECT); - var.setMetaData(((Types.Entity)root.getModel()).meta); + var.setMetaData(((AbstractManagedType)root.getModel()).meta); q.registerRoot(root, var); } - } } + } + } } protected void evalFilter(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl q) { @@ -212,25 +200,23 @@ public class CriteriaExpressionBuilder { if (subQuery == null || subQuery.getCorrelatedJoins() == null) { q.assertRoot(); for (Root root : roots) { - if (root.getJoins() != null) { - for (Join join : root.getJoins()) { - filter = and(factory, ((ExpressionImpl)join).toKernelExpression(factory, model, q), filter); - } + for (Join join : root.getJoins()) { + filter = Expressions.and(factory, + ((ExpressionImpl)join).toKernelExpression(factory, model, q), filter); } ((RootImpl)root).addToContext(factory, model, q); } } if (subQuery != null) { List> corrJoins = subQuery.getCorrelatedJoins(); - if (corrJoins != null) { - for (int i = 0; i < corrJoins.size(); i++) - filter = and(factory, ((ExpressionImpl)corrJoins.get(i)).toKernelExpression(factory, model, q), - filter); + for (int i = 0; corrJoins != null && i < corrJoins.size(); i++) { + filter = Expressions.and(factory, ((ExpressionImpl)corrJoins.get(i)) + .toKernelExpression(factory, model, q), filter); } } if (where != null) { - filter = and(factory, where.toKernelExpression(factory, model, q), filter); + filter = Expressions.and(factory, where.toKernelExpression(factory, model, q), filter); } if (filter == null) { filter = factory.emptyExpression(); @@ -296,51 +282,31 @@ public class CriteriaExpressionBuilder { } } } - - -// protected boolean isDefaultProjection(List> selections, CriteriaQueryImpl q) { -// if (selections == null) -// return true; -// if (selections.size() != 1) -// return false; -// Selection sel = selections.get(0); -// if (q.getRoots() != null && sel == q.getRoot()) -// return true; -// if ((sel instanceof PathImpl) && ((PathImpl)sel)._correlatedPath != null) -// return true; -// return false; -// } protected void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl q) { List iPaths = new ArrayList(); List oPaths = new ArrayList(); Set> roots = q.getRoots(); - if (roots == null) - return; for (Root root : roots) { Set fetches = root.getFetches(); if (fetches == null) continue; for (Fetch fetch : fetches) { - String fPath = ((Members.Member)fetch.getAttribute()) - .fmd.getFullName(false); + String fPath = ((Members.Member)fetch.getAttribute()).fmd.getFullName(false); oPaths.add(fPath); if (fetch.getJoinType() == JoinType.INNER) { iPaths.add(fPath); } } } - if (!iPaths.isEmpty()) + if (!iPaths.isEmpty()) { exps.fetchInnerPaths = iPaths.toArray(new String[iPaths.size()]); - if (!oPaths.isEmpty()) + } + if (!oPaths.isEmpty()) { exps.fetchPaths = oPaths.toArray(new String[oPaths.size()]); + } } - protected static 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); - } - // =================================================================================== // Result Shape processing // =================================================================================== @@ -358,7 +324,7 @@ public class CriteriaExpressionBuilder { if (type == null) type = Object.class; if (s.isCompoundSelection()) { - CompoundSelection cs = (CompoundSelection)s; + CompoundSelection cs = (CompoundSelection)s; result = new ResultShape(s.getJavaType(), CompoundSelections.getFillStrategy(cs)); List> terms = cs.getCompoundSelectionItems(); for (Selection term : terms) { @@ -414,6 +380,4 @@ public class CriteriaExpressionBuilder { return result; } - - } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java index 997c3971e..a31cb1285 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java @@ -28,11 +28,11 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; -import java.util.concurrent.CopyOnWriteArrayList; import javax.persistence.criteria.AbstractQuery; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; +import javax.persistence.criteria.Fetch; import javax.persistence.criteria.Join; import javax.persistence.criteria.Order; import javax.persistence.criteria.ParameterExpression; @@ -72,13 +72,13 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte private Set> _roots; private PredicateImpl _where; private List _orders; - private LinkedMap/*, Class>*/ _params; - private Selection _selection; + private LinkedMap _params; /*, Class>*/ + private Selection _selection; private List> _selections; private List> _groups; private PredicateImpl _having; private List> _subqueries; - private Boolean _distinct; + private boolean _distinct; private final SubqueryImpl _delegator; private final Class _resultClass; private boolean _compiled; @@ -236,18 +236,22 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte } public CriteriaQuery groupBy(Expression... grouping) { - _groups = new ArrayList>(); - if (grouping == null) + if (grouping == null) { + _groups = null; return this; + } + _groups = new ArrayList>(); for (Expression e : grouping) _groups.add(e); return this; } public CriteriaQuery groupBy(List> grouping) { - _groups = new ArrayList>(); - if (grouping == null) + if (grouping == null) { + _groups = null; return this; + } + _groups = new ArrayList>(); for (Expression e : grouping) _groups.add(e); return this; @@ -255,21 +259,27 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte public CriteriaQuery having(Expression restriction) { - _having = new PredicateImpl().add(restriction); + _having = (PredicateImpl)restriction; return this; } public CriteriaQuery having(Predicate... restrictions) { - _having = new PredicateImpl(); + if (restrictions == null) { + _having = null; + return this; + } + _having = new PredicateImpl.And(); for (Predicate p : restrictions) _having.add(p); return this; } public CriteriaQuery orderBy(Order... orders) { - _orders = new ArrayList(); - if (orders == null) + if (orders == null) { + _orders = null; return this; + } + _orders = new ArrayList(); for (Order o : orders) { _orders.add(o); } @@ -277,9 +287,11 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte } public CriteriaQuery orderBy(List orders) { - _orders = new ArrayList(); - if (orders == null) + if (orders == null) { + _orders = null; return this; + } + _orders = new ArrayList(); for (Order o : orders) { _orders.add(o); } @@ -306,7 +318,7 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte _where = null; return this; } - _where = new PredicateImpl().add(restriction); + _where = (PredicateImpl)restriction; return this; } @@ -316,9 +328,7 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte _where = null; return this; } - _where = new PredicateImpl(); - for (Predicate p : restrictions) - _where.add(p); + _where = new PredicateImpl.And(restrictions); return this; } @@ -371,11 +381,10 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte _roots.add(root); } + /** + * Affirms if selection of this query is distinct. + */ public boolean isDistinct() { - return _distinct == null ? false : _distinct.booleanValue(); - } - - Boolean getDistinct() { return _distinct; } @@ -553,11 +562,8 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte /** * Gets the registered variable for the given root. - * - * @param root - * @return */ - Value getRegisteredRootVariable(Root root) { + public Value getRegisteredRootVariable(Root root) { Value var = _rootVariables.get(root); if (var != null) return var; @@ -640,7 +646,7 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte public String toCQL() { StringBuilder buffer = new StringBuilder(); render(buffer, _roots, null); - return buffer.toString(); + return buffer.toString().trim(); } void render(StringBuilder buffer, Set> roots, List> correlatedJoins) { @@ -655,11 +661,20 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte } if (_orders != null) { buffer.append(" ORDER BY "); - List orderBys = getOrderList(); - for (int i = 0; i < orderBys.size(); i++) { - buffer.append(((CriteriaExpression)orderBys.get(i)).asValue(this)); + for (Order orderBy : getOrderList()) { + buffer.append(((CriteriaExpression)orderBy).asValue(this)); } } + if (_groups != null) { + buffer.append(" GROUP BY "); + for (Expression groupBy : getGroupList()) { + buffer.append(((CriteriaExpression)groupBy).asValue(this)); + } + } + if (_having != null) { + buffer.append(" HAVING "); + buffer.append(_having.asValue(this)); + } } private void renderJoins(StringBuilder buffer, Collection> joins) { @@ -667,6 +682,7 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte for (Join j : joins) { buffer.append(((ExpressionImpl)j).asVariable(this)).append(" "); renderJoins(buffer, j.getJoins()); + renderFetches(buffer, j.getFetches()); } } @@ -677,6 +693,13 @@ public class CriteriaQueryImpl implements OpenJPACriteriaQuery, AliasConte buffer.append(((ExpressionImpl)r).asVariable(this)); if (++i != roots.size()) buffer.append(", "); renderJoins(buffer, r.getJoins()); + renderFetches(buffer, r.getFetches()); + } + } + private void renderFetches(StringBuilder buffer, Set fetches) { + if (fetches == null) return; + for (Fetch j : fetches) { + buffer.append(((ExpressionImpl)j).asValue(this)).append(" "); } } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java index 66d95568d..6e26558b3 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java @@ -124,7 +124,7 @@ public class Expressions { /** * Renders the given expressions as a list of values separated by the given connector. */ - static StringBuilder asValue(CriteriaQueryImpl q, Expression[] exps, String connector) { + static StringBuilder asValue(AliasContext q, Expression[] exps, String connector) { StringBuilder buffer = new StringBuilder(); if (exps == null) return buffer; for (int i = 0; i < exps.length; i++) { @@ -139,7 +139,7 @@ public class Expressions { /** * Renders the given arguments as a list of values separated by the given connector. */ - static StringBuilder asValue(CriteriaQueryImpl q, Object...params) { + static StringBuilder asValue(AliasContext q, Object...params) { StringBuilder buffer = new StringBuilder(); if (params == null) return buffer; for (int i = 0; i < params.length; i++) { @@ -175,6 +175,11 @@ public class Expressions { return set == null ? new HashSet() : new CopyOnWriteArraySet(set); } + static 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); + } + /** @@ -254,7 +259,7 @@ public class Expressions { * i.e. an expression whose resultant type is Boolean. * */ - public static class BinaryLogicalExpression extends PredicateImpl { + public static abstract class BinaryLogicalExpression extends PredicateImpl { protected final ExpressionImpl e1; protected final ExpressionImpl e2; @@ -264,10 +269,10 @@ public class Expressions { e2 = (ExpressionImpl)y; } - @Override - public PredicateImpl clone() { - return new BinaryLogicalExpression(e1, e2); - } +// @Override +// public PredicateImpl clone() { +// return new BinaryLogicalExpression(e1, e2); +// } public void acceptVisit(CriteriaExpressionVisitor visitor) { Expressions.acceptVisit(visitor, this, e1, e2); @@ -285,7 +290,7 @@ public class Expressions { return factory.abs(Expressions.toValue(e, factory, model, q)); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "ABS", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -309,7 +314,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "COUNT", OPEN_BRACE, _distinct ? "DISTINCT"+OPEN_BRACE : "", e, _distinct ? CLOSE_BRACE : "", CLOSE_BRACE); } @@ -326,7 +331,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "AVG", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -341,7 +346,7 @@ public class Expressions { return factory.sqrt(Expressions.toValue(e, factory, model, q)); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "SQRT", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -356,7 +361,7 @@ public class Expressions { return factory.max(Expressions.toValue(e, factory, model, q)); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "MAX", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -371,7 +376,7 @@ public class Expressions { return factory.min(Expressions.toValue(e, factory, model, q)); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "MIN", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -395,7 +400,7 @@ public class Expressions { return factory.size(val); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "SIZE", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -416,7 +421,7 @@ public class Expressions { new Expressions.ListArgument(resultType, args).toValue(factory, model, q)); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, functionName, OPEN_BRACE, Expressions.asValue(q, args, COMMA), CLOSE_BRACE); } } @@ -433,7 +438,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "TYPE", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -449,7 +454,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, OPEN_BRACE, getJavaType().getSimpleName(), CLOSE_BRACE, e); } } @@ -475,7 +480,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "CONCAT", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE); } } @@ -520,7 +525,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "SUBSTRING", OPEN_BRACE, e, COMMA, from, COMMA, len, CLOSE_BRACE); } } @@ -572,7 +577,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "LOCATE", OPEN_BRACE, pattern, COMMA, path, CLOSE_BRACE); } } @@ -623,7 +628,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "TRIM", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE); } } @@ -655,7 +660,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return e2 == null ? Expressions.asValue(q, "SUM", OPEN_BRACE, e1, CLOSE_BRACE) : Expressions.asValue(q, e1, " + ", e2); @@ -683,7 +688,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e1, " * " ,e2); } } @@ -709,7 +714,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e1, " - " ,e2); } } @@ -736,7 +741,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e1, "%" ,e2); } } @@ -760,7 +765,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "MOD", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE); } } @@ -776,7 +781,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return new StringBuilder("CURRENT_DATE"); } } @@ -792,7 +797,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return new StringBuilder("CURRENT_TIME"); } } @@ -808,7 +813,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return new StringBuilder("CURRENT_TIMESTAMP"); } } @@ -821,10 +826,10 @@ public class Expressions { public Equal(Expression x, Object y) { this(x, new Constant(y)); } - + @Override - public PredicateImpl clone() { - return new Equal(e1, e2); + public PredicateImpl negate() { + return new NotEqual(e1, e2).markNegated(); } @Override @@ -833,15 +838,44 @@ public class Expressions { Value val1 = Expressions.toValue(e1, factory, model, q); Value val2 = Expressions.toValue(e2, factory, model, q); Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q); - return isNegated() ? factory.notEqual(val1, val2) : factory.equal(val1, val2); + return factory.equal(val1, val2); } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e1, " = ", e2); } } + public static class NotEqual extends BinaryLogicalExpression { + public NotEqual(Expression x, Expression y) { + super(x,y); + } + + public NotEqual(Expression x, Object y) { + this(x, new Constant(y)); + } + + @Override + public PredicateImpl negate() { + return new Equal(e1, e2).markNegated(); + } + + @Override + org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, + CriteriaQueryImpl q) { + Value val1 = Expressions.toValue(e1, factory, model, q); + Value val2 = Expressions.toValue(e2, factory, model, q); + Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q); + return factory.notEqual(val1, val2); + } + + @Override + public StringBuilder asValue(AliasContext q) { + return Expressions.asValue(q, e1, " <> ", e2); + } + } + public static class GreaterThan extends BinaryLogicalExpression { public GreaterThan(Expression x, Expression y) { super(x,y); @@ -851,6 +885,11 @@ public class Expressions { this(x, new Constant(y)); } + @Override + public PredicateImpl negate() { + return new LessThanEqual(e1, e2).markNegated(); + } + @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { @@ -861,7 +900,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e1, " > ", e2); } } @@ -875,6 +914,11 @@ public class Expressions { this(x, new Constant(y)); } + @Override + public PredicateImpl negate() { + return new LessThan(e1, e2).markNegated(); + } + @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { @@ -885,7 +929,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e1, " >= ", e2); } } @@ -899,6 +943,11 @@ public class Expressions { this(x, new Constant(y)); } + @Override + public PredicateImpl negate() { + return new GreaterThanEqual(e1, e2).markNegated(); + } + @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { @@ -909,7 +958,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e1, " < ", e2); } } @@ -923,6 +972,11 @@ public class Expressions { this(x, new Constant(y)); } + @Override + public PredicateImpl negate() { + return new GreaterThan(e1, e2).markNegated(); + } + @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { @@ -934,7 +988,7 @@ public class Expressions { @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e1, " <= ", e2); } } @@ -956,7 +1010,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e, " BETWEEN ", v1, " AND ", v2); } } @@ -1009,7 +1063,7 @@ public class Expressions { Expressions.acceptVisit(visitor, this, arg instanceof Expression ? ((Expression)arg) : null); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { if (arg == null) return new StringBuilder("NULL"); Class literalClass = getJavaType(); @@ -1040,15 +1094,20 @@ public class Expressions { } @Override - public PredicateImpl clone() { - return new IsEmpty(collection); + public PredicateImpl negate() { + return new IsNotEmpty(collection).markNegated(); + } + + @Override + Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { + return Expressions.toValue(collection, factory, model, q); } @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { Value val = Expressions.toValue(collection, factory, model, q); - return (isNegated()) ? factory.not(factory.isEmpty(val)) : factory.isEmpty(val); + return factory.isEmpty(val); } public void acceptVisit(CriteriaExpressionVisitor visitor) { @@ -1057,7 +1116,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, collection, " IS EMPTY"); } } @@ -1070,15 +1129,21 @@ public class Expressions { } @Override - public PredicateImpl clone() { - return new IsNotEmpty(collection); + public PredicateImpl negate() { + return new IsEmpty(collection).markNegated(); + } + + @Override + Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { + return Expressions.toValue(collection, factory, model, q); } @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { Value val = Expressions.toValue(collection, factory, model, q); - return (isNegated()) ? factory.isEmpty(val) : factory.isNotEmpty(val); + // factory.isNotEmpty() not used to match JPQL + return factory.not(factory.isEmpty(val)); } public void acceptVisit(CriteriaExpressionVisitor visitor) { @@ -1087,7 +1152,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, collection, " IS NOT EMPTY"); } } @@ -1108,7 +1173,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "INDEX", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -1131,18 +1196,13 @@ public class Expressions { this((Class)element.getClass(), element, collection); } - @Override - public PredicateImpl clone() { - return new IsMember(element.getJavaType(), element, collection); - } - @Override public org.apache.openjpa.kernel.exps.Expression toKernelExpression( ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { org.apache.openjpa.kernel.exps.Expression contains = factory.contains( Expressions.toValue(collection, factory, model, q), Expressions.toValue(element, factory, model, q)); - return isNegated() ? factory.not(contains) : contains; + return contains; } public void acceptVisit(CriteriaExpressionVisitor visitor) { @@ -1151,8 +1211,8 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { - return Expressions.asValue(q, element, isNegated() ? "NOT " : "", "MEMBER OF ", collection); + public StringBuilder asValue(AliasContext q) { + return Expressions.asValue(q, element, "MEMBER OF ", collection); } } @@ -1192,11 +1252,6 @@ public class Expressions { this(x, new Constant(pat), new Constant(esc)); } - @Override - public PredicateImpl clone() { - return new Like(str, pattern, escapeChar); - } - @Override public org.apache.openjpa.kernel.exps.Expression toKernelExpression( ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { @@ -1215,7 +1270,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, str, " LIKE ", pattern); } } @@ -1252,7 +1307,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "COALESCE", OPEN_BRACE, Expressions.asValue(q, values == null ? null : values.toArray(new Expression[values.size()]), COMMA), CLOSE_BRACE); } @@ -1285,7 +1340,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "NULLIF", OPEN_BRACE, val1, COMMA, val2, CLOSE_BRACE); } } @@ -1299,8 +1354,8 @@ public class Expressions { @Override public PredicateImpl negate() { - return new Expressions.IsNotNull(e); - } + return new IsNotNull(e).markNegated(); + } @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression( @@ -1316,7 +1371,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e, " IS NULL"); } } @@ -1330,9 +1385,9 @@ public class Expressions { @Override public PredicateImpl negate() { - return new Expressions.IsNull(e); - } - + return new IsNull(e).markNegated(); + } + @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression( ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { @@ -1347,7 +1402,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, e, " IS NOT NULL"); } } @@ -1355,7 +1410,6 @@ public class Expressions { public static class In extends PredicateImpl.Or implements QueryBuilder.In { final ExpressionImpl e; - private boolean negate; public In(Expression e) { super(); this.e = (ExpressionImpl)e; @@ -1375,11 +1429,16 @@ public class Expressions { return this; } - public In negate() { - this.negate = !negate; - return this; + @Override + public PredicateImpl negate() { + In notIn = new In(e); + notIn.markNegated(); + for (Predicate e : _exps) { + notIn.add(e); + } + return notIn; } - + @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression( ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { @@ -1390,23 +1449,20 @@ public class Expressions { ExpressionImpl e1 = e.e1; Value val2 = Expressions.toValue(e2, factory, model, q); if (!(val2 instanceof Literal)) { - Value val1 = Expressions.toValue(e1, factory, model, q); + Value val1 = Expressions.toValue(e1, factory, model, q); Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q); inExpr = factory.contains(val2, val1); - return negate ? factory.not(inExpr) : inExpr; + return isNegated() ? factory.not(inExpr) : inExpr; } else if (((Literal)val2).getParseType() == Literal.TYPE_COLLECTION) { - List> exps = new ArrayList>(); Collection coll = (Collection)((Literal)val2).getValue(); + _exps.clear(); for (Object v : coll) { - exps.add(new Expressions.Equal(e1,v)); + add(new Expressions.Equal(e1,v)); } - _exps = exps; } } inExpr = super.toKernelExpression(factory, model, q); IsNotNull notNull = new Expressions.IsNotNull(e); - if (negate) - inExpr = factory.not(inExpr); return factory.and(inExpr, notNull.toKernelExpression(factory, model, q)); } @@ -1417,8 +1473,8 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { - StringBuilder buffer = Expressions.asValue(q, e, negate ? " NOT IN " : " IN ", OPEN_BRACE); + public StringBuilder asValue(AliasContext q) { + StringBuilder buffer = Expressions.asValue(q, e, " IN ", OPEN_BRACE); for (int i = 0; i < _exps.size(); i++) { buffer.append(((Equal)_exps.get(i)).e2.asValue(q)).append(i+1 == _exps.size() ? CLOSE_BRACE : COMMA); } @@ -1481,7 +1537,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { StringBuilder buffer = new StringBuilder("CASE "); int size = whens.size(); for (int i = 0; i < size; i++) { @@ -1558,7 +1614,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { StringBuilder buffer = new StringBuilder("CASE "); int size = whens.size(); for (int i = 0; i < size; i++) { @@ -1580,7 +1636,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "LOWER", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -1596,7 +1652,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "UPPER", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -1612,7 +1668,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "LENGTH", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -1648,22 +1704,17 @@ public class Expressions { super(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 exists = factory.isNotEmpty(Expressions.toValue(e, factory, model, q)); - return isNegated() ? factory.not(exists) : exists; + return exists; } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { - return Expressions.asValue(q, isNegated() ? "NOT" : "", " EXISTS", OPEN_BRACE, e, CLOSE_BRACE); + public StringBuilder asValue(AliasContext q) { + return Expressions.asValue(q, " EXISTS", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -1679,7 +1730,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "ALL", OPEN_BRACE, e, CLOSE_BRACE); } } @@ -1695,27 +1746,22 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, "ANY", OPEN_BRACE, e, CLOSE_BRACE); } } - public static class Not extends PredicateImpl { + public static class Not extends PredicateImpl { protected final ExpressionImpl e; public Not(Expression ne) { super(); e = (ExpressionImpl)ne; } - @Override - public PredicateImpl clone() { - return new Not(e); - } - @Override public org.apache.openjpa.kernel.exps.Expression toKernelExpression( ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { - return factory.not(super.toKernelExpression(factory, model, q)); + return factory.not(e.toKernelExpression(factory, model, q)); } public void acceptVisit(CriteriaExpressionVisitor visitor) { @@ -1723,8 +1769,8 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { - return Expressions.asValue(q, "NOT", OPEN_BRACE, e, CLOSE_BRACE); + public StringBuilder asValue(AliasContext q) { + return Expressions.asValue(q, "NOT ", e); } } @@ -1748,7 +1794,7 @@ public class Expressions { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return actual.asValue(q); } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java index f2cde9ae8..080e91ec4 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java @@ -110,4 +110,7 @@ public class FetchPathImpl extends PathImpl implements Fetch { return fetch; } + public StringBuilder asValue(AliasContext q) { + return super.asValue(q).insert(0, " " + joinType + " JOIN FETCH "); + } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java index 984348cea..3e7336721 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java @@ -148,8 +148,7 @@ public class FromImpl extends PathImpl implements From { * Join to the given List-valued attribute using the given join type. */ public ListJoin join(ListAttribute list, JoinType jt) { - ListJoin join = new Joins.List(this, - (Members.ListAttributeImpl)list, jt); + ListJoin join = new Joins.List(this, (Members.ListAttributeImpl)list, jt); addJoin(join); return join; } @@ -283,6 +282,6 @@ public class FromImpl extends PathImpl implements From { public void acceptVisit(CriteriaExpressionVisitor visitor) { Expressions.acceptVisit(visitor, this, - _joins == null ? null : _joins.toArray(new ExpressionImpl[_joins.size()])); + _joins == null ? null : _joins.toArray(new ExpressionImpl[_joins.size()])); } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java index 3b233ea34..3a563fc0b 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java @@ -175,11 +175,11 @@ public abstract class Joins { } if (getJoins() != null) { for (Join join1 : getJoins()) { - filter = CriteriaExpressionBuilder.and(factory, - ((FromImpl)join1).toKernelExpression(factory, model, c), filter); + filter = Expressions.and(factory, + ((FromImpl)join1).toKernelExpression(factory, model, c), filter); } } - org.apache.openjpa.kernel.exps.Expression expr = CriteriaExpressionBuilder.and(factory, join, filter); + org.apache.openjpa.kernel.exps.Expression expr = Expressions.and(factory, join, filter); if (correlatedParentPath == null) { return expr; @@ -199,7 +199,7 @@ public abstract class Joins { path.setMetaData(meta); //filter = bindVariableForKeyPath(path, alias, filter); filter = factory.equal(parentPath, path); - return CriteriaExpressionBuilder.and(factory, expr, filter); + return Expressions.and(factory, expr, filter); } } @@ -249,7 +249,7 @@ public abstract class Joins { } @Override - public StringBuilder asVariable(CriteriaQueryImpl q) { + public StringBuilder asVariable(AliasContext q) { String varName = "?"; Value var = q.getRegisteredVariable(this); if (var == null) { @@ -257,8 +257,7 @@ public abstract class Joins { } else { varName = var.getName(); } - return new StringBuilder(joinType.toString()).append(" JOIN ") - .append(super.asVariable(q)).append(" " + varName); + return new StringBuilder(" " + joinType + " JOIN ").append(super.asVariable(q)).append(" " + varName); } } @@ -386,11 +385,11 @@ public abstract class Joins { } if (getJoins() != null) { for (Join join1 : getJoins()) { - filter = CriteriaExpressionBuilder.and(factory, + filter = Expressions.and(factory, ((FromImpl)join1).toKernelExpression(factory, model, c), filter); } } - org.apache.openjpa.kernel.exps.Expression expr = CriteriaExpressionBuilder.and(factory, join, filter); + org.apache.openjpa.kernel.exps.Expression expr = Expressions.and(factory, join, filter); if (correlatedParentPath == null) { return expr; } else { @@ -417,11 +416,11 @@ public abstract class Joins { c.registerVariable(this, var, parentPath); if (_member.fmd.isElementCollection()) { - filter = CriteriaExpressionBuilder.and(factory, join, filter); + filter = Expressions.and(factory, join, filter); } else { filter = factory.equal(parentPath, path); } - return CriteriaExpressionBuilder.and(factory, expr, filter); + return Expressions.and(factory, expr, filter); } } @@ -580,7 +579,7 @@ public abstract class Joins { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { StringBuilder buffer = new StringBuilder("KEY("); Value var = q.getRegisteredVariable(map); buffer.append(var != null ? var.getName() : map.asValue(q)).append(")"); @@ -609,7 +608,7 @@ public abstract class Joins { } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { StringBuilder buffer = new StringBuilder("ENTRY("); Value var = q.getRegisteredVariable(map); buffer.append(var != null ? var.getName() : map.asValue(q)).append(")"); diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java index db8fd4fd5..25ee56e00 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java @@ -60,11 +60,11 @@ public class OrderImpl implements Order, CriteriaExpression { } } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return e.asValue(q).append(_ascending ? "" : " DESC"); } - public StringBuilder asVariable(CriteriaQueryImpl q) { + public StringBuilder asVariable(AliasContext q) { throw new IllegalStateException(this + " can not be rendered as variable"); } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java index 82ee10deb..11d702515 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java @@ -98,7 +98,7 @@ public class ParameterExpressionImpl extends ExpressionImpl } @Override - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { return Expressions.asValue(q, ":", _name == null ? "param" : _name); } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java index 0fcdb4645..891291ff7 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java @@ -279,7 +279,7 @@ public class PathImpl extends ExpressionImpl implements Path { return new Expressions.Type>(this); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { StringBuilder buffer = new StringBuilder(); if (_parent != null) { Value var = q.getRegisteredVariable(_parent); @@ -291,7 +291,7 @@ public class PathImpl extends ExpressionImpl implements Path { return buffer; } - public StringBuilder asVariable(CriteriaQueryImpl q) { + public StringBuilder asVariable(AliasContext q) { Value var = q.getRegisteredVariable(this); return asValue(q).append(" ").append(var == null ? "?" : var.getName()); } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java index c74000e03..1ef067e81 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java @@ -19,7 +19,6 @@ package org.apache.openjpa.persistence.criteria; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -29,24 +28,37 @@ import javax.persistence.criteria.Predicate; import org.apache.openjpa.kernel.exps.ExpressionFactory; import org.apache.openjpa.persistence.meta.MetamodelImpl; -public class PredicateImpl extends ExpressionImpl implements Predicate { +/** + * Predicate is a expression that evaluates to true or false. + * All boolean expressions are implemented as Predicate. + * A predicate can have zero or more predicate arguments. + * Default predicate operator is AND (conjunction). + * Two constant predicates are Predicate.TRUE and Predicate.FALSE. + * AND predicate with no argument evaluates to TRUE. + * OR predicate with no argument evaluates to FALSE. + * Negation of a Predicate creates a new Predicate. + * + * @author Pinaki Poddar + * + */ +public abstract class PredicateImpl extends ExpressionImpl implements Predicate { private static final ExpressionImpl ONE = new Expressions.Constant(1); - public static final ExpressionImpl TRUE = new Expressions.Equal(ONE,ONE); - public static final ExpressionImpl FALSE = new Expressions.Equal(ONE,ONE).negate(); + public static final Predicate TRUE = new Expressions.Equal(ONE,ONE); + public static final Predicate FALSE = new Expressions.NotEqual(ONE,ONE); - List> _exps; + protected final List _exps = new ArrayList(); protected final BooleanOperator _op; - private boolean _negated = false; + protected boolean _negated = false; /** - * A predicate with empty name and AND operator. + * A predicate no arguments representing AND operator. */ protected PredicateImpl() { this(BooleanOperator.AND); } /** - * A predicate with given name and given operator. + * A predicate representing given operator. */ protected PredicateImpl(BooleanOperator op) { super(Boolean.class); @@ -54,13 +66,13 @@ public class PredicateImpl extends ExpressionImpl implements Predicate } /** - * A predicate with given name, given operator with given arguments. + * A predicate of given operator with given arguments. */ protected PredicateImpl(BooleanOperator op, Predicate...restrictions) { this(op); if (restrictions != null) { for (Predicate p : restrictions) - add((PredicateImpl)p); + add(p); } } @@ -68,14 +80,16 @@ public class PredicateImpl extends ExpressionImpl implements Predicate * Adds the given predicate expression. */ public PredicateImpl add(Expression s) { - if (_exps == null) - _exps = new ArrayList>(); - _exps.add(s); + _exps.add((Predicate)s); // all boolean expressions are Predicate return this; } public List> getExpressions() { - return Expressions.returnCopy(_exps); + List> result = new CopyOnWriteArrayList>(); + if (_exps.isEmpty()) + return result; + result.addAll(_exps); + return result; } public final BooleanOperator getOperator() { @@ -86,38 +100,38 @@ public class PredicateImpl extends ExpressionImpl implements Predicate return _negated; } + /** + * Default negation creates a Not expression with this receiver as delegate. + * Derived predicates can return the inverse expression such as NotEqual + * for Equal or LessThan for GreaterThanEqual etc. + */ public PredicateImpl negate() { - PredicateImpl not = clone(); - not._negated = true; - return not; + return new Expressions.Not(this).markNegated(); } - - public PredicateImpl clone() { - PredicateImpl clone = new PredicateImpl(_op); - if (_exps != null) - clone._exps = new ArrayList>(this._exps); - return clone; + + protected PredicateImpl markNegated() { + _negated = true; + return this; } @Override - org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, MetamodelImpl model, + org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { - throw new AbstractMethodError(); + throw new AbstractMethodError(this.getClass().getName()); } @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { - if (_exps == null || _exps.isEmpty()) { - ExpressionImpl nil = _op == BooleanOperator.AND ? TRUE : FALSE; - return nil.toKernelExpression(factory, model, q); + if (_exps.isEmpty()) { + Predicate nil = _op == BooleanOperator.AND ? TRUE : FALSE; + return ((PredicateImpl)nil).toKernelExpression(factory, model, q); } if (_exps.size() == 1) { - ExpressionImpl e0 = (ExpressionImpl)_exps.get(0); - if (e0 instanceof Expressions.Constant && e0.getJavaType() == Boolean.class) { - e0 = Boolean.TRUE.equals(((Expressions.Constant)e0).arg) ? TRUE : FALSE; - } - return e0.toKernelExpression(factory, model, q); + Predicate e0 = _exps.get(0); + if (isNegated()) + e0 = e0.negate(); + return ((PredicateImpl)e0).toKernelExpression(factory, model, q); } ExpressionImpl e1 = (ExpressionImpl)_exps.get(0); @@ -128,27 +142,30 @@ public class PredicateImpl extends ExpressionImpl implements Predicate ? factory.and(ke1,ke2) : factory.or(ke1, ke2); for (int i = 2; i < _exps.size(); i++) { - ExpressionImpl e = (ExpressionImpl)_exps.get(i); + PredicateImpl p = (PredicateImpl)_exps.get(i); result = _op == BooleanOperator.AND - ? factory.and(result, e.toKernelExpression(factory, model, q)) - : factory.or(result, e.toKernelExpression(factory,model,q)); + ? factory.and(result, p.toKernelExpression(factory, model, q)) + : factory.or(result, p.toKernelExpression(factory,model,q)); } return _negated ? factory.not(result) : result; } public void acceptVisit(CriteriaExpressionVisitor visitor) { - Expressions.acceptVisit(visitor, this, _exps == null ? null : _exps.toArray(new Expression[_exps.size()])); + Expressions.acceptVisit(visitor, this, _exps.toArray(new Expression[_exps.size()])); } - public StringBuilder asValue(CriteriaQueryImpl q) { - boolean braces = _exps != null && _exps.size() > 1; - StringBuilder buffer = Expressions.asValue(q, _exps == null ? null : - _exps.toArray(new Expression[_exps.size()]), " " +_op + " "); + public StringBuilder asValue(AliasContext q) { + boolean braces = _exps.size() > 1; + StringBuilder buffer = Expressions.asValue(q, _exps.toArray(new Expression[_exps.size()]), " " +_op + " "); if (braces) buffer.insert(0, "(").append(")"); + if (isNegated()) buffer.insert(0, "NOT "); return buffer; } - + /** + * Concrete AND predicate. + * + */ public static class And extends PredicateImpl { public And(Expression x, Expression y) { super(BooleanOperator.AND); @@ -160,6 +177,10 @@ public class PredicateImpl extends ExpressionImpl implements Predicate } } + /** + * Concrete OR predicate. + * + */ public static class Or extends PredicateImpl { public Or(Expression x, Expression y) { super(BooleanOperator.OR); diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java index d582e4149..2ae3195a6 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java @@ -99,7 +99,7 @@ public class RootImpl extends FromImpl implements Root { return factory.bindVariable(var, path); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { Value v = q.getRegisteredRootVariable(this); if (v != null) return new StringBuilder(v.getAlias()); @@ -111,7 +111,7 @@ public class RootImpl extends FromImpl implements Root { return new StringBuilder().append(Character.toLowerCase(_entity.getName().charAt(0))); } - public StringBuilder asVariable(CriteriaQueryImpl q) { + public StringBuilder asVariable(AliasContext q) { return new StringBuilder(_entity.getName()).append(" ").append(asValue(q)); } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java index 7dcb62511..dc91807ec 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java @@ -52,11 +52,11 @@ public class SelectionImpl extends TupleElementImpl return false; } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { throw new IllegalStateException(this.getClass().getSimpleName() + " can not be rendered as value"); } - public StringBuilder asVariable(CriteriaQueryImpl q) { + public StringBuilder asVariable(AliasContext q) { throw new IllegalStateException(this.getClass().getSimpleName() + " can not be rendered as variable"); } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java index 72161b737..e8118c76b 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java @@ -379,13 +379,13 @@ public class SubqueryImpl extends ExpressionImpl implements Subquery { return getJavaType(); } - public StringBuilder asValue(CriteriaQueryImpl q) { + public StringBuilder asValue(AliasContext q) { StringBuilder buffer = new StringBuilder(); _delegate.render(buffer, _delegate.getRoots(), _corrJoins); return buffer; } - public StringBuilder asVariable(CriteriaQueryImpl q) { + public StringBuilder asVariable(AliasContext q) { return asValue(q); } }