public void prepare() throws DatabaseException {
    type = (String) cmd.getObject("type");
    view_name = (String) cmd.getObject("view_name");

    String schema_name = database.getCurrentSchema();
    vname = TableName.resolve(schema_name, view_name);
    vname = database.tryResolveCase(vname);

    if (type.equals("create")) {
      // Get the select expression
      select_expression = (TableSelectExpression) cmd.getObject("select_expression");
      // Get the column name list
      ArrayList col_list = (ArrayList) cmd.getObject("column_list");

      // Generate the TableExpressionFromSet hierarchy for the expression,
      TableExpressionFromSet from_set = Planner.generateFromSet(select_expression, database);
      // Form the plan
      plan = Planner.formQueryPlan(database, select_expression, from_set, new ArrayList());

      // Wrap the result around a SubsetNode to alias the columns in the
      // table correctly for this view.
      int sz = (col_list == null) ? 0 : col_list.size();
      Variable[] original_vars = from_set.generateResolvedVariableList();
      Variable[] new_column_vars = new Variable[original_vars.length];

      if (sz > 0) {
        if (sz != original_vars.length) {
          throw new StatementException("Column list is not the same size as the columns selected.");
        }
        for (int i = 0; i < sz; ++i) {
          String col_name = (String) col_list.get(i);
          new_column_vars[i] = new Variable(vname, col_name);
        }
      } else {
        sz = original_vars.length;
        for (int i = 0; i < sz; ++i) {
          new_column_vars[i] = new Variable(vname, original_vars[i].getName());
        }
      }

      // Check there are no repeat column names in the table.
      for (int i = 0; i < sz; ++i) {
        Variable cur_v = new_column_vars[i];
        for (int n = i + 1; n < sz; ++n) {
          if (new_column_vars[n].equals(cur_v)) {
            throw new DatabaseException(
                "Duplicate column name '"
                    + cur_v
                    + "' in view.  "
                    + "A view may not contain duplicate column names.");
          }
        }
      }

      // Wrap the plan around a SubsetNode plan
      plan = new QueryPlan.SubsetNode(plan, original_vars, new_column_vars);
    }
  }
  public Table evaluate() throws DatabaseException {

    DatabaseQueryContext context = new DatabaseQueryContext(database);

    if (type.equals("create")) {
      // Does the user have privs to create this tables?
      if (!database.getDatabase().canUserCreateTableObject(context, user, vname)) {
        throw new UserAccessException("User not permitted to create view: " + view_name);
      }

      // Does the schema exist?
      boolean ignore_case = database.isInCaseInsensitiveMode();
      SchemaDef schema = database.resolveSchemaCase(vname.getSchema(), ignore_case);
      if (schema == null) {
        throw new DatabaseException("Schema '" + vname.getSchema() + "' doesn't exist.");
      } else {
        vname = new TableName(schema.getName(), vname.getName());
      }

      // Check the permissions for this user to select from the tables in the
      // given plan.
      Select.checkUserSelectPermissions(context, user, plan);

      // Does the table already exist?
      if (database.tableExists(vname)) {
        throw new DatabaseException("View or table with name '" + vname + "' already exists.");
      }

      // Before evaluation, make a clone of the plan,
      QueryPlanNode plan_copy;
      try {
        plan_copy = (QueryPlanNode) plan.clone();
      } catch (CloneNotSupportedException e) {
        Debug().writeException(e);
        throw new DatabaseException("Clone error: " + e.getMessage());
      }

      // We have to execute the plan to get the DataTableDef that represents the
      // result of the view execution.
      Table t = plan.evaluate(context);
      DataTableDef data_table_def = new DataTableDef(t.getDataTableDef());
      data_table_def.setTableName(vname);

      // Create a ViewDef object,
      ViewDef view_def = new ViewDef(data_table_def, plan_copy);

      // And create the view object,
      database.createView(query, view_def);

      // The initial grants for a view is to give the user who created it
      // full access.
      database
          .getGrantManager()
          .addGrant(
              Privileges.TABLE_ALL_PRIVS,
              GrantManager.TABLE,
              vname.toString(),
              user.getUserName(),
              true,
              Database.INTERNAL_SECURE_USERNAME);

    } else if (type.equals("drop")) {

      // Does the user have privs to drop this tables?
      if (!database.getDatabase().canUserDropTableObject(context, user, vname)) {
        throw new UserAccessException("User not permitted to drop view: " + view_name);
      }

      // Drop the view object
      database.dropView(vname);

      // Drop the grants for this object
      database.getGrantManager().revokeAllGrantsOnObject(GrantManager.TABLE, vname.toString());

    } else {
      throw new Error("Unknown view command type: " + type);
    }

    return FunctionTable.resultTable(context, 0);
  }