boolean isStreamWildcard = false;
if (selectClauseSpec.getSelectExprList().size() > 0)
{
List<ExprAggregateNode> aggExprNodes = new LinkedList<ExprAggregateNode>();
ExprEvaluatorContextStatement evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext);
ExprValidationContext validationContext = new ExprValidationContext(subselectTypeService, statementContext.getMethodResolutionService(), viewResourceDelegateSubselect, statementContext.getSchedulingService(), statementContext.getVariableService(), evaluatorContextStmt, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
for (int i = 0; i < selectClauseSpec.getSelectExprList().size(); i++) {
SelectClauseElementCompiled element = selectClauseSpec.getSelectExprList().get(i);
if (element instanceof SelectClauseExprCompiledSpec)
{
// validate
SelectClauseExprCompiledSpec compiled = (SelectClauseExprCompiledSpec) element;
ExprNode selectExpression = compiled.getSelectExpression();
selectExpression = ExprNodeUtility.getValidatedSubtree(selectExpression, validationContext);
selectExpressions.add(selectExpression);
assignedNames.add(compiled.getAssignedName());
// handle aggregation
ExprAggregateNodeUtil.getAggregatesBottomUp(selectExpression, aggExprNodes);
if (aggExprNodes.size() > 0)
{
// This stream (stream 0) properties must either all be under aggregation, or all not be.
List<Pair<Integer, String>> propertiesNotAggregated = ExprNodeUtility.getExpressionProperties(selectExpression, false);
for (Pair<Integer, String> pair : propertiesNotAggregated)
{
if (pair.getFirst() == 0)
{
throw new ExprValidationException("Subselect properties must all be within aggregation functions");
}
}
}
}
else if (element instanceof SelectClauseElementWildcard) {
isWildcard = true;
}
else if (element instanceof SelectClauseStreamCompiledSpec) {
isStreamWildcard = true;
}
} // end of for loop
if (!selectExpressions.isEmpty()) {
subselect.setSelectClause(selectExpressions.toArray(new ExprNode[selectExpressions.size()]));
subselect.setSelectAsNames(assignedNames.toArray(new String[assignedNames.size()]));
if (isWildcard || isStreamWildcard) {
throw new ExprValidationException("Subquery multi-column select does not allow wildcard or stream wildcard when selecting multiple columns.");
}
if (selectExpressions.size() > 1 && !subselect.isAllowMultiColumnSelect()) {
throw new ExprValidationException("Subquery multi-column select is not allowed in this context.");
}
if ((selectExpressions.size() > 1 && aggExprNodes.size() > 0)) {
// all properties must be aggregated
if (!ExprNodeUtility.getNonAggregatedProps(subselectTypeService.getEventTypes(), selectExpressions, contextPropertyRegistry).isEmpty()) {
throw new ExprValidationException("Subquery with multi-column select requires that either all or none of the selected columns are under aggregation.");
}
}
}
if (aggExprNodes.size() > 0)
{
List<ExprAggregateNode> havingAgg = Collections.emptyList();
List<ExprAggregateNode> orderByAgg = Collections.emptyList();
aggregationServiceFactoryDesc = AggregationServiceFactoryFactory.getService(aggExprNodes, havingAgg, orderByAgg, false, evaluatorContextStmt, annotations, statementContext.getVariableService(), false, statementSpec.getFilterRootNode(), statementSpec.getHavingExprRootNode());
// Other stream properties, if there is aggregation, cannot be under aggregation.
for (ExprAggregateNode aggNode : aggExprNodes)
{
List<Pair<Integer, String>> propertiesNodesAggregated = ExprNodeUtility.getExpressionProperties(aggNode, true);
for (Pair<Integer, String> pair : propertiesNodesAggregated)
{
if (pair.getFirst() != 0)
{
throw new ExprValidationException("Subselect aggregation functions cannot aggregate across correlated properties");
}
}
}
}
}
// no aggregation functions allowed in filter
if (statementSpec.getFilterRootNode() != null)
{
List<ExprAggregateNode> aggExprNodesFilter = new LinkedList<ExprAggregateNode>();
ExprAggregateNodeUtil.getAggregatesBottomUp(statementSpec.getFilterRootNode(), aggExprNodesFilter);
if (aggExprNodesFilter.size() > 0)
{
throw new ExprValidationException("Aggregation functions are not supported within subquery filters, consider using insert-into instead");
}
}
// Validate filter expression, if there is one
ExprNode filterExpr = statementSpec.getFilterRootNode();
boolean correlatedSubquery = false;
if (filterExpr != null)
{
ExprEvaluatorContextStatement evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext);
ExprValidationContext validationContext = new ExprValidationContext(subselectTypeService, statementContext.getMethodResolutionService(), viewResourceDelegateSubselect, statementContext.getSchedulingService(), statementContext.getVariableService(), evaluatorContextStmt, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
filterExpr = ExprNodeUtility.getValidatedSubtree(filterExpr, validationContext);
if (JavaClassHelper.getBoxedType(filterExpr.getExprEvaluator().getType()) != Boolean.class)
{
throw new ExprValidationException("Subselect filter expression must return a boolean value");