No need for parser to populate separate QueryExpressions.aggregate member now

that we can visit the projection values to see if they're aggregates.



git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@433431 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
A. Abram White 2006-08-21 23:53:49 +00:00
parent 9de5395486
commit d5bb522c34
6 changed files with 55 additions and 10 deletions

View File

@ -131,7 +131,7 @@ public class JDBCStoreQuery
ClassMetaData base, ClassMetaData[] metas, boolean subclasses,
ExpressionFactory[] facts, QueryExpressions[] exps, Object[] params,
boolean lrs, long startIdx, long endIdx) {
if (metas.length > 1 && exps[0].aggregate)
if (metas.length > 1 && exps[0].isAggregate())
throw new UserException(Localizer.forPackage(JDBCStoreQuery.class)
.get("mult-mapping-aggregate", Arrays.asList(metas)));

View File

@ -177,8 +177,8 @@ class SelectConstructor {
// get unique candidate values) and needed field values and
// applies the where conditions; the outer select applies
// ordering, grouping, etc
if (exps.aggregate || (exps.distinct & exps.DISTINCT_TRUE) == 0)
{
if (exps.isAggregate()
|| (exps.distinct & exps.DISTINCT_TRUE) == 0) {
DBDictionary dict = store.getDBDictionary();
dict.assertSupport(dict.supportsSubselect,
"SupportsSubselect");
@ -186,7 +186,7 @@ class SelectConstructor {
Select inner = sel;
sel = store.getSQLFactory().newSelect();
sel.setParent(parent, alias);
sel.setDistinct(exps.aggregate
sel.setDistinct(exps.isAggregate()
&& (exps.distinct & exps.DISTINCT_TRUE) != 0);
sel.setFromSelect(inner);
}

View File

@ -349,7 +349,7 @@ public class ExpressionStoreQuery
}
public final boolean isAggregate(StoreQuery q) {
return assertQueryExpression().aggregate;
return assertQueryExpression().isAggregate();
}
public final boolean hasGrouping(StoreQuery q) {

View File

@ -221,7 +221,7 @@ public class InMemoryExpressionFactory
return matches;
// if an ungrouped aggregate, evaluate the whole matches list
if (exps.grouping.length == 0 && exps.aggregate) {
if (exps.grouping.length == 0 && exps.isAggregate()) {
Object[] projection = project(matches, exps, true, ctx, params);
return Arrays.asList(new Object[]{ projection });
}

View File

@ -37,7 +37,11 @@ public class QueryExpressions {
public static final int DISTINCT_FALSE = 2 << 2;
public static final Value[] EMPTY_VALUES = new Value[0];
public boolean aggregate = false;
/**
* Map of {@link FieldMetaData},{@link Value} for update statements.
*/
public Map updates = null;
public int distinct = DISTINCT_AUTO;
public String alias = null;
public Value[] projections = EMPTY_VALUES;
@ -55,9 +59,51 @@ public class QueryExpressions {
public int operation = QueryOperations.OP_SELECT;
public ClassMetaData[] accessPath = StoreQuery.EMPTY_METAS;
public String[] fetchPaths = StoreQuery.EMPTY_STRINGS;
private Boolean _aggregate = null;
public boolean isAggregate() {
if (projections.length == 0)
return false;
if (_aggregate == null)
_aggregate = (AggregateExpressionVisitor.isAggregate(projections))
? Boolean.TRUE : Boolean.FALSE;
return _aggregate.booleanValue();
}
/**
* Map of {@link FieldMetaData},{@link Value} for update statements.
* Visitor to determine whether our projections are aggregates.
*/
public Map updates = null;
private static class AggregateExpressionVisitor
extends AbstractExpressionVisitor {
private Value _sub = null;
private boolean _agg = false;
/**
* Return whether the given values include projections.
*/
public static boolean isAggregate(Value[] vals) {
if (vals.length == 0)
return false;
AggregateExpressionVisitor v = new AggregateExpressionVisitor();
for (int i = 0; i < vals.length && !v._agg; i++)
vals[i].acceptVisit(v);
return v._agg;
}
public void enter(Value val) {
if (_agg)
return;
if (_sub == null) {
if (val.isAggregate())
_agg = true;
} else if (val instanceof Subquery)
_sub = val;
}
public void exit(Value val) {
if (val == _sub)
_sub = null;
}
}
}

View File

@ -286,7 +286,6 @@ class JPQLExpressionBuilder
JPQLNode parent = parametersNode.getChild(i);
JPQLNode node = onlyChild(parent);
Value proj = getValue(node);
exps.aggregate = exps.aggregate || node.id == JJTAGGREGATE;
exps.projections[i] = proj;
exps.projectionAliases[i] = nextAlias();