return base;
}
else if (entityInfo.dbSetMethods.contains(sig))
{
if (lambdaContext.joins == null)
throw new TypedValueVisitorException("Need a join handler here for subqueries just in case there's an embedded navigational query: " + val);
// TODO: Handle checking out the constructor and verifying how
// parameters pass through the constructor
SQLQuery subQuery = val.base.visit(subQueryHandler, in);
if (sig.equals(TransformationClassAnalyzer.dbsetSumInt)
|| sig.equals(TransformationClassAnalyzer.dbsetMaxInt))
{
// TODO: do subqueries need to be copied before being passed in here?
SQLQuery<Integer> newQuery = null;
if (sig.equals(TransformationClassAnalyzer.dbsetSumInt))
newQuery = queryMethodHandler.sumInt(subQuery, val.args.get(0), lambdaContext.joins.getEntityManager());
else if (sig.equals(TransformationClassAnalyzer.dbsetMaxInt))
newQuery = queryMethodHandler.maxInt(subQuery, val.args.get(0), lambdaContext.joins.getEntityManager());
if (newQuery == null) throw new TypedValueVisitorException("Could not decode a subquery " + val);
if (newQuery instanceof SQLQuery.InternalGroup)
{
SQLQuery.InternalGroup<Integer> agg = (SQLQuery.InternalGroup<Integer>)newQuery;
// TODO: This is probably correct but potentially bogus.
// It should be thought through a bit more wrt what InternalGroup
// means and whether that is sufficient to allow us to do this
assert(agg.reader instanceof SQLReader.IntegerSQLReader);
SQLColumnValues<Integer> toReturn = new SQLColumnValues<Integer>(agg.reader);
toReturn.columns[0] = agg.columns.get(0);
return toReturn;
}
else if (newQuery instanceof SQLQuery.SelectFromWhere)
{
SQLQuery.SelectFromWhere<Integer> subquery = (SQLQuery.SelectFromWhere<Integer>)newQuery;
assert(subquery.reader instanceof SQLReader.IntegerSQLReader);
SQLColumnValues<Integer> toReturn = new SQLColumnValues<Integer>(subquery.reader);
toReturn.columns[0].add(new SQLSubstitution.ScalarSelectFromWhereSubQuery(subquery));
return toReturn;
}
else
throw new TypedValueVisitorException("Unhandled nesting of a query");
}
// TODO: Implement other aggregation functions
throw new TypedValueVisitorException("Unhandled DBSet operation");
}
else if (entityInfo.N111Methods.containsKey(sig))
{
SQLColumnValues base = val.base.visit(this, in);
ORMInformation.N111NavigationalLink link = entityInfo.N111Methods.get(sig);
if (lambdaContext.joins == null)
throw new TypedValueVisitorException("Cannot handle navigational queries in this context: " + val);
assert(link.joinInfo.size() == 1);
// See if we've already done this join and can reuse it
List<SQLFragment> fromKey = new ArrayList<SQLFragment>();
for (int n = 0; n < link.joinInfo.get(0).fromColumns.size(); n++)
{
String fromCol = link.joinInfo.get(0).fromColumns.get(n);
int fromColIdx = base.reader.getColumnIndexForColumnName(fromCol);
if (fromColIdx < 0) throw new TypedValueVisitorException("Cannot find column for navigational query: " + val);
fromKey.add(base.getColumn(fromColIdx));
}
SQLSubstitution.FromReference from = lambdaContext.joins.findExistingJoin(link.fromEntity, link.name, fromKey);
if (from == null)
{
from = lambdaContext.joins.addFrom(link.joinInfo.get(0).toTableName);
for (int n = 0; n < link.joinInfo.get(0).fromColumns.size(); n++)
{
SQLFragment where = new SQLFragment();
String fromCol = link.joinInfo.get(0).fromColumns.get(n);
String toCol = link.joinInfo.get(0).toColumns.get(n);
int fromColIdx = base.reader.getColumnIndexForColumnName(fromCol);
if (fromColIdx < 0) throw new TypedValueVisitorException("Cannot find column for navigational query: " + val);
where.add("(");
where.add(base.getColumn(fromColIdx));
where.add(") = (");
where.add(from);
where.add("." + toCol);