protected override SqlStatement PrepareStatement(IRequest context)
{
var viewName = context.Access().ResolveTableName(ViewName);
var queryFrom = QueryExpressionFrom.Create(context, QueryExpression);
var queryPlan = context.Query.Context.QueryPlanner().PlanQuery(new QueryInfo(context, QueryExpression));
var colList = ColumnNames == null ? new string[0] : ColumnNames.ToArray();
// Wrap the result around a SubsetNode to alias the columns in the
// table correctly for this view.
int sz = colList.Length;
var originalNames = queryFrom.GetResolvedColumns();
var newColumnNames = new ObjectName[originalNames.Length];
if (sz > 0) {
if (sz != originalNames.Length)
throw new InvalidOperationException("Column list is not the same size as the columns selected.");
for (int i = 0; i < sz; ++i) {
var colName = colList[i];
newColumnNames[i] = new ObjectName(viewName, colName);
}
} else {
sz = originalNames.Length;
for (int i = 0; i < sz; ++i) {
newColumnNames[i] = new ObjectName(viewName, originalNames[i].Name);
}
}
// Check there are no repeat column names in the table.
for (int i = 0; i < sz; ++i) {
var columnName = newColumnNames[i];
for (int n = i + 1; n < sz; ++n) {
if (newColumnNames[n].Equals(columnName))
throw new InvalidOperationException(String.Format("Duplicate column name '{0}' in view. A view may not contain duplicate column names.", columnName));
}
}
// Wrap the plan around a SubsetNode plan
queryPlan = new SubsetNode(queryPlan, originalNames, newColumnNames);
return new Prepared(viewName, QueryExpression, queryPlan, ReplaceIfExists);
}