BufferManager bufferManager = new BufferManager(context);
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 ...
PlanHints hints = new PlanHints();
hints.validateColumnExistance = false;
// Create a query context that queries all workspaces (we won't actually query using it) ...
Set<String> allWorkspaces = Collections.emptySet();
RepositoryIndexes indexDefns = RepositoryIndexes.NO_INDEXES;
QueryContext queryContext = new QueryContext(context, null, allWorkspaces, schemata, indexDefns, nodeTypes,
bufferManager, hints, null);
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(PlanNode.Type.PROJECT);
assert project != null;
List<org.modeshape.jcr.query.model.Column> columns = project.getPropertyAsList(Property.PROJECT_COLUMNS,
org.modeshape.jcr.query.model.Column.class);
assert !columns.isEmpty();
// Go through all the columns and look up the types ...
Map<SelectorName, SelectorName> tableNameByAlias = null;
List<Column> viewColumns = new ArrayList<Column>(columns.size());
List<Column> viewColumnsInSelectStar = new ArrayList<Column>(columns.size());
Set<String> columnNames = new HashSet<String>();
for (org.modeshape.jcr.query.model.Column column : columns) {
// Find the table that the column came from ...
Table source = schemata.getTable(column.selectorName());
if (source == null) {
// The column may be referring to the alias of the table ...
if (tableNameByAlias == null) {
tableNameByAlias = Visitors.getSelectorNamesByAlias(command);
}
SelectorName tableName = tableNameByAlias.get(column.selectorName());
if (tableName != null) source = schemata.getTable(tableName);
if (source == null) {
continue;
}
}
String viewColumnName = column.getColumnName();
if (viewColumnName.equals(column.getSelectorName() + "." + column.getPropertyName())) {
viewColumnName = column.getPropertyName();
}
if (columnNames.contains(viewColumnName)) continue;
String sourceColumnName = column.getPropertyName(); // getColumnName() returns alias
Column sourceColumn = source.getColumn(sourceColumnName);
if (sourceColumn == null) {
sourceColumn = source.getColumn(column.getColumnName());
if (sourceColumn == null) {
throw new InvalidQueryException(Visitors.readable(command),
"The view references a non-existant column '"
+ column.getColumnName() + "' in '" + source.getName() + "'");
}
}
Set<Operator> operators = operators(name, viewColumnName, sourceColumn.getOperators());
boolean orderable = orderable(name, viewColumnName, sourceColumn.isOrderable());
Column newColumn = new ImmutableColumn(viewColumnName, sourceColumn.getPropertyTypeName(),
sourceColumn.getRequiredType(),
sourceColumn.isFullTextSearchable(), orderable,
sourceColumn.getMinimum(), sourceColumn.getMaximum(), operators);
viewColumns.add(newColumn);
if (source.getSelectAllColumnsByName().containsKey(sourceColumnName)) {
viewColumnsInSelectStar.add(newColumn);
}
columnNames.add(newColumn.getName());
}
// 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 ...
Map<String, Column> viewColumnsByName = new HashMap<String, Column>();
Map<String, Column> viewSelectStarColumnsByName = new HashMap<String, Column>();
for (Column column : viewColumns) {
viewColumnsByName.put(column.getName(), column);
}
for (Column column : viewColumnsInSelectStar) {
viewSelectStarColumnsByName.put(column.getName(), column);
}
Set<Key> keys = Collections.emptySet();
boolean hasExtraColumns = tablesOrViewsWithExtraColumns.contains(name);
ImmutableView view = new ImmutableView(name, viewColumnsByName, viewColumns, hasExtraColumns, command, keys,
viewSelectStarColumnsByName, viewColumnsInSelectStar);
definitions.remove(name);
tablesByName.put(view.getName(), view);
schemata = new ImmutableSchemata(tablesByName);
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;