package com.chenyang.druid.sql.dialect.kingbase.ast.statement;

import com.chenyang.druid.DbType;
import com.chenyang.druid.sql.SQLUtils;
import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLName;
import com.chenyang.druid.sql.ast.SQLWindow;
import com.chenyang.druid.sql.ast.statement.SQLSelectItem;
import com.chenyang.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.chenyang.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.chenyang.druid.sql.dialect.kingbase.KingbaseSQLObject;
import com.chenyang.druid.sql.dialect.kingbase.ast.expression.KingbaseForUpdateExpr;
import com.chenyang.druid.sql.dialect.kingbase.visitor.KingbaseASTVisitor;
import com.chenyang.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;

public class KingbaseSelectQueryBlock extends SQLSelectQueryBlock implements KingbaseSQLObject {
   private boolean hignPriority;
   private boolean straightJoin;
   private boolean smallResult;
   private boolean bigResult;
   private boolean bufferResult;
   private Boolean cache;
   private boolean calcFoundRows;
   private SQLName procedureName;
   private List<SQLExpr> procedureArgumentList;
   private boolean lockInShareMode;
   private SQLName forcePartition;
   private KingbaseForUpdateExpr forUpdate;
   private IntoOption intoOption;

   public KingbaseSelectQueryBlock() {
      this.dbType = DbType.kingbase;
   }

   public KingbaseSelectQueryBlock clone() {
      KingbaseSelectQueryBlock x = new KingbaseSelectQueryBlock();
      this.cloneTo(x);
      x.hignPriority = this.hignPriority;
      x.straightJoin = this.straightJoin;
      x.smallResult = this.smallResult;
      x.bigResult = this.bigResult;
      x.bufferResult = this.bufferResult;
      x.cache = this.cache;
      x.calcFoundRows = this.calcFoundRows;
      if (this.procedureName != null) {
         x.setProcedureName(this.procedureName.clone());
      }

      if (this.procedureArgumentList != null) {
         for(SQLExpr arg : this.procedureArgumentList) {
            SQLExpr arg_cloned = arg.clone();
            arg_cloned.setParent(this);
            x.procedureArgumentList.add(arg_cloned);
         }
      }

      x.lockInShareMode = this.lockInShareMode;
      x.intoOption = this.intoOption;
      return x;
   }

   public int getHintsSize() {
      return this.hints == null ? 0 : this.hints.size();
   }

   public boolean isLockInShareMode() {
      return this.lockInShareMode;
   }

   public void setLockInShareMode(boolean lockInShareMode) {
      this.lockInShareMode = lockInShareMode;
   }

   public SQLName getProcedureName() {
      return this.procedureName;
   }

   public void setProcedureName(SQLName procedureName) {
      this.procedureName = procedureName;
   }

   public List<SQLExpr> getProcedureArgumentList() {
      if (this.procedureArgumentList == null) {
         this.procedureArgumentList = new ArrayList(2);
      }

      return this.procedureArgumentList;
   }

   public boolean isHignPriority() {
      return this.hignPriority;
   }

   public void setHignPriority(boolean hignPriority) {
      this.hignPriority = hignPriority;
   }

   public boolean isStraightJoin() {
      return this.straightJoin;
   }

   public void setStraightJoin(boolean straightJoin) {
      this.straightJoin = straightJoin;
   }

   public boolean isSmallResult() {
      return this.smallResult;
   }

   public void setSmallResult(boolean smallResult) {
      this.smallResult = smallResult;
   }

   public boolean isBigResult() {
      return this.bigResult;
   }

   public void setBigResult(boolean bigResult) {
      this.bigResult = bigResult;
   }

   public boolean isBufferResult() {
      return this.bufferResult;
   }

   public void setBufferResult(boolean bufferResult) {
      this.bufferResult = bufferResult;
   }

   public Boolean getCache() {
      return this.cache;
   }

   public void setCache(Boolean cache) {
      this.cache = cache;
   }

   public boolean isCalcFoundRows() {
      return this.calcFoundRows;
   }

   public void setCalcFoundRows(boolean calcFoundRows) {
      this.calcFoundRows = calcFoundRows;
   }

