package jeql.engine.query;
import jeql.api.row.Row;
import jeql.api.row.RowIterator;
import jeql.api.row.RowList;
import jeql.api.row.RowSchema;
import jeql.syntax.ParseTreeNode;
public class FilterRowList
implements RowList
{
private RowList rowStr;
private ParseTreeNode filterExpr;
private QueryScope scope;
public FilterRowList(RowList rowStr, ParseTreeNode filterExpr, QueryScope scope)
{
this.rowStr = rowStr;
this.filterExpr = filterExpr;
this.scope = scope;
}
public RowSchema getSchema() { return rowStr.getSchema(); }
public RowIterator iterator()
{
return new FilterRowIterator(rowStr, filterExpr, scope);
}
private static class FilterRowIterator implements RowIterator {
private RowSchema schema;
private ParseTreeNode filterExpr;
private QueryScope scope;
private RowIterator it;
private int rowNum = 0;
public FilterRowIterator(RowList rowList,
ParseTreeNode filterExpr, QueryScope scope) {
schema = rowList.getSchema();
this.filterExpr = filterExpr;
this.scope = scope;
it = rowList.iterator();
rowNum = 0;
}
public RowSchema getSchema() {
return schema;
}
public Row next() {
// short-circuit if no filter expr
if (filterExpr == null) {
rowNum++;
// set rownum for use in where clause expressions
scope.setRowNum(rowNum);
return it.next();
}
while (true) {
rowNum++;
// set rownum for use in where clause expressions
scope.setRowNum(rowNum);
Row row = it.next();
if (row == null)
return null;
if (isAccepted(row))
return row;
}
}
private boolean isAccepted(Row row) {
if (filterExpr == null)
return true;
((QueryScope) scope).setRow(row);
boolean isAccepted = ((Boolean) filterExpr.eval(scope)).booleanValue();
return isAccepted;
}
}
}