}
protected static IntIterator getComparisonIterator(Table t,
ComparisonPredicate cp)
{
Expression l = cp.getLeftExpression();
Expression r = cp.getRightExpression();
int operation = cp.getOperation();
// not equals operations aren't handled by the index
if ( operation == ComparisonPredicate.NEQ )
return null;
ColumnExpression col;
Expression lit;
// make sure columns are of the right type
if (l instanceof ColumnExpression &&
!ExpressionAnalyzer.hasDependency(r))
{
col = (ColumnExpression)l;
lit = r;
} else if (r instanceof ColumnExpression &&
!ExpressionAnalyzer.hasDependency(l))
{
col = (ColumnExpression)r;
lit = l;
} else {
return null;
}
// if table has index of the right type, use it
Comparator cmp = cp.getComparator();
Index index = t.getIndex(col.getColumnName());
if ( index == null || !cmp.equals(index.getComparator()) )
return null;
Class ltype = lit.getClass();
if ( ltype == int.class ) {
int val = lit.getInt(null); // literal value, so null is safe
switch ( operation ) {
case ComparisonPredicate.LT:
return index.rows(Integer.MIN_VALUE, val, Index.TYPE_AIE);
case ComparisonPredicate.GT:
return index.rows(val, Integer.MAX_VALUE, Index.TYPE_AEI);
case ComparisonPredicate.EQ:
return index.rows(val, val, Index.TYPE_AII);
case ComparisonPredicate.LTEQ:
return index.rows(Integer.MIN_VALUE, val, Index.TYPE_AII);
case ComparisonPredicate.GTEQ:
return index.rows(val, Integer.MAX_VALUE, Index.TYPE_AII);
default:
throw new IllegalStateException(); // should never occur
}
} else if ( ltype == long.class ) {
long val = lit.getLong(null); // literal value, so null is safe
switch ( operation ) {
case ComparisonPredicate.LT:
return index.rows(Long.MIN_VALUE, val, Index.TYPE_AIE);
case ComparisonPredicate.GT:
return index.rows(val, Long.MAX_VALUE, Index.TYPE_AEI);
case ComparisonPredicate.EQ:
return index.rows(val, val, Index.TYPE_AII);
case ComparisonPredicate.LTEQ:
return index.rows(Long.MIN_VALUE, val, Index.TYPE_AII);
case ComparisonPredicate.GTEQ:
return index.rows(val, Long.MAX_VALUE, Index.TYPE_AII);
default:
throw new IllegalStateException(); // should never occur
}
} else if ( ltype == float.class ) {
float val = lit.getFloat(null); // literal value, so null is safe
switch ( operation ) {
case ComparisonPredicate.LT:
return index.rows(Float.MIN_VALUE, val, Index.TYPE_AIE);
case ComparisonPredicate.GT:
return index.rows(val, Float.MAX_VALUE, Index.TYPE_AEI);
case ComparisonPredicate.EQ:
return index.rows(val, val, Index.TYPE_AII);
case ComparisonPredicate.LTEQ:
return index.rows(Float.MIN_VALUE, val, Index.TYPE_AII);
case ComparisonPredicate.GTEQ:
return index.rows(val, Float.MAX_VALUE, Index.TYPE_AII);
default:
throw new IllegalStateException(); // should never occur
}
} else if ( ltype == double.class ) {
double val = lit.getDouble(null); // literal value, so null is safe
switch ( operation ) {
case ComparisonPredicate.LT:
return index.rows(Double.MIN_VALUE, val, Index.TYPE_AIE);
case ComparisonPredicate.GT:
return index.rows(val, Double.MAX_VALUE, Index.TYPE_AEI);
case ComparisonPredicate.EQ:
return index.rows(val, val, Index.TYPE_AII);
case ComparisonPredicate.LTEQ:
return index.rows(Double.MIN_VALUE, val, Index.TYPE_AII);
case ComparisonPredicate.GTEQ:
return index.rows(val, Double.MAX_VALUE, Index.TYPE_AII);
default:
throw new IllegalStateException(); // should never occur
}
} else {
Object val = lit.get(null); // literal value, so null is safe
switch ( operation ) {
case ComparisonPredicate.LT:
return index.rows(null, val, Index.TYPE_AIE);
case ComparisonPredicate.GT:
return index.rows(val, null, Index.TYPE_AEI);