for (ParsedColInfo candidateCol : candidateColumns)
{
if (candidateCol.orderBy) {
continue;
}
AbstractExpression candidateExpr = candidateCol.expression;
if (orderByExprs == null) {
orderByExprs = new HashSet<AbstractExpression>();
for (ParsedColInfo orderByCol : m_orderColumns) {
orderByExprs.add(orderByCol.expression);
}
}
if (orderByExprs.contains(candidateExpr)) {
continue;
}
if (candidateExpr instanceof TupleValueExpression) {
// Simple column references can only be exactly equal to but not "based on" an ORDER BY.
return false;
}
if (candidateExprHardCases == null) {
candidateExprHardCases = new ArrayList<AbstractExpression>();
}
candidateExprHardCases.add(candidateExpr);
}
if (candidateExprHardCases == null) {
return true;
}
// Plan B. profile the ORDER BY list and try to include/exclude the hard cases on that basis.
HashSet<AbstractExpression> orderByTVEs = new HashSet<AbstractExpression>();
ArrayList<AbstractExpression> orderByNonTVEs = new ArrayList<AbstractExpression>();
ArrayList<List<AbstractExpression>> orderByNonTVEBaseTVEs = new ArrayList<List<AbstractExpression>>();
HashSet<AbstractExpression> orderByAllBaseTVEs = new HashSet<AbstractExpression>();
for (AbstractExpression orderByExpr : orderByExprs) {
if (orderByExpr instanceof TupleValueExpression) {
orderByTVEs.add(orderByExpr);
orderByAllBaseTVEs.add(orderByExpr);
} else {
orderByNonTVEs.add(orderByExpr);
List<AbstractExpression> baseTVEs = orderByExpr.findBaseTVEs();
orderByNonTVEBaseTVEs.add(baseTVEs);
orderByAllBaseTVEs.addAll(baseTVEs);
}
}
boolean result = true;
for (AbstractExpression candidateExpr : candidateExprHardCases)
{
Collection<AbstractExpression> candidateBases = candidateExpr.findBaseTVEs();
if (orderByTVEs.containsAll(candidateBases)) {
continue;
}
if (orderByAllBaseTVEs.containsAll(candidateBases) == false) {
if (outNonOrdered == null) {