package jeql.engine.query;
import java.util.List;
import jeql.api.row.BasicRow;
import jeql.api.row.Row;
import jeql.api.row.RowIterator;
import jeql.api.row.RowList;
import jeql.api.row.RowSchema;
import jeql.syntax.ParseTreeNode;
import jeql.syntax.SelectItemList;
import jeql.syntax.SelectItemNode;
import jeql.syntax.StatementListNode;
/**
* A {@link RowList} of the computed selected items in a select expression
*
* @author Martin Davis
*
*/
public class SelectedItemsRowList
implements RowList
{
private RowSchema schema;
private RowList baseRowStr;
private List selectedItems;
private StatementListNode aliasList;
private QueryScope scope;
public SelectedItemsRowList(RowList baseRowStr,
SelectItemList selectedItems,
StatementListNode aliasList,
QueryScope scope)
{
this.baseRowStr = baseRowStr;
this.selectedItems = selectedItems.getFinalItems();
this.aliasList = aliasList;
this.scope = scope;
schema = selectedItems.computeRowSchema(scope);
}
public RowSchema getSchema() { return schema; }
public RowIterator iterator()
{
return new SelectedItemsRowIterator(schema, baseRowStr, selectedItems, aliasList, scope);
}
private static class SelectedItemsRowIterator
implements RowIterator
{
private RowSchema schema;
private RowList rowList;
private List selectedItems;
private StatementListNode aliasList;
private QueryScope scope;
private RowIterator it;
private int rowNum = 0;
public SelectedItemsRowIterator(RowSchema schema, RowList rowList,
List selectedItems,
StatementListNode aliasList,
QueryScope scope)
{
this.schema = schema;
this.rowList = rowList;
this.selectedItems = selectedItems;
this.aliasList = aliasList;
this.scope = scope;
rowNum = 0;
}
public RowSchema getSchema() { return schema; }
public Row next()
{
if (it == null)
it = rowList.iterator();
Row baseRow = it.next();
if (baseRow == null) return null;
rowNum++;
scope.setRowNum(rowNum);
// post the current base row in the scope so the select expressions can access it
scope.setRow(baseRow);
// evaluate alias assignments for this row
SelectEvaluator.evalAliases(aliasList, scope);
Row outRow = createRow();
return outRow;
}
private Row createRow()
{
// build a new row containing the values of the selected items (expressions)
BasicRow row = new BasicRow(selectedItems.size());
for (int i = 0; i < selectedItems.size(); i++) {
SelectItemNode item = (SelectItemNode) selectedItems.get(i);
ParseTreeNode expr = item.getItem();
Object value = expr.eval(scope);
row.setValue(i, value);
}
return row;
}
}
}