package jeql.syntax;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import jeql.api.row.RowSchema;
import jeql.engine.CompilationException;
import jeql.engine.Scope;
/**
* A list of {@link SelectItemNode}s.
* Maybe be constructed during parse,
* or during SELECT transformation.
*
* @author Martin Davis
* @version 1.0
*/
public class SelectItemList
{
List items = new ArrayList();
List finalItems = new ArrayList();
public SelectItemList() {
}
public void add(SelectItemNode item)
{
items.add(item);
}
public List getItems() { return items; }
public List getFinalItems() { return finalItems; }
public void bind(Scope scope)
{
for (Iterator i = finalItems.iterator(); i.hasNext(); ) {
SelectItemNode item = (SelectItemNode) i.next();
item.bind(scope);
}
}
public void expand(Scope scope) {
finalItems = new ArrayList();
Set itemNames = new HashSet();
int colIndex = 0;
for (Iterator i = items.iterator(); i.hasNext();) {
SelectItemNode item = (SelectItemNode) i.next();
if (item.getItem() instanceof TableRefNode) {
TableRefNode tblStar = (TableRefNode) item.getItem();
List starCols = tblStar.prepareStarSelectItems(scope);
//List starCols = tblStar.prepareStarSelectItems(scope, itemNames);
addColNames(starCols, colIndex, itemNames);
finalItems.addAll(starCols);
colIndex += starCols.size();
} else {
finalItems.add(item);
itemNames.add(item.getName(colIndex));
}
colIndex++;
}
}
private static void addColNames(List selItems, int startIndex, Set names)
{
for (Iterator i = selItems.iterator(); i.hasNext(); ) {
SelectItemNode item = (SelectItemNode) i.next();
names.add(item.getName(startIndex++));
}
}
public String[] getResultColumnNames()
{
String[] colName = new String[finalItems.size()];
for (int i = 0; i < finalItems.size(); i++) {
SelectItemNode item = (SelectItemNode) finalItems.get(i);
String name = item.getName(i + 1);
colName[i] = name;
}
return colName;
}
public void checkUniqueNames()
{
Set namesSet = new TreeSet();
for (int i = 0; i < finalItems.size(); i++) {
SelectItemNode item = (SelectItemNode) finalItems.get(i);
String name = item.getName(i + 1);
if (namesSet.contains(name))
throw new CompilationException(item, "Duplicate column names in result table: " + name);
namesSet.add(name);
}
}
public RowSchema computeRowSchema(Scope scope)
{
RowSchema rs = new RowSchema(finalItems.size());
for (int i = 0; i < finalItems.size(); i++) {
SelectItemNode item = (SelectItemNode) finalItems.get(i);
Class colType = item.getType(scope);
if (colType == null)
throw new CompilationException(item, "Unable to determine type of select list item (#" + (i + 1)
+ " - " + item
+ " )");
rs.setColumnDef(i, item.getName(i), colType);
}
return rs;
}
}