throws WrappedException, IndexOutOfBoundsException, TranslationException
{
visitFromClause(ctx.tableExpression().fromClause());
/* {@code state.formula} now represents the tables in the FROM clause*/
final RaTermBuilder raBuilder = RaTermBuilder.create();
List<Expression> selected =
processSelectList(raBuilder, ctx.selectList());
boolean isSelectAsterisk = (selected == null);
if (isSelectAsterisk) {
// TODO refactor, move to {@link processSelectList}
selected = state.nonParameterAttributes();
}
/* {@link #scopeIncludingAliases} now includes column aliases, as defined in the SELECT clause,
* used in {@link #visitColumnReference} when interpreting references to columns.
* Will be null for SELECT * queries
*/
GroupByClauseContext groupByClause;
HavingClauseContext havingClause;
groupByClause = ctx.tableExpression().groupByClause(); /* null if no GROUP BY clause is present */
havingClause = ctx.tableExpression().havingClause();
if (groupByClause != null && isSelectAsterisk) {
/* SELECT * FROM.. GROUP BY.. */
throw new TranslationException("a query cannot have the form of 'SELECT * ... GROUP BY'");
}
if (havingClause != null && isSelectAsterisk) {
/* SELECT * FROM.. HAVING.. */
throw new TranslationException("a query cannot have the form of 'SELECT * ... HAVING'");
}
List<SimpleColumn> groupByExpressions = null;
if (groupByClause != null) {
groupByExpressions = Lists.newArrayList(visitGroupByClause(groupByClause));
} else if (havingClause != null) {
groupByExpressions = Lists.<SimpleColumn>newArrayList();
}
processWhereClause(ctx.tableExpression().whereClause());
raBuilder.select(selected);
raBuilder.groupBy(groupByExpressions);
raBuilder.withBaseRelation(state.rela);
raBuilder.withQueryParameters(state.parameterAttributes());
if (havingClause != null) {
// TODO do not use WrappedException in InterpretsColumnReferences
Proposition havingCondition = ConditionTranslation.of(columnNamesLookupForHaving(raBuilder), raBuilder, havingClause.searchCondition()).proposition();
raBuilder.withHaving(havingCondition);
}
state.rela = raBuilder.build();
state.updateColumnScopeWithRelationsColumns();
// TODO test this further in SelectFromTest.SelectDistinct
boolean selectDistinct = ctx.setQuantifier() != null && ctx.setQuantifier().DISTINCT() != null;