boolean added = false;
do {
added = false;
Set<SelectorName> viewNames = new HashSet<SelectorName>(definitions.keySet());
for (SelectorName name : viewNames) {
QueryCommand command = definitions.get(name);
// Create the canonical plan for the definition ...
QueryContext queryContext = new QueryContext(schemata, typeSystem);
CanonicalPlanner planner = new CanonicalPlanner();
PlanNode plan = planner.createPlan(queryContext, command);
if (queryContext.getProblems().hasErrors()) {
continue;
}
// Get the columns from the top-level PROJECT ...
PlanNode project = plan.findAtOrBelow(Type.PROJECT);
assert project != null;
List<org.jboss.dna.graph.query.model.Column> columns = project.getPropertyAsList(Property.PROJECT_COLUMNS,
org.jboss.dna.graph.query.model.Column.class);
assert !columns.isEmpty();
// Go through all the columns and look up the types ...
List<Column> viewColumns = new ArrayList<Column>(columns.size());
for (org.jboss.dna.graph.query.model.Column column : columns) {
// Find the table that the column came from ...
Table source = schemata.getTable(column.getSelectorName());
if (source == null) break;
String viewColumnName = column.getColumnName();
String sourceColumnName = column.getPropertyName(); // getColumnName() returns alias
Column sourceColumn = source.getColumn(sourceColumnName);
if (sourceColumn == null) {
throw new InvalidQueryException(Visitors.readable(command),
"The view references a non-existant column '"
+ column.getColumnName() + "' in '" + source.getName() + "'");
}
viewColumns.add(new ImmutableColumn(viewColumnName, sourceColumn.getPropertyType(),
sourceColumn.isFullTextSearchable()));
}
if (viewColumns.size() != columns.size()) {
// We weren't able to resolve all of the columns,
// so maybe the columns were referencing yet-to-be-built views ...
continue;
}
// If we could resolve the definition ...
ImmutableView view = new ImmutableView(name, viewColumns, command);
definitions.remove(name);
schemata = schemata.with(view);
added = true;
}
} while (added && !definitions.isEmpty());
if (!definitions.isEmpty()) {
QueryCommand command = definitions.values().iterator().next();
throw new InvalidQueryException(Visitors.readable(command), "The view definition cannot be resolved: "
+ Visitors.readable(command));
}
return schemata;