package jeql.syntax;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import jeql.api.error.JeqlException;
import jeql.api.row.ArrayRowList;
import jeql.api.row.BasicRow;
import jeql.api.row.Row;
import jeql.api.row.RowSchema;
import jeql.engine.Scope;
public class ValuesNode
extends ParseTreeNode
{
List rows = new ArrayList();
public ValuesNode() {
}
public void add(List row)
{
rows.add(row);
}
public Class getType(Scope scope)
{
throw new UnsupportedOperationException();
}
public void bind(Scope scope)
{
for (Iterator i = rows.iterator(); i.hasNext(); ) {
List rowValues = (List) i.next();
for (Iterator iRow = rowValues.iterator(); iRow.hasNext(); ) {
ParseTreeNode node = (ParseTreeNode) iRow.next();
node.bind(scope);
}
}
}
public Object eval(Scope scope)
{
RowSchema schema = extractRowSchema((List) rows.get(0), scope);
ArrayRowList rs = new ArrayRowList(schema);
Row firstRow = null;
for (Iterator i = rows.iterator(); i.hasNext(); ) {
List rowValues = (List) i.next();
Row row = evalRow(rowValues, scope);
rs.add(row);
if (firstRow == null)
firstRow = row;
else {
// check consistency of subsequent rows
if (row.size() != firstRow.size())
throw new JeqlException("Values rows must have same size");
// check schema here too...
}
}
return rs;
}
public Row evalRow(List rowValues, Scope scope)
{
BasicRow row = new BasicRow(rowValues.size());
int i = 0;
for (Iterator iRow = rowValues.iterator(); iRow.hasNext(); ) {
ParseTreeNode node = (ParseTreeNode) iRow.next();
Object val = node.eval(scope);
row.setValue(i++, val);
}
return row;
}
public static RowSchema extractRowSchema(List rowValues, Scope scope)
{
RowSchema schema = new RowSchema(rowValues.size());
int i = 0;
for (Iterator iRow = rowValues.iterator(); iRow.hasNext(); ) {
ParseTreeNode node = (ParseTreeNode) iRow.next();
Class type = node.getType(scope);
schema.setColumnDef(i, RowSchema.getDefaultColumnName(i), type);
i++;
}
return schema;
}
}