HashMap<Column, ArrayList<AbstractExpression>> eqColumns = new HashMap<Column, ArrayList<AbstractExpression>>();
HashMap<Column, ArrayList<AbstractExpression>> gtColumns = new HashMap<Column, ArrayList<AbstractExpression>>();
HashMap<Column, ArrayList<AbstractExpression>> ltColumns = new HashMap<Column, ArrayList<AbstractExpression>>();
for (AbstractExpression expr : exprs)
{
Column col = getColumnForFilterExpression(table, expr);
if (col != null)
{
if (expr.getExpressionType() == ExpressionType.COMPARE_EQUAL)
{
if (eqColumns.containsKey(col) == false)
eqColumns.put(col, new ArrayList<AbstractExpression>());
eqColumns.get(col).add(expr);
}
else if ((expr.getExpressionType() == ExpressionType.COMPARE_GREATERTHAN) ||
(expr.getExpressionType() == ExpressionType.COMPARE_GREATERTHANOREQUALTO))
{
if (gtColumns.containsKey(col) == false)
gtColumns.put(col, new ArrayList<AbstractExpression>());
gtColumns.get(col).add(expr);
}
else if ((expr.getExpressionType() == ExpressionType.COMPARE_LESSTHAN) ||
(expr.getExpressionType() == ExpressionType.COMPARE_LESSTHANOREQUALTO))
{
if (ltColumns.containsKey(col) == false)
ltColumns.put(col, new ArrayList<AbstractExpression>());
ltColumns.get(col).add(expr);
}
else
{
retval.otherExprs.add(expr);
}
}
else
{
retval.otherExprs.add(expr);
}
}
// See if we can use index scan for ORDER BY.
// The only scenario where we can use index scan is when the ORDER BY
// columns is a subset of the tree index columns, in the same order from
// left to right. It also requires that all columns are ordered in the
// same direction. For example, if a table has a tree index of columns
// A, B, C, then 'ORDER BY A, B', 'ORDER BY A DESC, B DESC, C DESC'
// work, but not 'ORDER BY A, C' or 'ORDER BY A, B DESC'.
if (indexScannable && m_parsedStmt instanceof ParsedSelectStmt) {
ParsedSelectStmt parsedSelectStmt = (ParsedSelectStmt) m_parsedStmt;
if (!parsedSelectStmt.orderColumns.isEmpty()) {
List<ColumnRef> sortedColumns = CatalogUtil.getSortedCatalogItems(index.getColumns(), "index");
Iterator<ColumnRef> colRefIter = sortedColumns.iterator();
boolean ascending = parsedSelectStmt.orderColumns.get(0).ascending;
for (ParsedColInfo colInfo : parsedSelectStmt.orderColumns) {
if (!colRefIter.hasNext()) {
retval.sortDirection = SortDirectionType.INVALID;
break;
}
ColumnRef colRef = colRefIter.next();
if (colInfo.tableName.equals(table.getTypeName()) &&
colInfo.columnName.equals(colRef.getColumn().getTypeName()) &&
colInfo.ascending == ascending) {
if (ascending)
retval.sortDirection = SortDirectionType.ASC;
else
retval.sortDirection = SortDirectionType.DESC;
retval.use = IndexUseType.INDEX_SCAN;
} else {
retval.sortDirection = SortDirectionType.INVALID;
break;
}
}
}
}
// cover as much of the index as possible with expressions that use
// index columns
for (ColumnRef colRef : CatalogUtil.getSortedCatalogItems(index.getColumns(), "index")) {
Column col = colRef.getColumn();
if (eqColumns.containsKey(col) && (eqColumns.get(col).size() >= 0)) {
AbstractExpression expr = eqColumns.get(col).remove(0);
retval.indexExprs.add(expr);
retval.endExprs.add(expr);
} else {