   public boolean equals(Object o) {
      if (this == o) {
         return true;
      } else if (o != null && this.getClass() == o.getClass()) {
         if (!super.equals(o)) {
            return false;
         } else {
            KingbaseSelectQueryBlock that = (KingbaseSelectQueryBlock)o;
            if (this.hignPriority != that.hignPriority) {
               return false;
            } else if (this.straightJoin != that.straightJoin) {
               return false;
            } else if (this.smallResult != that.smallResult) {
               return false;
            } else if (this.bigResult != that.bigResult) {
               return false;
            } else if (this.bufferResult != that.bufferResult) {
               return false;
            } else if (this.calcFoundRows != that.calcFoundRows) {
               return false;
            } else if (this.lockInShareMode != that.lockInShareMode) {
               return false;
            } else {
               if (this.cache != null) {
                  if (!this.cache.equals(that.cache)) {
                     return false;
                  }
               } else if (that.cache != null) {
                  return false;
               }

               if (this.procedureName != null) {
                  if (!this.procedureName.equals(that.procedureName)) {
                     return false;
                  }
               } else if (that.procedureName != null) {
                  return false;
               }

               if (this.procedureArgumentList != null) {
                  if (!this.procedureArgumentList.equals(that.procedureArgumentList)) {
                     return false;
                  }
               } else if (that.procedureArgumentList != null) {
                  return false;
               }

               if (this.hints != null) {
                  if (!this.hints.equals(that.hints)) {
                     return false;
                  }
               } else if (that.hints != null) {
                  return false;
               }

               if (this.forcePartition != null) {
                  if (!this.forcePartition.equals(that.forcePartition)) {
                     return false;
                  }
               } else if (that.forcePartition != null) {
                  return false;
               }

               return true;
            }
         }
      } else {
         return false;
      }
   }

   public int hashCode() {
      int result = super.hashCode();
      result = 31 * result + (this.hignPriority ? 1 : 0);
      result = 31 * result + (this.straightJoin ? 1 : 0);
      result = 31 * result + (this.smallResult ? 1 : 0);
      result = 31 * result + (this.bigResult ? 1 : 0);
      result = 31 * result + (this.bufferResult ? 1 : 0);
      result = 31 * result + (this.cache != null ? this.cache.hashCode() : 0);
      result = 31 * result + (this.calcFoundRows ? 1 : 0);
      result = 31 * result + (this.procedureName != null ? this.procedureName.hashCode() : 0);
      result = 31 * result + (this.procedureArgumentList != null ? this.procedureArgumentList.hashCode() : 0);
      result = 31 * result + (this.lockInShareMode ? 1 : 0);
      result = 31 * result + (this.hints != null ? this.hints.hashCode() : 0);
      result = 31 * result + (this.forcePartition != null ? this.forcePartition.hashCode() : 0);
      return result;
   }

   protected void accept0(SQLASTVisitor visitor) {
      if (visitor instanceof KingbaseASTVisitor) {
         this.accept0((KingbaseASTVisitor)visitor);
      }
   }

   public void accept0(KingbaseASTVisitor visitor) {
      if (visitor.visit(this)) {
         for(int i = 0; i < this.selectList.size(); ++i) {
            SQLSelectItem item = (SQLSelectItem)this.selectList.get(i);
            if (item != null) {
               item.accept(visitor);
            }
         }

         if (this.from != null) {
            this.from.accept(visitor);
         }

         if (this.into != null) {
            this.into.accept(visitor);
         }

         if (this.where != null) {
            this.where.accept(visitor);
         }

         if (this.startWith != null) {
            this.startWith.accept(visitor);
         }

         if (this.connectBy != null) {
            this.connectBy.accept(visitor);
         }

         if (this.groupBy != null) {
            this.groupBy.accept(visitor);
         }

         if (this.windows != null) {
            for(SQLWindow item : this.windows) {
               item.accept(visitor);
            }
         }

         if (this.orderBy != null) {
            this.orderBy.accept(visitor);
         }

         if (this.distributeBy != null) {
            for(int i = 0; i < this.distributeBy.size(); ++i) {
               SQLSelectOrderByItem item = (SQLSelectOrderByItem)this.distributeBy.get(i);
               item.accept(visitor);
            }
         }

         if (this.sortBy != null) {
            for(int i = 0; i < this.sortBy.size(); ++i) {
               SQLSelectOrderByItem item = (SQLSelectOrderByItem)this.sortBy.get(i);
               item.accept(visitor);
            }
         }

         if (this.waitTime != null) {
            this.waitTime.accept(visitor);
         }

         if (this.limit != null) {
            this.limit.accept(visitor);
         }

         if (this.procedureName != null) {
            this.procedureName.accept(visitor);
         }

         if (this.procedureArgumentList != null) {
            for(SQLExpr item : this.procedureArgumentList) {
               item.accept(visitor);
            }
         }

         if (this.forUpdate != null) {
            this.forUpdate.accept(visitor);
         }
      }

      visitor.endVisit(this);
   }

   public SQLName getForcePartition() {
      return this.forcePartition;
   }

   public KingbaseForUpdateExpr getForUpdate() {
      return this.forUpdate;
   }

   public void setForUpdate(KingbaseForUpdateExpr forUpdate) {
      this.forUpdate = forUpdate;
   }

   public void setForcePartition(SQLName x) {
      if (x != null) {
         x.setParent(this);
      }

      this.forcePartition = x;
   }

   public String toString() {
      return SQLUtils.toMySqlString(this);
   }

   public IntoOption getIntoOption() {
      return this.intoOption;
   }

   public void setIntoOption(IntoOption intoOption) {
      this.intoOption = intoOption;
   }

   public static enum IntoOption {
      TEMPORARY("TEMPORARY"),
      TEMP("TEMP"),
      UNLOGGED("UNLOGGED");

      public final String name;

      private IntoOption(String name) {
         this.name = name;
      }
   }
}
