content: /*
   * Copyright 1999-2017 Alibaba Group Holding Ltd.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.alibaba.druid.sql.ast.statement;
  
  import com.alibaba.druid.DbType;
  import com.alibaba.druid.sql.SQLUtils;
  import com.alibaba.druid.sql.ast.*;
  import com.alibaba.druid.sql.ast.expr.*;
  import com.alibaba.druid.sql.visitor.SQLASTVisitor;
  
  import java.util.ArrayList;
  import java.util.List;
  
  public class SQLCreateViewStatement extends SQLStatementImpl implements SQLCreateStatement {
      private boolean orReplace;
      private boolean force;
      private boolean temporary;
      // protected SQLName   name;
      protected SQLSelect subQuery;
      protected boolean ifNotExists;
  
      protected String algorithm;
      protected SQLName definer;
      protected String sqlSecurity;
  
      protected SQLExprTableSource tableSource;
  
      protected final List<SQLTableElement> columns = new ArrayList<SQLTableElement>();
  
      private boolean withCheckOption;
      private boolean withCascaded;
      private boolean withLocal;
      private boolean withReadOnly;
      private boolean global;
  
      private SQLLiteralExpr comment;
  
      private SQLVariantRefExpr returns; // odps
      private SQLTableDataType returnsDataType; // odps
  
      // clickhouse
      protected boolean onCluster;
      private SQLName to;
  
      // bigquery
      protected List<SQLAssignItem> options = new ArrayList<>();
  
      private SQLBlockStatement script;
  
      public SQLCreateViewStatement() {
      }
  
      public SQLCreateViewStatement(DbType dbType) {
          super(dbType);
      }
  
      public boolean isGlobal() {
          return global;
      }
  
      public void setGlobal(boolean global) {
          this.global = global;
      }
  
      public String computeName() {
          if (tableSource == null) {
              return null;
          }
  
          SQLExpr expr = tableSource.getExpr();
          if (expr instanceof SQLName) {
              String name = ((SQLName) expr).getSimpleName();
              return SQLUtils.normalize(name);
          }
  
          return null;
      }
  
      public String getSchema() {
          SQLName name = getName();
          if (name == null) {
              return null;
          }
  
          if (name instanceof SQLPropertyExpr) {
              return ((SQLPropertyExpr) name).getOwnernName();
          }
  
          return null;
      }
  
      public boolean isOrReplace() {
          return orReplace;
      }
  
      public void setOrReplace(boolean orReplace) {
          this.orReplace = orReplace;
      }
  
      public SQLName getName() {
          if (tableSource == null) {
              return null;
          }
  
          return (SQLName) tableSource.getExpr();
      }
  
      public void setName(SQLName name) {
          this.setTableSource(new SQLExprTableSource(name));
      }
  
      public void setName(String name) {
          this.setName(new SQLIdentifierExpr(name));
      }
  
      public SQLExprTableSource getTableSource() {
          return tableSource;
      }
  
      public void setTableSource(SQLExprTableSource tableSource) {
          if (tableSource != null) {
              tableSource.setParent(this);
          }
          this.tableSource = tableSource;
      }
  
      public boolean isWithCheckOption() {
          return withCheckOption;
      }
  
      public void setWithCheckOption(boolean withCheckOption) {
          this.withCheckOption = withCheckOption;
      }
  
      public boolean isWithCascaded() {
          return withCascaded;
      }
  
      public void setWithCascaded(boolean withCascaded) {
          this.withCascaded = withCascaded;
      }
  
      public boolean isWithLocal() {
          return withLocal;
      }
  
      public void setWithLocal(boolean withLocal) {
          this.withLocal = withLocal;
      }
  
      public boolean isWithReadOnly() {
          return withReadOnly;
      }
  
      public void setWithReadOnly(boolean withReadOnly) {
          this.withReadOnly = withReadOnly;
      }
  
      public SQLSelect getSubQuery() {
          return subQuery;
      }
  
      public void setSubQuery(SQLSelect subQuery) {
          if (subQuery != null) {
              subQuery.setParent(this);
          }
          this.subQuery = subQuery;
      }
  
      public List<SQLTableElement> getColumns() {
          return columns;
      }
  
      public void addColumn(SQLTableElement column) {
          if (column != null) {
              column.setParent(this);
          }
          this.columns.add(column);
      }
  
      public boolean isIfNotExists() {
          return ifNotExists;
      }
  
      public void setIfNotExists(boolean ifNotExists) {
          this.ifNotExists = ifNotExists;
      }
  
      public SQLLiteralExpr getComment() {
          return comment;
      }
  
      public void setComment(SQLLiteralExpr comment) {
          if (comment != null) {
              comment.setParent(this);
          }
          this.comment = comment;
      }
  
      public String getAlgorithm() {
          return algorithm;
      }
  
      public void setAlgorithm(String algorithm) {
          this.algorithm = algorithm;
      }
  
      public SQLName getDefiner() {
          return definer;
      }
  
      public void setDefiner(SQLName definer) {
          if (definer != null) {
              definer.setParent(this);
          }
          this.definer = definer;
      }
  
      public String getSqlSecurity() {
          return sqlSecurity;
      }
  
      public void setSqlSecurity(String sqlSecurity) {
          this.sqlSecurity = sqlSecurity;
      }
  
      public boolean isForce() {
          return force;
      }
  
      public void setForce(boolean force) {
          this.force = force;
      }
  
      public boolean isTemporary() {
          return temporary;
      }
  
      public void setTemporary(boolean temporary) {
          this.temporary = temporary;
      }
  
      @Override
      protected void accept0(SQLASTVisitor visitor) {
          if (visitor.visit(this)) {
              if (tableSource != null) {
                  tableSource.accept(visitor);
              }
  
              for (int i = 0; i < columns.size(); i++) {
                  final SQLTableElement column = columns.get(i);
                  if (column != null) {
                      column.accept(visitor);
                  }
              }
  
              if (comment != null) {
                  comment.accept(visitor);
              }
  
              if (subQuery != null) {
                  subQuery.accept(visitor);
              }
          }
          visitor.endVisit(this);
      }
  
      public List<SQLObject> getChildren() {
          List<SQLObject> children = new ArrayList<SQLObject>();
          if (tableSource != null) {
              children.add(tableSource);
          }
          children.addAll(this.columns);
          if (comment != null) {
              children.add(comment);
          }
          if (subQuery != null) {
              children.add(subQuery);
          }
          return children;
      }
  
      public static enum Level {
          CASCADED, LOCAL
      }
  
      public static class Column extends SQLObjectImpl {
          private SQLExpr expr;
          private SQLCharExpr comment;
  
          public SQLExpr getExpr() {
              return expr;
          }
  
          public void setExpr(SQLExpr expr) {
              if (expr != null) {
                  expr.setParent(this);
              }
              this.expr = expr;
          }
  
          public SQLCharExpr getComment() {
              return comment;
          }
  
          public void setComment(SQLCharExpr comment) {
              if (comment != null) {
                  comment.setParent(this);
              }
              this.comment = comment;
          }
  
          @Override
          protected void accept0(SQLASTVisitor visitor) {
              if (visitor.visit(this)) {
                  acceptChild(visitor, expr);
                  acceptChild(visitor, comment);
              }
          }
      }
  
      public boolean isOnCluster() {
          return onCluster;
      }
  
      public void setOnCluster(boolean onCluster) {
          this.onCluster = onCluster;
      }
  
      public SQLName getTo() {
          return to;
      }
  
      public void setTo(SQLName x) {
          if (x != null) {
              x.setParent(this);
          }
          this.to = x;
      }
  
      public SQLVariantRefExpr getReturns() {
          return returns;
      }
  
      public void setReturns(SQLVariantRefExpr x) {
          if (x != null) {
              x.setParent(this);
          }
          this.returns = x;
      }
  
      public SQLTableDataType getReturnsDataType() {
          return returnsDataType;
      }
  
      public void
      setReturnsDataType(SQLTableDataType x) {
          if (x != null) {
              x.setParent(this);
          }
          this.returnsDataType = x;
      }
  
      public SQLBlockStatement getScript() {
          return script;
      }
  
      public void setScript(SQLBlockStatement x) {
          if (x != null) {
              x.setParent(this);
          }
          this.script = x;
      }
  
      public DDLObjectType getDDLObjectType() {
          return DDLObjectType.VIEW;
      }
  
      public SQLCreateViewStatement clone() {
          SQLCreateViewStatement x = new SQLCreateViewStatement();
  
          x.orReplace = orReplace;
          x.force = force;
          if (subQuery != null) {
              x.setSubQuery(subQuery.clone());
          }
          x.ifNotExists = ifNotExists;
  
          x.algorithm = algorithm;
          if (definer != null) {
              x.setDefiner(definer.clone());
          }
          x.sqlSecurity = sqlSecurity;
          if (tableSource != null) {
              x.setTableSource(tableSource.clone());
          }
          for (SQLTableElement column : columns) {
              SQLTableElement column2 = column.clone();
              column2.setParent(x);
              x.columns.add(column2);
          }
          x.withCheckOption = withCheckOption;
          x.withCascaded = withCascaded;
          x.withLocal = withLocal;
          x.withReadOnly = withReadOnly;
          x.global = global;
  
          if (comment != null) {
              x.setComment(comment.clone());
          }
  
          x.onCluster = onCluster;
          if (x.to != null) {
              to = x.to.clone();
          }
  
          if (x.returns != null) {
              returns = x.returns.clone();
          }
  
          if (x.returnsDataType != null) {
              returnsDataType = x.returnsDataType.clone();
          }
  
          return x;
      }
  
      public List<SQLAssignItem> getOptions() {
          return options;
      }
  }
  