super(planner, context);
}
@Override
public PhysicalPlan getPlan(SqlNode sqlNode) throws ValidationException, RelConversionException, IOException {
SqlCreateView createView = unwrap(sqlNode, SqlCreateView.class);
try {
SchemaPlus defaultSchema = context.getNewDefaultSchema();
SchemaPlus schema = findSchema(context.getRootSchema(), defaultSchema, createView.getSchemaPath());
AbstractSchema drillSchema = getDrillSchema(schema);
String schemaPath = drillSchema.getFullSchemaName();
if (!drillSchema.isMutable()) {
return DirectPlan.createDirectPlan(context, false, String.format("Unable to create view. " +
"Schema [%s] is immutable. ", schemaPath));
}
// find current workspace schema path
List<String> workspaceSchemaPath = ImmutableList.of();
if (!isRootSchema(defaultSchema)) {
workspaceSchemaPath = getDrillSchema(defaultSchema).getSchemaPath();
}
String viewSql = createView.getQuery().toString();
SqlNode validatedQuery = planner.validate(createView.getQuery());
RelNode validatedRelNode = planner.convert(validatedQuery);
// If view's field list is specified then its size should match view's query field list size.
RelDataType queryRowType = validatedRelNode.getRowType();
List<String> viewFieldNames = createView.getFieldNames();
if (viewFieldNames.size() > 0) {
// number of fields match.
if (viewFieldNames.size() != queryRowType.getFieldCount()) {
return DirectPlan.createDirectPlan(context, false,
"View's field list and View's query field list have different counts.");
}
// make sure View's query field list has no "*"
for (String field : queryRowType.getFieldNames()) {
if (field.equals("*")) {
return DirectPlan.createDirectPlan(context, false,
"View's query field list has a '*', which is invalid when View's field list is specified.");
}
}
queryRowType = new DrillFixedRelDataTypeImpl(planner.getTypeFactory(), viewFieldNames);
}
View view = new View(createView.getName(), viewSql, queryRowType, workspaceSchemaPath);
boolean replaced;
if (drillSchema instanceof WorkspaceSchema) {
WorkspaceSchema workspaceSchema = (WorkspaceSchema) drillSchema;
if (!createView.getReplace() && workspaceSchema.viewExists(view.getName())) {
return DirectPlan.createDirectPlan(context, false, "View with given name already exists in current schema");
}
replaced = ((WorkspaceSchema) drillSchema).createView(view);
} else {
return DirectPlan.createDirectPlan(context, false, "Schema provided was not a workspace schema.");
}
String summary = String.format("View '%s' %s successfully in '%s' schema",
createView.getName(), replaced ? "replaced" : "created", schemaPath);
return DirectPlan.createDirectPlan(context, true, summary);
} catch(Exception e) {
logger.error("Failed to create view '{}'", createView.getName(), e);
return DirectPlan.createDirectPlan(context, false, String.format("Error: %s", e.getMessage()));
}
}