package com.chenyang.druid.sql.dialect.gauss.visitor;

import com.chenyang.druid.DbType;
import com.chenyang.druid.sql.ast.SQLArrayDataType;
import com.chenyang.druid.sql.ast.SQLDataType;
import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.SQLLimit;
import com.chenyang.druid.sql.ast.SQLName;
import com.chenyang.druid.sql.ast.SQLStatement;
import com.chenyang.druid.sql.ast.SQLWindow;
import com.chenyang.druid.sql.ast.expr.SQLBinaryExpr;
import com.chenyang.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.chenyang.druid.sql.ast.expr.SQLIdentifierExpr;
import com.chenyang.druid.sql.ast.expr.SQLListExpr;
import com.chenyang.druid.sql.ast.expr.SQLPropertyExpr;
import com.chenyang.druid.sql.ast.expr.SQLVariantRefExpr;
import com.chenyang.druid.sql.ast.statement.SQLAlterTableItem;
import com.chenyang.druid.sql.ast.statement.SQLAssignItem;
import com.chenyang.druid.sql.ast.statement.SQLColumnConstraint;
import com.chenyang.druid.sql.ast.statement.SQLColumnDefinition;
import com.chenyang.druid.sql.ast.statement.SQLCommitStatement;
import com.chenyang.druid.sql.ast.statement.SQLCreateTriggerStatement;
import com.chenyang.druid.sql.ast.statement.SQLDropTableStatement;
import com.chenyang.druid.sql.ast.statement.SQLExprTableSource;
import com.chenyang.druid.sql.ast.statement.SQLGrantStatement;
import com.chenyang.druid.sql.ast.statement.SQLIfStatement;
import com.chenyang.druid.sql.ast.statement.SQLPrivilegeItem;
import com.chenyang.druid.sql.ast.statement.SQLRollbackStatement;
import com.chenyang.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.chenyang.druid.sql.ast.statement.SQLSelectStatement;
import com.chenyang.druid.sql.ast.statement.SQLSetStatement;
import com.chenyang.druid.sql.ast.statement.SQLTableElement;
import com.chenyang.druid.sql.ast.statement.SQLTableSource;
import com.chenyang.druid.sql.ast.statement.SQLTruncateStatement;
import com.chenyang.druid.sql.ast.statement.SQLUpdateSetItem;
import com.chenyang.druid.sql.ast.statement.SQLWithSubqueryClause;
import com.chenyang.druid.sql.dialect.gauss.ast.GaussSQLIndexSpec;
import com.chenyang.druid.sql.dialect.gauss.ast.GaussSQLPartition;
import com.chenyang.druid.sql.dialect.gauss.ast.GaussSQLPartitionBy;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussBoxExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussCidrExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussCircleExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussColumnSimpleDefinitionExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussExtractExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussInetExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussLineSegmentsExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussMacAddrExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussOptionValue;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussPointExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussPolygonExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussSQLObjectCollection;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussSchemaTables;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.GaussTypeCastExpr;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.constraint.GaussConstraint;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.constraint.GaussStorageParameter;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.tablesource.GaussExprTableSource;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.tablesource.GaussFunctionTableSource;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.tablesource.GaussMethodInvokeTableSource;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.tablesource.GaussRowsFromTableSource;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.tablesource.GaussSubqueryTableSource;
import com.chenyang.druid.sql.dialect.gauss.ast.expr.tablesource.GaussValuesTableSource;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterDatabaseStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterGroupStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterIndexStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterRoleStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterSchemaStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterSequenceStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterSessionStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterSynonymStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterSystemKillSessionStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterTableSpaceStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterTableStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterTriggerStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussAlterViewStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCommonStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussConnectToStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateDatabaseStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateGroupStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateIndexStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateMaterializedViewStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateRoleStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateSchemaStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateSeqenceStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateSynonymStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateTableAsStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateTableSpaceStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateTableStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateTriggerStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussCreateViewStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussDeleteStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussDropSchemaStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussDropSequenceStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussDropTriggerStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussGrantStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussInsertStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussRevokeStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussSelectQueryBlock;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussSelectStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussShowStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussStartTransactionStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.GaussUpdateStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableAddColumn;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableAddConstraint;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableAlterColumn;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableAlterColumnOptions;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableCluster;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableDisableEnabelTrigger;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableDropColumn;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableDropConstraint;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableInheriteOrNotParentTable;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableModify;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableOf;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableRenameColumn;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableRenameConstraint;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableRenameTo;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableSetNewTableSpace;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableSetReset;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableSetSchema;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableSetTableSpace;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableSetWith;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterTableValidateConstraint;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussAlterUserStatement;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussColumnDefinition;
import com.chenyang.druid.sql.dialect.gauss.ast.stmt.alterTable.GaussCreateUserStatement;
import com.chenyang.druid.sql.visitor.SQLASTOutputVisitor;
import com.chenyang.druid.util.FnvHash;
import java.util.ArrayList;
import java.util.List;
import util.StringJoin;

public class GaussOutputVisitor extends SQLASTOutputVisitor implements GaussASTVisitor {
   public GaussOutputVisitor(Appendable appender) {
      super(appender);
      this.dbType = DbType.gauss;
   }

   public GaussOutputVisitor(Appendable appender, boolean parameterized) {
      super(appender, parameterized);
      this.dbType = DbType.gauss;
   }

   public boolean visit(GaussSelectQueryBlock.FetchClause x) {
      this.print0(this.ucase ? "FETCH " : "fetch ");
      if (GaussSelectQueryBlock.FetchClause.Option.FIRST.equals(x.getOption())) {
         this.print0(this.ucase ? "FIRST " : "first ");
      } else if (GaussSelectQueryBlock.FetchClause.Option.NEXT.equals(x.getOption())) {
         this.print0(this.ucase ? "NEXT " : "next ");
      }

      x.getCount().accept(this);
      this.print0(this.ucase ? " ROWS ONLY" : " rows only");
      return false;
   }

   public void endVisit(GaussSelectQueryBlock.ForClause x) {
   }

   public boolean visit(GaussSelectQueryBlock.ForClauses x) {
      if (x != null && x.getClauses() != null && x.getClauses().size() > 0) {
         for(int i = 0; i < x.getClauses().size(); ++i) {
            GaussSelectQueryBlock.ForClause forClause = (GaussSelectQueryBlock.ForClause)x.getClauses().get(i);
            forClause.accept(this);
            if (i != x.getClauses().size() - 1) {
               this.println();
            }
         }
      }

      return false;
   }

   public void endVisit(GaussColumnSimpleDefinitionExpr x) {
   }

   public boolean visit(GaussColumnSimpleDefinitionExpr x) {
      return true;
   }

   public void endVisit(GaussRowsFromTableSource x) {
   }

   public boolean visit(GaussSelectQueryBlock.ForClause x) {
      this.print0(this.ucase ? "FOR " : "for ");
      if (GaussSelectQueryBlock.ForClause.Option.UPDATE.equals(x.getOption())) {
         this.print0(this.ucase ? "UPDATE" : "update");
      } else if (GaussSelectQueryBlock.ForClause.Option.SHARE.equals(x.getOption())) {
         this.print0(this.ucase ? "SHARE" : "share");
      } else if (GaussSelectQueryBlock.ForClause.Option.NO_KEY_UPDATE.equals(x.getOption())) {
         this.print0(this.ucase ? "NO KEY UPDATE" : "no key update");
      } else if (GaussSelectQueryBlock.ForClause.Option.KEY_SHARE.equals(x.getOption())) {
         this.print0(this.ucase ? "KEY SHARE" : "key share");
      }

      if (x.getOf().size() > 0) {
         this.print(' ');
         this.print0(this.ucase ? "OF" : "of");
         this.print(' ');

         for(int i = 0; i < x.getOf().size(); ++i) {
            if (i != 0) {
               this.println(", ");
            }

            ((SQLExpr)x.getOf().get(i)).accept(this);
         }
      }

      if (x.isNoWait()) {
         this.print0(this.ucase ? " NOWAIT" : " nowait");
      } else if (x.isSkipLocked()) {
         this.print0(this.ucase ? " SKIP LOCKED" : " skip locked");
      }

      return false;
   }

   public void endVisit(GaussDeleteStatement x) {
   }

   public void endVisit(GaussSelectQueryBlock x) {
      this.endVisit((SQLSelectQueryBlock)x);
   }

   public boolean visit(GaussSelectQueryBlock x) {
      if (!this.isParameterized() && this.isPrettyFormat() && x.hasBeforeComment()) {
         this.printlnComments(x.getBeforeCommentsDirect());
      }

      boolean bracket = x.isBracket();
      if (bracket) {
         this.print('(');
      }

      this.print0(this.ucase ? "SELECT " : "select ");
      if (1 == x.getDistionOption()) {
         this.print0(this.ucase ? "ALL " : "all ");
      } else if (2 == x.getDistionOption()) {
         this.print0(this.ucase ? "DISTINCT " : "distinct ");
         List<SQLExpr> distinctOn = x.getDistinctOn();
         if (distinctOn != null && distinctOn.size() > 0) {
            this.print0(this.ucase ? "ON " : "on ");
            if (distinctOn.size() == 1 && distinctOn.get(0) instanceof SQLListExpr) {
               this.printExpr((SQLExpr)distinctOn.get(0));
               this.print(' ');
            } else {
               this.print0("(");
               this.printAndAccept(distinctOn, ", ");
               this.print0(") ");
            }
         }
      }

      this.printSelectList(x.getSelectList());
      if (x.getInto() != null) {
         this.println();
         if (x.getIntoOption() != null) {
            this.print0(x.getIntoOption().name());
            this.print(' ');
         }

         this.print0(this.ucase ? "INTO " : "into ");
         x.getInto().accept(this);
      }

      if (x.getFrom() != null) {
         this.println();
         this.print0(this.ucase ? "FROM " : "from ");
         x.getFrom().accept(this);
      }

      SQLExpr where = x.getWhere();
      if (where != null) {
         this.println();
         this.print0(this.ucase ? "WHERE " : "where ");
         where.accept(this);
         if (where.hasAfterComment() && this.isPrettyFormat()) {
            this.print(' ');
            this.printlnComment(x.getWhere().getAfterCommentsDirect());
         }
      }

      if (x.getGroupBy() != null) {
         this.println();
         x.getGroupBy().accept(this);
      }

      List<SQLWindow> windows = x.getWindows();
      if (windows != null && windows.size() > 0) {
         this.println();
         this.print0(this.ucase ? "WINDOW " : "window ");
         this.printAndAccept(windows, ", ");
      }

      if (x.getOrderBy() != null) {
         this.println();
         x.getOrderBy().accept(this);
      }

      if (x.isUsing()) {
         this.print0(this.ucase ? " USING " : " using ");
         x.getUsingOperator().accept(this);
      }

      if (x.getLimit() != null) {
         this.println();
         x.getLimit().accept(this);
      }

      if (x.getFetch() != null) {
         this.println();
         x.getFetch().accept(this);
      }

      if (x.getForClause() != null) {
         this.println();
         x.getForClause().accept(this);
      }

      if (bracket) {
         this.print(')');
      }

      return false;
   }

   public void endVisit(GaussSelectQueryBlock.FetchClause x) {
   }

   public boolean visit(SQLTruncateStatement x) {
      this.print0(this.ucase ? "TRUNCATE TABLE " : "truncate table ");
      if (x.isOnly()) {
         this.print0(this.ucase ? "ONLY " : "only ");
      }

      this.printlnAndAccept(x.getTableSources(), ", ");
      if (x.getRestartIdentity() != null) {
         if (x.getRestartIdentity()) {
            this.print0(this.ucase ? " RESTART IDENTITY" : " restart identity");
         } else {
            this.print0(this.ucase ? " CONTINUE IDENTITY" : " continue identity");
         }
      }

      if (x.getCascade() != null) {
         if (x.getCascade()) {
            this.print0(this.ucase ? " CASCADE" : " cascade");
         } else {
            this.print0(this.ucase ? " RESTRICT" : " restrict");
         }
      }

      if (x.isPurge()) {
         this.print0(this.ucase ? " PURGE " : " purge ");
      }

      return false;
   }

   public boolean visit(GaussAlterSessionStatement x) {
      this.print0(this.ucase ? "ALTER SESSION SET " : "alter session set ");
      if (x.isSessionCharacteristicsAs()) {
         this.print0(this.ucase ? "SESSION CHARACTERISTICS AS " : "session characteristics as ");
      }

      if (x.isTransaction()) {
         this.print0(this.ucase ? "TRANSACTION " : "transaction ");
      }

      if (x.isIsolationLevel()) {
         this.print0(this.ucase ? "ISOLATION LEVEL " : "isolation level ");
      }

      if (x.isReadCommitted()) {
         this.print0(this.ucase ? "READ COMMITTED " : "read committed ");
      }

      if (x.isReadUncommitted()) {
         this.print0(this.ucase ? "READ UNCOMMITTED " : "read uncommitted ");
      }

      if (x.isReadOnly()) {
         this.print0(this.ucase ? "READ ONLY " : "read only ");
      }

      if (x.isReadWrite()) {
         this.print0(this.ucase ? "READ WRITE " : "read write ");
      }

      if (x.getConfigParameter() != null) {
         x.getConfigParameter().accept(this);
         this.print0(" ");
      }

      if (x.isConfigParameterTo()) {
         this.print0(this.ucase ? "TO " : "to ");
      }

      if (x.isConfigParameterEq()) {
         this.print0("= ");
      }

      if (x.getValue() != null) {
         x.getValue().accept(this);
         this.print0(" ");
      }

      if (x.isConfigParameterDefault()) {
         this.print0(this.ucase ? "DEFAULT " : "default ");
      }

      if (x.isFromCurrent()) {
         this.print0(this.ucase ? "FROM CURRENT " : "from current ");
      }

      if (x.isCurrentSchema()) {
         this.print0(this.ucase ? "CURRENT_SCHEMA " : "current_schema ");
      }

      if (x.isCurrentSchemaTo()) {
         this.print0(this.ucase ? "TO " : "to ");
      }

      if (x.isCurrentSchemaEq()) {
         this.print0("= ");
      }

      if (x.getSchema() != null) {
         x.getSchema().accept(this);
         this.print0(" ");
      }

      if (x.isCurrentSchemaDefault()) {
         this.print0(this.ucase ? "DEFAULT " : "default ");
      }

      if (x.isTimeZone()) {
         this.print0(this.ucase ? "TIME ZONE " : "time zone ");
      }

      if (x.getTimeZoneValue() != null) {
         x.getTimeZoneValue().accept(this);
         this.print0(" ");
      }

      if (x.isSetSchema()) {
         this.print0(this.ucase ? "SCHEMA " : "schema ");
      }

      if (x.isNames()) {
         this.print0(this.ucase ? "NAMES " : "names ");
      }

      if (x.getEncodingName() != null) {
         x.getEncodingName().accept(this);
         this.print0(" ");
      }

      if (x.isRole()) {
         this.print0(this.ucase ? "ROLE " : "role ");
      }

      if (x.isSessionAuthorization()) {
         this.print0(this.ucase ? "SESSION AUTHORIZATION " : "session authorization ");
      }

      if (x.getRoleName() != null) {
         x.getRoleName().accept(this);
         this.print0(" ");
      }

      if (x.isPassword()) {
         this.print0(this.ucase ? "PASSWORD " : "password ");
      }

      if (x.getPasswordValue() != null) {
         x.getPasswordValue().accept(this);
         this.print0(" ");
      }

      if (x.isSessionAuthorizationDefault()) {
         this.print0(this.ucase ? "DEFAULT " : "default ");
      }

      if (x.isXmlOption()) {
         this.print0(this.ucase ? "XML OPTION " : "xml option ");
      }

      if (x.isDocument()) {
         this.print0(this.ucase ? "DOCUMENT " : "document ");
      }

      if (x.isContent()) {
         this.print0(this.ucase ? "CONTENT " : "content ");
      }

      return false;
   }

   public void endVisit(GaussAlterSystemKillSessionStatement x) {
   }

   public boolean visit(GaussAlterSystemKillSessionStatement x) {
      this.print0(this.ucase ? "ALTER SYSTEM KILL SESSION " : "alter system kill session ");
      if (x.getConfigParameter() != null) {
         x.getConfigParameter().accept(this);
         this.print0(" ");
      }

      if (x.isImmediate()) {
         this.print0(this.ucase ? "IMMEDIATE " : "immediate ");
      }

      return false;
   }

   public void endVisit(GaussAlterTableSpaceStatement x) {
   }

   public boolean visit(GaussDeleteStatement x) {
      if (x.getWith() != null) {
         x.getWith().accept(this);
         this.println();
      }

      this.print0(this.ucase ? "DELETE FROM " : "delete from ");
      if (x.isOnly()) {
         this.print0(this.ucase ? "ONLY " : "only ");
      }

      this.printTableSourceExpr(x.getTableName());
      if (x.getAlias() != null) {
         this.print0(this.ucase ? " AS " : " as ");
         this.print0(x.getAlias());
      }

      SQLTableSource using = x.getUsing();
      if (using != null) {
         this.println();
         this.print0(this.ucase ? "USING " : "using ");
         using.accept(this);
      }

      List<SQLTableSource> usingList = x.getUsingList();
      if (usingList != null) {
         this.println();
         this.print0(this.ucase ? "USING " : "using ");

         for(int i = 0; i < usingList.size(); ++i) {
            SQLExprTableSource sqlExprTableSource = (SQLExprTableSource)usingList.get(i);
            if (i == usingList.size() - 1) {
               this.print0(sqlExprTableSource.getExpr().toString() + " ");
            } else {
               this.print0(sqlExprTableSource.getExpr().toString() + ", ");
            }
         }
      }

      if (x.getWhere() != null) {
         this.println();
         this.print0(this.ucase ? "WHERE " : "where ");
         ++this.indentCount;
         x.getWhere().accept(this);
         --this.indentCount;
      }

      if (x.isReturning()) {
         this.println();
         this.print0(this.ucase ? "RETURNING *" : "returning *");
      }

      return false;
   }

   public void endVisit(GaussInsertStatement x) {
   }

   public boolean visit(GaussInsertStatement x) {
      if (x.getWith() != null) {
         x.getWith().accept(this);
         this.println();
      }

      this.print0(this.ucase ? "INSERT INTO " : "insert into ");
      x.getTableSource().accept(this);
      this.printInsertColumns(x.getColumns());
      if (x.getValues() != null) {
         this.println();
         this.print0(this.ucase ? "VALUES " : "values ");
         this.printlnAndAccept(x.getValuesList(), ", ");
      } else if (x.getQuery() != null) {
         this.println();
         x.getQuery().accept(this);
      }

      List<SQLExpr> duplicateKeyUpdate = x.getDuplicateKeyUpdate();
      if (duplicateKeyUpdate.size() != 0) {
         this.println();
         this.print0(this.ucase ? "ON DUPLICATE KEY UPDATE " : "on duplicate key update ");
         int i = 0;

         for(int size = duplicateKeyUpdate.size(); i < size; ++i) {
            if (i != 0) {
               if (i % 5 == 0) {
                  this.println();
               }

               this.print0(", ");
            }

            ((SQLExpr)duplicateKeyUpdate.get(i)).accept(this);
         }
      }

      List<SQLExpr> onConflictTarget = x.getOnConflictTarget();
      List<SQLUpdateSetItem> onConflictUpdateSetItems = x.getOnConflictUpdateSetItems();
      boolean onConflictDoNothing = x.isOnConflictDoNothing();
      if (onConflictDoNothing || onConflictTarget != null && onConflictTarget.size() > 0 || onConflictUpdateSetItems != null && onConflictUpdateSetItems.size() > 0) {
         this.println();
         this.print0(this.ucase ? "ON CONFLICT" : "on conflict");
         if (onConflictTarget != null && onConflictTarget.size() > 0) {
            this.print0(" (");
            this.printAndAccept(onConflictTarget, ", ");
            this.print(')');
         }

         SQLName onConflictConstraint = x.getOnConflictConstraint();
         if (onConflictConstraint != null) {
            this.print0(this.ucase ? " ON CONSTRAINT " : " on constraint ");
            this.printExpr(onConflictConstraint);
         }

         SQLExpr onConflictWhere = x.getOnConflictWhere();
         if (onConflictWhere != null) {
            this.print0(this.ucase ? " WHERE " : " where ");
            this.printExpr(onConflictWhere);
         }

         if (onConflictDoNothing) {
            this.print0(this.ucase ? " DO NOTHING" : " do nothing");
         } else if (onConflictUpdateSetItems != null && onConflictUpdateSetItems.size() > 0) {
            this.print0(this.ucase ? " DO UPDATE SET " : " do update set ");
            this.printAndAccept(onConflictUpdateSetItems, ", ");
            SQLExpr onConflictUpdateWhere = x.getOnConflictUpdateWhere();
            if (onConflictUpdateWhere != null) {
               this.print0(this.ucase ? " WHERE " : " where ");
               this.printExpr(onConflictUpdateWhere);
            }
         }
      }

      if (x.getReturning() != null) {
         this.println();
         this.print0(this.ucase ? "RETURNING " : "returning ");
         x.getReturning().accept(this);
      }

      return false;
   }

   public void endVisit(GaussSelectStatement x) {
      this.endVisit((SQLSelectStatement)x);
   }

   public boolean visit(GaussSelectStatement x) {
      return this.visit((SQLSelectStatement)x);
   }

   public void endVisit(GaussUpdateStatement x) {
   }

   public boolean visit(GaussUpdateStatement x) {
      SQLWithSubqueryClause with = x.getWith();
      if (with != null) {
         this.visit((SQLWithSubqueryClause)with);
         this.println();
      }

      this.print0(this.ucase ? "UPDATE " : "update ");
      if (x.isOnly()) {
         this.print0(this.ucase ? "ONLY " : "only ");
      }

      this.printTableSource(x.getTableSource());
      this.println();
      this.print0(this.ucase ? "SET " : "set ");
      int i = 0;

      for(int size = x.getItems().size(); i < size; ++i) {
         if (i != 0) {
            this.print0(", ");
         }

         SQLUpdateSetItem item = (SQLUpdateSetItem)x.getItems().get(i);
         this.visit((SQLUpdateSetItem)item);
      }

      SQLTableSource from = x.getFrom();
      if (from != null) {
         this.println();
         this.print0(this.ucase ? "FROM " : "from ");
         this.printTableSource(from);
      }

      SQLExpr where = x.getWhere();
      if (where != null) {
         this.println();
         ++this.indentCount;
         this.print0(this.ucase ? "WHERE " : "where ");
         this.printExpr(where);
         --this.indentCount;
      }

      List<SQLExpr> returning = x.getReturning();
      if (returning.size() > 0) {
         this.println();
         this.print0(this.ucase ? "RETURNING " : "returning ");
         this.printAndAccept(returning, ", ");
      }

      return false;
   }

   public void endVisit(GaussFunctionTableSource x) {
   }

   public boolean visit(GaussFunctionTableSource x) {
      x.getExpr().accept(this);
      if (x.getAlias() != null) {
         this.print0(this.ucase ? " AS " : " as ");
         this.print0(x.getAlias());
      }

      if (x.getParameters().size() > 0) {
         this.print('(');
         this.printAndAccept(x.getParameters(), ", ");
         this.print(')');
      }

      return false;
   }

   public void endVisit(GaussTypeCastExpr x) {
   }

   public boolean visit(GaussTypeCastExpr x) {
      SQLExpr expr = x.getExpr();
      SQLDataType dataType = x.getDataType();
      if (dataType.nameHashCode64() == FnvHash.Constants.VARBIT) {
         dataType.accept(this);
         this.print(' ');
         this.printExpr(expr);
         return false;
      } else {
         if (expr != null) {
            if (expr instanceof SQLBinaryOpExpr) {
               this.print('(');
               expr.accept(this);
               this.print(')');
            } else {
               if (expr instanceof GaussTypeCastExpr && dataType.getArguments().size() == 0) {
                  dataType.accept(this);
                  this.print('(');
                  this.visit((GaussTypeCastExpr)expr);
                  this.print(')');
                  return false;
               }

               expr.accept(this);
            }
         }

         this.print0("::");
         dataType.accept(this);
         return false;
      }
   }

   public void endVisit(GaussExtractExpr x) {
   }

   public boolean visit(GaussExtractExpr x) {
      this.print0(this.ucase ? "EXTRACT (" : "extract (");
      this.print0(x.getField().name());
      this.print0(this.ucase ? " FROM " : " from ");
      x.getSource().accept(this);
      this.print(')');
      return false;
   }

   public void endVisit(GaussBoxExpr x) {
   }

   public boolean visit(GaussBoxExpr x) {
      this.print0(this.ucase ? "BOX " : "box ");
      x.getValue().accept(this);
      return false;
   }

   public void endVisit(GaussPointExpr x) {
   }

   public boolean visit(GaussPointExpr x) {
      this.print0(this.ucase ? "POINT " : "point ");
      x.getValue().accept(this);
      return false;
   }

   public void endVisit(GaussMacAddrExpr x) {
   }

   public boolean visit(GaussMacAddrExpr x) {
      this.print0("macaddr ");
      x.getValue().accept(this);
      return false;
   }

   public void endVisit(GaussInetExpr x) {
   }

   public boolean visit(GaussInetExpr x) {
      this.print0("inet ");
      x.getValue().accept(this);
      return false;
   }

   public void endVisit(GaussCidrExpr x) {
   }

   public boolean visit(GaussCidrExpr x) {
      this.print0("cidr ");
      x.getValue().accept(this);
      return false;
   }

   public void endVisit(GaussPolygonExpr x) {
   }

   public boolean visit(GaussPolygonExpr x) {
      this.print0("polygon ");
      x.getValue().accept(this);
      return false;
   }

   public void endVisit(GaussCircleExpr x) {
   }

   public boolean visit(GaussCircleExpr x) {
      this.print0("circle ");
      x.getValue().accept(this);
      return false;
   }

   public void endVisit(GaussLineSegmentsExpr x) {
   }

   public boolean visit(GaussLineSegmentsExpr x) {
      this.print0("lseg ");
      x.getValue().accept(this);
      return false;
   }

   public void endVisit(GaussShowStatement x) {
   }

   public boolean visit(SQLBinaryExpr x) {
      this.print0(this.ucase ? "B'" : "b'");
      this.print0(x.getText());
      this.print('\'');
      return false;
   }

   public boolean visit(GaussShowStatement x) {
      this.print0(this.ucase ? "SHOW " : "show ");
      x.getExpr().accept(this);
      return false;
   }

   public void endVisit(GaussStartTransactionStatement x) {
   }

   public boolean visit(SQLLimit x) {
      if (x.getRowCount() != null) {
         this.print0(this.ucase ? "LIMIT " : "limit ");
         x.getRowCount().accept(this);
      }

      if (x.getOffset() != null) {
         this.print0(this.ucase ? " OFFSET " : " offset ");
         x.getOffset().accept(this);
      }

      return false;
   }

   public boolean visit(GaussStartTransactionStatement x) {
      this.print0(this.ucase ? "START TRANSACTION" : "start transaction");
      return false;
   }

   public void endVisit(GaussConnectToStatement x) {
   }

   public boolean visit(GaussConnectToStatement x) {
      this.print0(this.ucase ? "CONNECT TO " : "connect to ");
      x.getTarget().accept(this);
      return false;
   }

   public void endVisit(GaussCreateSchemaStatement x) {
   }

   public boolean visit(GaussCreateSchemaStatement x) {
      this.printUcase("CREATE SCHEMA ");
      if (x.isIfNotExists()) {
         this.printUcase("IF NOT EXISTS ");
      }

      if (x.getSchemaName() != null) {
         x.getSchemaName().accept(this);
         this.print0(" ");
      }

      if (x.isAuthorization()) {
         this.printUcase("AUTHORIZATION ");
         x.getUserName().accept(this);
         this.print0(" ");
      }

      if (x.getElements() != null && x.getElements().size() > 0) {
         this.incrementIndent();

         for(SQLStatement element : x.getElements()) {
            this.println();
            this.printIndent();
            element.accept(this);
         }
      }

      if (x.isWith()) {
         this.printUcase("WITH ");
         x.getWithValue().accept(this);
         this.print0(" ");
      }

      return false;
   }

   public void endVisit(GaussDropSchemaStatement x) {
   }

   public boolean visit(GaussDropSchemaStatement x) {
      this.printUcase("DROP SCHEMA ");
      if (x.isIfExists()) {
         this.printUcase("IF EXISTS ");
      }

      ArrayList<SQLIdentifierExpr> schemaList = x.getSchemaList();
      if (schemaList != null && schemaList.size() > 0) {
         this.printAndAccept(schemaList, ", ");
      }

      if (x.isCascade()) {
         this.printUcase(" CASCADE ");
      } else if (x.isRestrict()) {
         this.printUcase(" RESTRICT ");
      }

      return false;
   }

   public void endVisit(GaussAlterSchemaStatement x) {
   }

   public boolean visit(GaussAlterSchemaStatement x) {
      this.printUcase("ALTER SCHEMA ");
      x.getSchemaName().accept(this);
      if (x.getNewName() != null) {
         this.print0(" RENAME TO ");
         x.getNewName().accept(this);
      } else if (x.getNewOwner() != null) {
         this.print0(" OWNER TO ");
         x.getNewOwner().accept(this);
      }

      if (x.isWith()) {
         this.print0(" WITH ");
         if (x.getWithValue() != null) {
            x.getWithValue().accept(this);
         }
      }

      return false;
   }

   public void endVisit(GaussMethodInvokeTableSource x) {
   }

   public boolean visit(SQLSetStatement x) {
      this.print0(this.ucase ? "SET " : "set ");
      SQLSetStatement.Option option = x.getOption();
      if (option != null) {
         this.print(option.name());
         this.print(' ');
      }

      List<SQLAssignItem> items = x.getItems();

      for(int i = 0; i < items.size(); ++i) {
         if (i != 0) {
            this.print0(", ");
         }

         SQLAssignItem item = (SQLAssignItem)x.getItems().get(i);
         SQLExpr target = item.getTarget();
         target.accept(this);
         SQLExpr value = item.getValue();
         this.print(' ');
         if (target instanceof SQLIdentifierExpr && ((SQLIdentifierExpr)target).getName().equalsIgnoreCase("TIME ZONE")) {
            this.print(' ');
         } else if (value instanceof SQLPropertyExpr && ((SQLPropertyExpr)value).getOwner() instanceof SQLVariantRefExpr) {
            this.print0(" := ");
         }

         if (value instanceof SQLListExpr) {
            SQLListExpr listExpr = (SQLListExpr)value;
            this.printAndAccept(listExpr.getItems(), ", ");
         } else {
            value.accept(this);
         }
      }

      return false;
   }

   public boolean visit(GaussCreateUserStatement x) {
      this.print0(this.ucase ? "CREATE USER " : "create user ");
      x.getUser().accept(this);
      if (x.isEncrypted()) {
         this.printUcase(" ENCRYPTED ");
      } else if (x.isUnencrypted()) {
         this.printUcase(" UNENCRYPTED ");
      }

      if (x.isPasswordFlag()) {
         this.print0(this.ucase ? " PASSWORD " : " password ");
      } else {
         this.printUcase(" IDENTIFIED BY ");
      }

      SQLExpr passoword = x.getPassword();
      if (passoword instanceof SQLIdentifierExpr) {
         this.print('\'');
         passoword.accept(this);
         this.print('\'');
      } else {
         passoword.accept(this);
      }

      if (x.isExpired()) {
         this.printUcase(" EXPIRED ");
      }

      if (x.isDisable()) {
         this.printUcase(" DISABLE ");
      }

      return false;
   }

   public boolean visit(GaussCreateRoleStatement x) {
      this.print0(this.ucase ? "CREATE ROLE " : "create role ");
      x.getName().accept(this);
      if (x.isEncrypted()) {
         this.printUcase(" ENCRYPTED ");
      } else if (x.isUnencrypted()) {
         this.printUcase(" UNENCRYPTED ");
      }

      if (x.isPasswordFlag()) {
         this.print0(this.ucase ? " PASSWORD " : " password ");
      } else {
         this.printUcase(" IDENTIFIED BY ");
      }

      SQLExpr passoword = x.getPassword();
      if (passoword instanceof SQLIdentifierExpr) {
         this.print('\'');
         passoword.accept(this);
         this.print('\'');
      } else {
         passoword.accept(this);
      }

      if (x.isExpired()) {
         this.printUcase(" EXPIRED ");
      }

      if (x.isDisable()) {
         this.printUcase(" DISABLE ");
      }

      return false;
   }

   public void endVisit(GaussAlterRoleStatement x) {
   }

   public boolean visit(GaussCreateGroupStatement x) {
      this.print0(this.ucase ? "CREATE GROUP " : "create group ");
      x.getUser().accept(this);
      if (x.isEncrypted()) {
         this.printUcase(" ENCRYPTED ");
      } else if (x.isUnencrypted()) {
         this.printUcase(" UNENCRYPTED ");
      }

      if (x.isPasswordFlag()) {
         this.print0(this.ucase ? " PASSWORD " : " password ");
      } else {
         this.printUcase(" IDENTIFIED BY ");
      }

      SQLExpr passoword = x.getPassword();
      if (passoword instanceof SQLIdentifierExpr) {
         this.print('\'');
         passoword.accept(this);
         this.print('\'');
      } else {
         passoword.accept(this);
      }

      if (x.isExpired()) {
         this.printUcase(" EXPIRED ");
      }

      if (x.isDisable()) {
         this.printUcase(" DISABLE ");
      }

      return false;
   }

   public void endVisit(GaussAlterGroupStatement x) {
   }

   public void endVisit(GaussAlterUserStatement x) {
   }

   public boolean visit(GaussAlterUserStatement x) {
      this.print0(this.ucase ? "ALTER USER " : "alter user ");
      x.getUser().accept(this);
      if (x.isRenameTo()) {
         this.printUcase(" RENAME TO ");
         x.getNewName().accept(this);
         return true;
      } else if (x.isAccount()) {
         this.printUcase(" ACCOUNT ");
         if (x.isLock()) {
            this.printUcase("LOCK ");
         }

         if (x.isUnlock()) {
            this.printUcase("UNLOCK ");
         }

         return true;
      } else {
         if (x.isEncrypted()) {
            this.printUcase(" ENCRYPTED ");
         } else if (x.isUnencrypted()) {
            this.printUcase(" UNENCRYPTED ");
         }

         if (x.isPasswordFlag()) {
            this.print0(this.ucase ? " PASSWORD " : " password ");
         } else {
            this.printUcase(" IDENTIFIED BY ");
         }

         SQLExpr passoword = x.getPassword();
         if (passoword instanceof SQLIdentifierExpr) {
            this.print('\'');
            passoword.accept(this);
            this.print('\'');
         } else {
            passoword.accept(this);
         }

         if (x.isExpired()) {
            this.printUcase(" EXPIRED ");
         }

         if (x.isDisable()) {
            this.printUcase(" DISABLE ");
         }

         return false;
      }
   }

   public boolean visit(GaussAlterRoleStatement x) {
      this.print0(this.ucase ? "ALTER ROLE " : "alter role ");
      x.getUser().accept(this);
      if (x.isRenameTo()) {
         this.printUcase(" RENAME TO ");
         x.getNewName().accept(this);
         return true;
      } else if (x.isAccount()) {
         this.printUcase(" ACCOUNT ");
         if (x.isLock()) {
            this.printUcase("LOCK ");
         }

         if (x.isUnlock()) {
            this.printUcase("UNLOCK ");
         }

         return true;
      } else {
         if (x.isEncrypted()) {
            this.printUcase(" ENCRYPTED ");
         } else if (x.isUnencrypted()) {
            this.printUcase(" UNENCRYPTED ");
         }

         if (x.isPasswordFlag()) {
            this.print0(this.ucase ? " PASSWORD " : " password ");
         } else {
            this.printUcase(" IDENTIFIED BY ");
         }

         SQLExpr passoword = x.getPassword();
         if (passoword instanceof SQLIdentifierExpr) {
            this.print('\'');
            passoword.accept(this);
            this.print('\'');
         } else {
            passoword.accept(this);
         }

         if (x.isExpired()) {
            this.printUcase(" EXPIRED ");
         }

         if (x.isDisable()) {
            this.printUcase(" DISABLE ");
         }

         return false;
      }
   }

   public void endVisit(GaussCreateTableAsStatement x) {
   }

   public boolean visit(GaussAlterGroupStatement x) {
      this.printUcase("ALTER GROUP ");
      x.getGroupName().accept(this);
      if (x.isRenameTo()) {
         this.printUcase(" RENAME TO ");
         x.getNewName().accept(this);
         return true;
      } else if (x.isAddUser()) {
         this.printUcase(" ADD USER ");
         this.printAndAccept(x.getNames().getItems(), ", ");
         return true;
      } else {
         if (x.isDropUser()) {
            this.printUcase(" DROP USER ");
            this.printAndAccept(x.getNames().getItems(), ", ");
         }

         return true;
      }
   }

   public void endVisit(GaussCreateMaterializedViewStatement x) {
   }

   public void endVisit(GaussCommonStatement x) {
   }

   public boolean visit(GaussCommonStatement x) {
      if (x.isShutdown()) {
         this.printUcase("SHUTDOWN ");
         if (x.getShutdownParam() != null) {
            x.getShutdownParam().accept(this);
         }
      }

      if (x.isDropGroup()) {
         this.printUcase("DROP GROUP ");
         if (x.isIfExists()) {
            this.printUcase("IF EXISTS ");
         }

         this.printAndAccept(x.getGroupNameList().getItems(), ", ");
      }

      if (x.isSavepoint()) {
         this.printUcase("SAVEPOINT ");
         if (x.getSavepointName() != null) {
            x.getSavepointName().accept(this);
         }
      }

      if (x.isRollback()) {
         this.printUcase("ROLLBACK ");
         if (x.isPrepared()) {
            this.printUcase("PREPARED ");
         }

         if (x.isWork()) {
            this.printUcase("WORK ");
         }

         if (x.isTransaction()) {
            this.printUcase("TRANSACTION ");
         }

         if (x.getTransactionId() != null) {
            x.getTransactionId().accept(this);
         }
      }

      if (x.isCheckpoint()) {
         this.printUcase("CHECKPOINT ");
      }

      if (x.isReset()) {
         this.printUcase("RESET ");
         if (x.isRole()) {
            this.printUcase("ROLE ");
         }
      }

      if (x.isCommit()) {
         this.printUcase("COMMIT ");
         if (x.isPrepared()) {
            this.printUcase("PREPARED ");
         }

         if (x.isWork()) {
            this.printUcase("WORK ");
         }

         if (x.isTransaction()) {
            this.printUcase("TRANSACTION ");
         }

         if (x.getTransactionId() != null) {
            x.getTransactionId().accept(this);
            this.print(" ");
            if (x.isWith()) {
               this.printUcase("WITH ");
            }

            if (x.getCsn() != null) {
               x.getCsn().accept(this);
            }
         }
      }

      if (x.isEnd()) {
         this.printUcase("END ");
         if (x.isWork()) {
            this.printUcase("WORK ");
         }

         if (x.isTransaction()) {
            this.printUcase("TRANSACTION ");
         }
      }

      return false;
   }

   public void endVisit(GaussCreateGroupStatement x) {
   }

   protected void printGrantPrivileges(SQLGrantStatement x) {
      List<SQLPrivilegeItem> privileges = x.getPrivileges();
      int i = 0;

      for(SQLPrivilegeItem privilege : privileges) {
         if (i != 0) {
            this.print(", ");
         }

         SQLExpr action = privilege.getAction();
         if (action instanceof SQLIdentifierExpr) {
            String name = ((SQLIdentifierExpr)action).getName();
            if ("RESOURCE".equalsIgnoreCase(name)) {
               continue;
            }
         }

         privilege.accept(this);
         ++i;
      }

   }

   public boolean visit(GaussGrantStatement x) {
      this.print0(this.ucase ? "GRANT " : "grant ");
      this.printAndAccept(x.getPrivileges(), ", ");
      this.printGrantOn(x);
      if (x.getRoleName() != null) {
         x.getRoleName().accept(this);
      }

      if (x.getUsers() != null && x.getUsers().size() > 0) {
         this.print0(this.ucase ? " TO " : " to ");
         this.printAndAccept(x.getUsers(), ",");
      }

      if (x.getGroups() != null && x.getGroups().size() > 0) {
         this.print0(this.ucase ? " TO Group " : " to group ");
         this.printAndAccept(x.getGroups(), ",");
      }

      if (x.getWithGrantOption()) {
         this.print0(this.ucase ? " WITH GRANT OPTION" : " with grant option");
      }

      boolean with = false;
      SQLExpr maxQueriesPerHour = x.getMaxQueriesPerHour();
      if (maxQueriesPerHour != null) {
         if (!with) {
            this.print0(this.ucase ? " WITH" : " with");
            with = true;
         }

         this.print0(this.ucase ? " MAX_QUERIES_PER_HOUR " : " max_queries_per_hour ");
         maxQueriesPerHour.accept(this);
      }

      SQLExpr maxUpdatesPerHour = x.getMaxUpdatesPerHour();
      if (maxUpdatesPerHour != null) {
         if (!with) {
            this.print0(this.ucase ? " WITH" : " with");
            with = true;
         }

         this.print0(this.ucase ? " MAX_UPDATES_PER_HOUR " : " max_updates_per_hour ");
         maxUpdatesPerHour.accept(this);
      }

      SQLExpr maxConnectionsPerHour = x.getMaxConnectionsPerHour();
      if (maxConnectionsPerHour != null) {
         if (!with) {
            this.print0(this.ucase ? " WITH" : " with");
            with = true;
         }

         this.print0(this.ucase ? " MAX_CONNECTIONS_PER_HOUR " : " max_connections_per_hour ");
         maxConnectionsPerHour.accept(this);
      }

      SQLExpr maxUserConnections = x.getMaxUserConnections();
      if (maxUserConnections != null) {
         if (!with) {
            this.print0(this.ucase ? " WITH" : " with");
            with = true;
         }

         this.print0(this.ucase ? " MAX_USER_CONNECTIONS " : " max_user_connections ");
         maxUserConnections.accept(this);
      }

      if (x.isAdminOption()) {
         if (!with) {
            this.print0(this.ucase ? " WITH" : " with");
            with = true;
         }

         this.print0(this.ucase ? " ADMIN OPTION" : " admin option");
      }

      if (x.getIdentifiedBy() != null) {
         this.print0(this.ucase ? " IDENTIFIED BY " : " identified by ");
         x.getIdentifiedBy().accept(this);
      }

      return false;
   }

   public boolean visit(GaussRevokeStatement x) {
      this.print0(this.ucase ? "REVOKE " : "revoke ");
      if (x.isGrantOptionFor()) {
         this.print0(this.ucase ? "GRANT OPTION FOR " : "grant option for ");
      }

      this.printAndAccept(x.getPrivileges(), ", ");
      this.printRevokeOn(x);
      if (x.getRoleName() != null) {
         x.getRoleName().accept(this);
      }

      if (x.getUsers() != null && x.getUsers().size() > 0) {
         this.print0(this.ucase ? " TO " : " to ");
         this.printAndAccept(x.getUsers(), ",");
      }

      if (x.getGroups() != null && x.getGroups().size() > 0) {
         this.print0(this.ucase ? " TO Group " : " to group ");
         this.printAndAccept(x.getGroups(), ",");
      }

      if (x.isCascade()) {
         this.printUcase(" CASCADE");
      }

      if (x.isRestrict()) {
         this.printUcase(" RESTRICT");
      }

      return false;
   }

   public void endVisit(GaussCreateTriggerStatement x) {
   }

   public boolean visit(SQLIfStatement.Else x) {
      this.print0(this.ucase ? "ELSE" : "else");
      ++this.indentCount;
      this.println();
      int i = 0;

      for(int size = x.getStatements().size(); i < size; ++i) {
         if (i != 0) {
            this.println();
         }

         SQLStatement item = (SQLStatement)x.getStatements().get(i);
         item.accept(this);
      }

      --this.indentCount;
      return false;
   }

   public boolean visit(SQLIfStatement.ElseIf x) {
      this.print0(this.ucase ? "ELSE IF " : "else if ");
      x.getCondition().accept(this);
      this.print0(this.ucase ? " THEN" : " then");
      ++this.indentCount;
      int i = 0;

      for(int size = x.getStatements().size(); i < size; ++i) {
         this.println();
         SQLStatement item = (SQLStatement)x.getStatements().get(i);
         item.accept(this);
      }

      --this.indentCount;
      return false;
   }

   public boolean visit(SQLIfStatement x) {
      this.print0(this.ucase ? "IF " : "if ");
      int lines = this.lines;
      ++this.indentCount;
      x.getCondition().accept(this);
      --this.indentCount;
      if (lines != this.lines) {
         this.println();
      } else {
         this.print(' ');
      }

      this.print0(this.ucase ? "THEN" : "then");
      ++this.indentCount;
      int i = 0;

      for(int size = x.getStatements().size(); i < size; ++i) {
         this.println();
         SQLStatement item = (SQLStatement)x.getStatements().get(i);
         item.accept(this);
      }

      --this.indentCount;

      for(SQLIfStatement.ElseIf elseIf : x.getElseIfList()) {
         this.println();
         elseIf.accept(this);
      }

      if (x.getElseItem() != null) {
         this.println();
         x.getElseItem().accept(this);
      }

      this.println();
      this.print0(this.ucase ? "END IF" : "end if");
      return false;
   }

   public boolean visit(SQLArrayDataType x) {
      x.getComponentType().accept(this);
      this.print('[');
      this.printAndAccept(x.getArguments(), ", ");
      this.print(']');
      return false;
   }

   public boolean visit(GaussExprTableSource ts) {
      if (ts.isOnly()) {
         this.print0(" ONLY ");
      }

      if (ts.getExpr() != null) {
         ts.getExpr().accept(this);
      }

      if (ts.getAlias() != null) {
         this.print0(" AS ");
         this.print0(ts.getAlias());
         this.print0(" ");
      }

      if (ts.getColumns() != null && ts.getColumns().size() > 0) {
         this.print0("(");

         for(int i = 0; i < ts.getColumns().size(); ++i) {
            ((SQLName)ts.getColumns().get(i)).accept(this);
            if (i != ts.getColumns().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (ts.getSampling() != null) {
         ts.getSampling().accept(this);
      }

      return false;
   }

   public void endVisit(GaussSubqueryTableSource x) {
   }

   public boolean visit(GaussSubqueryTableSource ts) {
      if (ts.isOnly()) {
         this.print0(" ONLY ");
      }

      if (ts.getSelect() != null) {
         this.print0("(");
         ts.getSelect().accept(this);
         this.print0(")");
      }

      if (ts.getAlias() != null) {
         this.print0(" AS ");
         this.print0(ts.getAlias());
         this.print0(" ");
      }

      if (ts.getColumns() != null && ts.getColumns().size() > 0) {
         this.print0("(");

         for(int i = 0; i < ts.getColumns().size(); ++i) {
            ((SQLName)ts.getColumns().get(i)).accept(this);
            if (i != ts.getColumns().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      return false;
   }

   public void endVisit(GaussValuesTableSource x) {
   }

   public boolean visit(GaussMethodInvokeTableSource ts) {
      if (ts.isOnly()) {
         this.print0(" ONLY ");
      }

      ts.getExpr().accept(this);
      this.print0("(");

      for(int i = 0; i < ts.getParameters().size(); ++i) {
         ((SQLExpr)ts.getParameters().get(i)).accept(this);
         if (i != ts.getParameters().size() - 1) {
            this.print0(",");
         }
      }

      this.print0(")");
      if (ts.isWithOrdinality()) {
         this.print0(this.ucase ? " WITH ORDINALITY " : " with ordinality ");
      }

      if (ts.getAlias() != null) {
         this.print0(this.ucase ? " AS " : " as ");
         this.print0(ts.getAlias());
      }

      List<GaussColumnSimpleDefinitionExpr> defines = ts.getDefines();
      boolean flag = false;
      if (defines != null && defines.size() > 0) {
         flag = true;
         this.print0(this.ucase ? " AS (" : " as (");

         for(int i = 0; i < defines.size(); ++i) {
            GaussColumnSimpleDefinitionExpr def = (GaussColumnSimpleDefinitionExpr)defines.get(i);
            def.getName().accept(this);
            if (def.getType() != null) {
               this.print0(" ");
               def.getType().accept(this);
            }

            if (i != defines.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (!flag && ts.getColumns() != null && ts.getColumns().size() > 0) {
         this.print0("(");

         for(int i = 0; i < ts.getColumns().size(); ++i) {
            ((SQLName)ts.getColumns().get(i)).accept(this);
            if (i != ts.getColumns().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      return false;
   }

   public void endVisit(GaussExprTableSource x) {
   }

   public boolean visit(GaussRowsFromTableSource ts) {
      this.print0(this.ucase ? "ROWS FROM (" : "rows from (");

      for(int i = 0; i < ts.getInvokers().size(); ++i) {
         ((GaussMethodInvokeTableSource)ts.getInvokers().get(i)).accept(this);
         if (i != ts.getInvokers().size() - 1) {
            this.print0(",");
         }
      }

      this.print0(")");
      if (ts.isWithOrdinality()) {
         this.print0(this.ucase ? " WITH ORDINALITY " : " with ordinality ");
      }

      if (ts.getAlias() != null) {
         this.print0(this.ucase ? " AS " : " as ");
         this.print0(ts.getAlias());
      }

      if (ts.getColumns() != null && ts.getColumns().size() > 0) {
         this.print0("(");

         for(int i = 0; i < ts.getColumns().size(); ++i) {
            ((SQLName)ts.getColumns().get(i)).accept(this);
            if (i != ts.getColumns().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (ts.isRowsFrom()) {
         this.print0(") ");
      }

      return false;
   }

   public void endVisit(GaussAlterDatabaseStatement x) {
   }

   public boolean visit(GaussValuesTableSource ts) {
      this.println();
      this.print0("(");
      this.print0(this.ucase ? "VALUES " : "values ");

      for(int i = 0; i < ts.getRows().size(); ++i) {
         GaussValuesTableSource.ValueRow row = (GaussValuesTableSource.ValueRow)ts.getRows().get(i);
         this.print0("(");

         for(int j = 0; j < row.getVals().size(); ++j) {
            ((SQLExpr)row.getVals().get(j)).accept(this);
            if (j != row.getVals().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
         if (i != ts.getRows().size() - 1) {
            this.print0(",");
         }
      }

      this.print0(") ");
      this.print0(ts.getAlias());
      if (ts.getColumns().size() > 0) {
         List<SQLName> columns = ts.getColumns();
         this.print0(" (");

         for(int i = 0; i < columns.size(); ++i) {
            ((SQLName)columns.get(i)).accept(this);
            if (i != columns.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      return false;
   }

   public void endVisit(GaussValuesTableSource.ValueRow x) {
   }

   public boolean visit(GaussValuesTableSource.ValueRow x) {
      return true;
   }

   public void endVisit(GaussSelectQueryBlock.ForClauses x) {
   }

   public boolean visit(GaussAlterDatabaseStatement stmt) {
      this.print0(this.ucase ? "ALTER DATABASE " : "alter database ");
      stmt.getName().accept(this);
      this.print0(" ");
      if (stmt.isEnable()) {
         this.print0(this.ucase ? "WITH ENABLE  " : "with DISABLE ");
         stmt.getPrivateValue().accept(this);
         stmt.getObjectValue().accept(this);
      }

      if (stmt.isDisable()) {
         this.print0(this.ucase ? "WITH DISABLE  " : "with disable ");
         stmt.getPrivateValue().accept(this);
         stmt.getObjectValue().accept(this);
      }

      if (stmt.getConnLimit() != null) {
         this.print0(this.ucase ? "WITH CONNECTION LIMIT " : "with connection limit ");
         stmt.getConnLimit().accept(this);
      } else if (stmt.getNewName() != null) {
         this.print0(this.ucase ? "RENAME TO " : "rename to ");
         stmt.getNewName().accept(this);
      } else if (stmt.getNewOwner() != null) {
         this.print0(this.ucase ? "OWNER TO " : "owner to ");
         stmt.getNewOwner().accept(this);
      } else if (stmt.getType() == GaussAlterDatabaseStatement.SetType.Set) {
         this.print0(this.ucase ? "SET " : "set ");
         if (stmt.getNewTableSpace() != null) {
            this.print0(this.ucase ? "TABLESPACE " : "tablespace ");
            stmt.getNewTableSpace().accept(this);
         } else {
            stmt.getParamter().accept(this);
            this.print0(" ");
            if (stmt.getValues() != null && stmt.getValues().size() > 0) {
               if (stmt.isSetTo()) {
                  this.print0(this.ucase ? "TO " : "to ");
               } else {
                  this.print0("= ");
               }

               for(int i = 0; i < stmt.getValues().size(); ++i) {
                  ((SQLExpr)stmt.getValues().get(i)).accept(this);
                  if (i != stmt.getValues().size() - 1) {
                     this.print0(",");
                  }
               }
            } else if (stmt.isSetFromCurrent()) {
               this.print0(this.ucase ? "FROM CURRENT" : "from current");
            }
         }
      } else if (stmt.getType() == GaussAlterDatabaseStatement.SetType.Reset) {
         this.print0(this.ucase ? "RESET " : "reset ");
         if (stmt.getParamter() != null) {
            stmt.getParamter().accept(this);
         } else {
            this.print0(this.ucase ? "ALL" : "all");
         }
      }

      return false;
   }

   public void endVisit(GaussAlterIndexStatement x) {
   }

   public boolean visit(GaussAlterIndexStatement x) {
      this.print0(this.ucase ? "ALTER INDEX " : "alter index ");
      if (x.isSetIfExists()) {
         this.printUcase("IF EXISTS ");
      }

      if (x.isSetAllIn()) {
         this.printUcase("ALL IN TABLESPACE ");
      }

      x.getName().accept(this);
      if (x.isSetOwnedBy()) {
         this.printUcase(" OWNED BY ");
      }

      List<SQLExpr> roleList = x.getRoleList();
      if (roleList != null && roleList.size() > 0) {
         this.printAndAccept(roleList, ", ");
      }

      if ("Set".equals(x.getType().name())) {
         this.print0(this.ucase ? " SET " : " set ");
         if (x.getNewTableSpace() != null) {
            this.print0(this.ucase ? "TABLESPACE " + x.getNewTableSpace() : " tablespace " + x.getNewTableSpace());
         }

         List<SQLUpdateSetItem> parameterList = x.getParameterList();
         if (parameterList != null && parameterList.size() > 0) {
            this.print0("(");
            this.printAndAccept(parameterList, ", ");
            this.print0(")");
         }

         if (x.isSetNowait()) {
            this.print0(" NOWAIT");
         }
      }

      if ("Reset".equals(x.getType().name())) {
         this.print0(this.ucase ? " RESET " : " reset ");
         List<SQLExpr> itemList = x.getItemList();
         if (itemList != null && itemList.size() > 0) {
            this.print0("(");
            this.printAndAccept(itemList, ", ");
            this.print0(")");
         }
      }

      if (x.getRenameTo() != null) {
         this.print0(this.ucase ? " RENAME TO " : " rename to ");
         x.getRenameTo().accept(this);
      }

      return false;
   }

   public void endVisit(GaussAlterSequenceStatement x) {
   }

   public boolean visit(GaussAlterSequenceStatement x) {
      this.print0(this.ucase ? "ALTER " : "alter ");
      if (x.isLarge()) {
         this.print0(this.ucase ? "LARGE " : "large ");
      }

      this.print0(this.ucase ? "SEQUENCE " : "sequence ");
      if (x.isIfExists()) {
         this.printUcase("IF EXISTS ");
      }

      x.getName().accept(this);
      if (x.getIncrementBy() != null) {
         this.print0(this.ucase ? " INCREMENT " : " increment ");
         if (x.isBy()) {
            this.print0(this.ucase ? "BY " : "by ");
         }

         x.getIncrementBy().accept(this);
      }

      if (x.getMinValue() != null) {
         this.print0(this.ucase ? " MINVALUE " : " minvalue ");
         x.getMinValue().accept(this);
      }

      if (x.getMaxValue() != null) {
         this.print0(this.ucase ? " MAXVALUE " : " maxvalue ");
         x.getMaxValue().accept(this);
      }

      if (x.isNoMaxValue()) {
         this.print0(this.ucase ? " NO MAXVALUE" : " no maxvalue");
      }

      if (x.isNoMinValue()) {
         this.print0(this.ucase ? " NO MINVALUE" : " no minvalue");
      }

      if (x.getStartWith() != null) {
         this.print0(this.ucase ? " START " : " start ");
         if (x.isStart()) {
            this.print0(this.ucase ? "WITH " : "with ");
         }

         x.getStartWith().accept(this);
      }

      SQLExpr restartWith = x.getRestartWith();
      if (restartWith != null) {
         this.print0(this.ucase ? " RESTART" : " restart");
         if (x.isRestart()) {
            this.print0(this.ucase ? " WITH " : " with ");
         }

         restartWith.accept(this);
      }

      Boolean cache = x.getCache();
      if (cache != null && cache) {
         this.print0(this.ucase ? " CACHE " : " cache ");
         SQLExpr cacheValue = x.getCacheValue();
         if (cacheValue != null) {
            cacheValue.accept(this);
         }
      }

      if (x.getCycle() != null) {
         if (x.isCycleNo()) {
            this.print0(this.ucase ? " NO" : " no");
         }

         if (x.getCycle()) {
            this.print0(this.ucase ? " CYCLE" : " cycle");
         }
      }

      if (x.isOwnedBy()) {
         this.print0(this.ucase ? " OWNED BY " : " owned by ");
         x.getOwnedByName().accept(this);
      }

      if (x.isNone()) {
         this.print0(this.ucase ? " NONE " : " none ");
      }

      if (x.isOwnerTo()) {
         this.print0(this.ucase ? " OWNER TO " : " owner to ");
         x.getNewOwner().accept(this);
      }

      if (x.isRenameTo()) {
         this.print0(this.ucase ? " RENAME TO " : " rename to ");
         x.getNewName().accept(this);
      }

      if (x.isSetSchema()) {
         this.print0(this.ucase ? " SET SCHEMA " : " set schema ");
         x.getNewSchema().accept(this);
      }

      return false;
   }

   public void endVisit(GaussAlterTableStatement x) {
   }

   public boolean visit(GaussAlterTableStatement stmt) {
      this.print0(this.ucase ? "ALTER TABLE " : "alter table ");
      if (stmt.isIfExists()) {
         this.print0(this.ucase ? "IF EXISTS " : "if exists ");
      }

      if (stmt.isOnly()) {
         this.print0(this.ucase ? "ONLY " : "only ");
      }

      if (stmt.getTableName() != null) {
         stmt.getName().accept(this);
      }

      this.print0(" ");

      for(int i = 0; i < stmt.getItems().size(); ++i) {
         this.println();
         this.print("\t");
         ((SQLAlterTableItem)stmt.getItems().get(i)).accept(this);
         if (i != stmt.getItems().size() - 1) {
            this.print0(",");
         }
      }

      return false;
   }

   public void endVisit(GaussAlterTableRenameColumn x) {
   }

   public boolean visit(GaussAlterTableRenameColumn item) {
      this.print0(this.ucase ? "RENAME COLUMN " : "rename column ");
      item.getCol().accept(this);
      this.print0(this.ucase ? " TO " : " to ");
      item.getTo().accept(this);
      return false;
   }

   public void endVisit(GaussAlterTableRenameConstraint x) {
   }

   public boolean visit(GaussAlterTableRenameConstraint item) {
      this.print0(this.ucase ? "RENAME CONSTRAINT " : "rename constraint ");
      item.getCol().accept(this);
      this.print0(this.ucase ? " TO " : " to ");
      item.getTo().accept(this);
      return false;
   }

   public void endVisit(GaussAlterTableRenameTo x) {
   }

   public boolean visit(GaussAlterTableRenameTo item) {
      this.print0(this.ucase ? "RENAME TO " : "rename to ");
      item.getTo().accept(this);
      return false;
   }

   public void endVisit(GaussAlterTableSetSchema x) {
   }

   public boolean visit(GaussAlterTableSetSchema item) {
      this.print0(this.ucase ? "SET SCHEMA " : "set schema ");
      item.getSchema().accept(this);
      return false;
   }

   public void endVisit(GaussAlterTableSetNewTableSpace x) {
   }

   public boolean visit(GaussAlterTableSetNewTableSpace item) {
      this.print0(this.ucase ? "ALL IN TABLESPACE " : "all in tablespace ");
      item.getName().accept(this);
      this.print0(" ");
      if (item.getOwners() != null && item.getOwners().size() > 0) {
         this.print0(this.ucase ? "OWNED BY " : "owned by ");

         for(int i = 0; i < item.getOwners().size(); ++i) {
            ((SQLExpr)item.getOwners().get(i)).accept(this);
            if (i != item.getOwners().size() - 1) {
               this.print(",");
            }
         }

         this.print0(" ");
      }

      this.print0(this.ucase ? "SET TABLESPACE " : "set tablespace ");
      item.getNewTablespace().accept(this);
      if (item.isNowait()) {
         this.print0(this.ucase ? " NOWAIT " : " nowait ");
      }

      return false;
   }

   public void endVisit(GaussAlterTableSetWith x) {
   }

   public boolean visit(GaussAlterTableSetWith item) {
      this.print0(this.ucase ? "SET " : "set ");
      switch (item.getDistributeType()) {
         case with:
            this.print0(this.ucase ? "WITH (REORGANIZE=" : "with (reorganize=");
            this.print0(item.isWithReorgnize() ? "true" : "false");
            this.print0(")");
            break;
         case by:
            this.print0(this.ucase ? "DISTRIBUTED BY (" : "distributed by (");

            for(int i = 0; i < item.getOptions().size(); ++i) {
               GaussAlterTableSetWith.GaussAlterTableDistributeByOption option = (GaussAlterTableSetWith.GaussAlterTableDistributeByOption)item.getOptions().get(i);
               option.getColumnName().accept(this);
               if (option.getOpClass() != null) {
                  this.print0(" ");
                  option.getOpClass().accept(this);
               }

               if (i != item.getOptions().size() - 1) {
                  this.print0(",");
               }
            }

            this.print0(")");
            break;
         case randomly:
            this.print0(this.ucase ? "DISTRIBUTED RANDOMLY" : "distributed randomly");
            break;
         case replicated:
            this.print0(this.ucase ? "DISTRIBUTED REPLICATED" : "distributed replicated");
      }

      return false;
   }

   public void endVisit(GaussAlterTableAddColumn x) {
   }

   public boolean visit(GaussAlterTableAddColumn item) {
      this.print0(this.ucase ? "ADD COLUMN " : "add column ");
      GaussColumnDefinition column = (GaussColumnDefinition)item.getColumns().get(0);
      column.getName().accept(this);
      this.print0(" ");
      column.getType().accept(this);
      this.print0(" ");
      SQLExpr defaultExpr = column.getDefaultExpr();
      if (defaultExpr != null) {
         this.print0(this.ucase ? "DEFAULT " : "default ");
         defaultExpr.accept(this);
         this.print0(" ");
      }

      List<SQLColumnConstraint> constraints = column.getConstraints();
      if (constraints != null && constraints.size() > 0) {
         for(SQLColumnConstraint constraint : constraints) {
            constraint.accept(this);
            this.print0(" ");
         }
      }

      SQLExpr collateExpr = column.getCollateExpr();
      if (collateExpr != null) {
         this.print0(this.ucase ? "COLLATE " : "collate ");
         collateExpr.accept(this);
         this.print0(" ");
      }

      List<SQLExpr> encodings = column.getEncodings();
      if (encodings != null && encodings.size() > 0) {
         this.print0(this.ucase ? "ENCODING (" : "encoding (");

         for(int i = 0; i < encodings.size(); ++i) {
            ((SQLExpr)encodings.get(i)).accept(this);
            if (i != encodings.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      return false;
   }

   public void endVisit(GaussAlterTableSetWith.GaussAlterTableDistributeByOption x) {
   }

   public boolean visit(GaussAlterTableSetWith.GaussAlterTableDistributeByOption x) {
      return true;
   }

   public void endVisit(GaussAlterTableDropColumn x) {
   }

   public boolean visit(GaussAlterTableDropColumn item) {
      this.print0(this.ucase ? "DROP COLUMN " : "drop column ");
      if (item.isIfExists()) {
         this.print0(this.ucase ? "IF EXISTS " : "if exists ");
      }

      item.getColumnName().accept(this);
      this.print0(" ");
      GaussAlterTableDropColumn.DropColumType type = item.getType();
      if (type != null) {
         if (type == GaussAlterTableDropColumn.DropColumType.restrict) {
            this.print0(this.ucase ? "RESTRICT " : "restrict ");
         } else {
            this.print0(this.ucase ? "CASCADE " : "cascade ");
         }
      }

      return false;
   }

   public void endVisit(GaussAlterTableAlterColumn x) {
   }

   public boolean visit(GaussAlterTableAlterColumn item) {
      this.print0(this.ucase ? "ALTER COLUMN " : "alter column ");
      item.getColumn().accept(this);
      this.print0(" ");
      switch (item.getType()) {
         case setType:
            this.print0(this.ucase ? "SET DATA TYPE " : "set data type ");
            item.getDataType().accept(this);
            this.print0(" ");
            SQLExpr collation = item.getCollation();
            if (collation != null) {
               this.print0(this.ucase ? "COLLATE " : "collate ");
               collation.accept(this);
               this.print0(" ");
            }

            SQLExpr usingExpression = item.getUsingExpression();
            if (usingExpression != null) {
               this.print0(this.ucase ? "USING " : "using ");
               usingExpression.accept(this);
               this.print0(" ");
            }
            break;
         case setDefault:
            this.print0(this.ucase ? "SET DEFAULT " : "set default ");
            item.getDefaultExpression().accept(this);
            break;
         case dropDefault:
            this.print0(this.ucase ? "DROP DEFAULT " : "drop default ");
            break;
         case setNotNull:
            this.print0(this.ucase ? "SET NOT NULL " : "set not null ");
            break;
         case dropNotNull:
            this.print0(this.ucase ? "DROP NOT NULL " : "drop not null ");
            break;
         case setStatistics:
            this.print0(this.ucase ? "SET STATISTICS " : "set statistics ");
            item.getStatics().accept(this);
            this.print0(" ");
      }

      return false;
   }

   public void endVisit(GaussAlterTableAlterColumnOptions x) {
   }

   public boolean visit(GaussAlterTableAlterColumnOptions item) {
      this.print0(this.ucase ? "ALTER COLUMN COLUMN " : "alter column column ");
      if (item.isSet()) {
         this.print0(this.ucase ? "SET (" : "set (");
      } else {
         this.print0(this.ucase ? "RESET (" : "reset (");
      }

      List<GaussAlterTableAlterColumnOptions.GaussAlterTableAlterColumnOptionValue> options = item.getOptions();

      for(int i = 0; i < options.size(); ++i) {
         GaussAlterTableAlterColumnOptions.GaussAlterTableAlterColumnOptionValue option = (GaussAlterTableAlterColumnOptions.GaussAlterTableAlterColumnOptionValue)options.get(i);
         option.getAttribute().accept(this);
         SQLExpr value = option.getValue();
         if (value != null) {
            this.print0("=");
            value.accept(this);
         }

         if (i != options.size() - 1) {
            this.print0(",");
         }
      }

      this.print0(") ");
      return false;
   }

   public void endVisit(GaussAlterTableAlterColumnOptions.GaussAlterTableAlterColumnOptionValue x) {
   }

   public boolean visit(GaussAlterTableAlterColumnOptions.GaussAlterTableAlterColumnOptionValue x) {
      return true;
   }

   public void endVisit(GaussAlterTableAddConstraint x) {
   }

   public boolean visit(GaussAlterTableAddConstraint item) {
      this.print0(this.ucase ? "ADD " : "add ");
      if (item.getConstraint() != null) {
         item.getConstraint().accept(this);
      } else if (item.getUsingIndex() != null) {
         GaussAlterTableAddConstraint.GaussAlterTableAddConstraintUsingIndex index = item.getUsingIndex();
         if (index.getConstraint() != null) {
            this.print0(this.ucase ? "CONSTRAINT " : "constraint ");
            index.getConstraint().accept(this);
            this.print0(" ");
         }

         if (index.getType() == GaussAlterTableAddConstraint.GaussAlterTableAddConstraintUsingIndex.ConstraintType.unique) {
            this.print0(this.ucase ? "UNIQUE " : "unique ");
         } else {
            this.print0(this.ucase ? "PRIMARY KEY " : "primary key ");
         }

         this.print0(this.ucase ? "USING INDEX " : "using index ");
         index.getIndexName().accept(this);
         this.print0(" ");
         if (index.getStrategy() != null) {
            switch (index.getStrategy()) {
               case deferable:
                  this.print0(this.ucase ? "DEFERRABLE " : "deferrable");
                  break;
               case notDeferable:
                  this.print0(this.ucase ? "NOT DEFERRABLE " : "not deferrable");
                  break;
               case initiallyDefered:
                  this.print0(this.ucase ? "INITIALLY DEFERRED " : "initially deferred ");
                  break;
               case initiallyImmediate:
                  this.print0(this.ucase ? "INITIALLY IMMEDIATE " : "initially immediate ");
            }
         }
      }

      return false;
   }

   public void endVisit(GaussAlterTableAddConstraint.GaussAlterTableAddConstraintUsingIndex x) {
   }

   public boolean visit(GaussAlterTableAddConstraint.GaussAlterTableAddConstraintUsingIndex x) {
      return true;
   }

   public void endVisit(GaussAlterTableValidateConstraint x) {
   }

   public boolean visit(GaussAlterTableValidateConstraint item) {
      this.print0(this.ucase ? "VALIDATE CONSTRAINT " : "validate constraint ");
      item.getConstraint().accept(this);
      this.print0(" ");
      return false;
   }

   public void endVisit(GaussAlterTableDropConstraint x) {
   }

   public boolean visit(GaussAlterTableDropConstraint item) {
      this.print0(this.ucase ? "DROP CONSTRAINT " : "drop constraint ");
      if (item.isIfExists()) {
         this.print0(this.ucase ? "IF EXISTS " : "if exists ");
      }

      item.getConstraint().accept(this);
      this.print0(" ");
      GaussAlterTableDropConstraint.DorpType type = item.getType();
      if (type != null) {
         if (type == GaussAlterTableDropConstraint.DorpType.cascade) {
            this.print0(this.ucase ? "RESTRICT " : "restrict ");
         } else {
            this.print0(this.ucase ? "CASCADE " : "cascade ");
         }
      }

      return false;
   }

   public void endVisit(GaussAlterTableDisableEnabelTrigger x) {
   }

   public boolean visit(GaussAlterTableDisableEnabelTrigger item) {
      if (!item.isEnable()) {
         this.print0(this.ucase ? "DISABLE TRIGGER " : "disable trigger ");
      } else {
         this.print0(this.ucase ? "ENABLE TRIGGER " : "enable trigger ");
      }

      if (item.getTrigger() != null) {
         item.getTrigger().accept(this);
      } else if (item.getType() != null) {
         if (item.getType() == GaussAlterTableDisableEnabelTrigger.Type.all) {
            this.print0(this.ucase ? "ALL " : "all ");
         } else {
            this.print0(this.ucase ? "USER " : "user ");
         }
      }

      return false;
   }

   public void endVisit(GaussAlterTableCluster x) {
   }

   public boolean visit(GaussAlterTableCluster item) {
      this.print0(this.ucase ? "CLUSTER ON " : "cluster on ");
      item.getIndex().accept(this);
      this.print0(" ");
      return false;
   }

   public void endVisit(GaussAlterTableSetReset x) {
   }

   public boolean visit(GaussAlterTableSetReset item) {
      if (item.isSet()) {
         this.print0(this.ucase ? "SET " : "set ");
      } else {
         this.print0(this.ucase ? "RESET " : "reset ");
      }

      if (item.isCluster()) {
         this.print0(this.ucase ? "WITHOUT CLUSTER " : "without cluster ");
         return false;
      } else if (item.isOids()) {
         this.print0(this.ucase ? "WITHOUT OIDS" : "without oids ");
         return false;
      } else if (item.getTablespace() != null) {
         this.print0(this.ucase ? "TABLESPACE  " : "tablespace ");
         item.getTablespace().accept(this);
         this.print0(" ");
         return false;
      } else {
         List<GaussAlterTableSetReset.StorageParameter> parameters = item.getParameters();
         if (parameters != null && parameters.size() > 0) {
            this.print0("(");

            for(int i = 0; i < parameters.size(); ++i) {
               GaussAlterTableSetReset.StorageParameter parameter = (GaussAlterTableSetReset.StorageParameter)parameters.get(i);
               parameter.getParameter().accept(this);
               SQLExpr value = parameter.getValue();
               if (value != null) {
                  this.print0("=");
                  value.accept(this);
               }

               if (i != parameters.size() - 1) {
                  this.print0(",");
               }
            }

            this.print0(")");
         }

         return false;
      }
   }

   public void endVisit(GaussAlterTableSetReset.StorageParameter x) {
   }

   public boolean visit(GaussAlterTableSetReset.StorageParameter x) {
      return true;
   }

   public void endVisit(GaussAlterTableInheriteOrNotParentTable x) {
   }

   public boolean visit(GaussAlterTableInheriteOrNotParentTable item) {
      if (item.isInherite()) {
         this.print0(this.ucase ? "INHERIT " : "inherit ");
      } else {
         this.print0(this.ucase ? "NO INHERIT " : "no inherit ");
      }

      item.getParentTable().accept(this);
      this.print0(" ");
      return false;
   }

   public void endVisit(GaussAlterTableOf x) {
   }

   public boolean visit(GaussAlterTableOf item) {
      if (item.isOf()) {
         this.print0(this.ucase ? "OF " : "of ");
         item.getTypeName().accept(this);
      }

      if (item.isNotOf()) {
         this.print0(this.ucase ? "NOT OF " : "not of ");
      }

      if (item.isOwn()) {
         this.print0(this.ucase ? "OWNER TO  " : "owner to  ");
         item.getNewOwner().accept(this);
      }

      this.print0(" ");
      return false;
   }

   public void endVisit(GaussAlterTableSetTableSpace x) {
   }

   public boolean visit(GaussAlterTableSetTableSpace item) {
      this.print0(this.ucase ? "SET TABLESPACE " : "set tablespace ");
      item.getName().accept(this);
      return false;
   }

   public void endVisit(GaussCreateDatabaseStatement x) {
   }

   public boolean visit(GaussCreateDatabaseStatement stmt) {
      this.print0(this.ucase ? "CREATE DATABSE " : "create database ");
      stmt.getName().accept(this);
      this.print0(" ");
      if (stmt.getOwner() != null) {
         this.print0(this.ucase ? "OWNER=" : "owner=");
         stmt.getOwner().accept(this);
         this.print(" ");
      }

      if (stmt.getTemplate() != null) {
         this.print0(this.ucase ? "TEMPLATE=" : "template=");
         stmt.getTemplate().accept(this);
         this.print(" ");
      }

      if (stmt.getEncoding() != null) {
         this.print0(this.ucase ? "ENCODING=" : "encoding=");
         stmt.getEncoding().accept(this);
         this.print(" ");
      }

      if (stmt.getLcCollate() != null) {
         this.print0(this.ucase ? "LC_COLLATE=" : "lc_collate=");
         stmt.getLcCollate().accept(this);
         this.print(" ");
      }

      if (stmt.getCtype() != null) {
         this.print0(this.ucase ? "LC_CTYPE=" : "lc_ctype=");
         stmt.getCtype().accept(this);
         this.print(" ");
      }

      if (stmt.getTablespace() != null) {
         this.print0(this.ucase ? "TABLESPACE=" : "tablespace=");
         stmt.getTablespace().accept(this);
         this.print(" ");
      }

      if (stmt.getLimit() != null) {
         this.print0(this.ucase ? "CONNECTION LIMIT=" : "connection limit=");
         stmt.getLimit().accept(this);
         this.print(" ");
      }

      return false;
   }

   public void endVisit(GaussConstraint x) {
   }

   public boolean visit(GaussCreateTableStatement stmt) {
      this.print0(this.ucase ? "CREATE " : "create ");
      if (stmt.getTableType() != null) {
         switch (stmt.getTableType()) {
            case GLOBAL_TEMPORARY:
               this.print0(this.ucase ? "GLOBAL TEMPORARY " : "golbal temporary ");
               break;
            case LOCAL_TEMPORARY:
               this.print0(this.ucase ? "LOCAL TEMPORARY " : "local temporary ");
               break;
            case GLOBAL_TEMP:
               this.print0(this.ucase ? "GLOBAL TEMP " : "golbal temp ");
               break;
            case LOCAL_TEMP:
               this.print0(this.ucase ? "LOCAL TEMP " : "local temp ");
               break;
            case GLOBAL_UNLOGGED:
               this.print0(this.ucase ? "GLOBAL UNLOGGED " : "golbal unlogged ");
               break;
            case LOCAL_UNLOGGED:
               this.print0(this.ucase ? "LOCAL UNLOGGED " : "local unlogged ");
               break;
            case TEMPORARY:
               this.print0(this.ucase ? "TEMPORARY " : "temporary ");
               break;
            case TEMP:
               this.print0(this.ucase ? "TEMP " : "temp ");
               break;
            case UNLOGGED:
               this.print0(this.ucase ? "UNLOGGED " : "unlogged ");
         }
      }

      this.print0(this.ucase ? "TABLE " : "table ");
      if (stmt.isIfNotExists()) {
         this.print0(this.ucase ? "IF NOT EXISTS " : "if not exists ");
      }

      stmt.getTableSource().accept(this);
      this.print0(" ");
      if (stmt.getOfType() != null) {
         this.print0(this.ucase ? "OF " : "of ");
         stmt.getOfType().accept(this);
         this.print0(" ");
      }

      if (stmt.getTableElementList() != null && stmt.getTableElementList().size() > 0) {
         this.print0("(");

         for(int i = 0; i < stmt.getTableElementList().size(); ++i) {
            this.println();
            SQLTableElement element = (SQLTableElement)stmt.getTableElementList().get(i);
            element.accept(this);
            if (i != stmt.getTableElementList().size() - 1) {
               this.print0(",");
            }
         }

         this.println();
         this.print0(")");
      }

      List<SQLExpr> parentTables = stmt.getParentTables();
      if (parentTables != null && parentTables.size() > 0) {
         this.println();
         this.print0(this.ucase ? "INHERITS " : "inherits ");
         this.print0("(");

         for(int i = 0; i < parentTables.size(); ++i) {
            ((SQLExpr)parentTables.get(i)).accept(this);
            if (i != parentTables.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (stmt.getParameters() != null && stmt.getParameters().size() > 0) {
         this.println();
         this.print0(this.ucase ? "WITH " : "with ");
         this.print0("(");

         for(int i = 0; i < stmt.getParameters().size(); ++i) {
            GaussStorageParameter paramter = (GaussStorageParameter)stmt.getParameters().get(i);
            paramter.accept(this);
            this.println();
            if (i != stmt.getParameters().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (stmt.getTableOptions() != null && stmt.getTableOptions().size() > 0) {
         this.println();
         this.print0(this.ucase ? "WITH " : "with ");
         this.print0("(");

         for(int i = 0; i < stmt.getTableOptions().size(); ++i) {
            SQLAssignItem paramter = (SQLAssignItem)stmt.getTableOptions().get(i);
            paramter.accept(this);
            this.println();
            if (i != stmt.getTableOptions().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (stmt.getOnCommit() != null) {
         this.println();
         this.print0(this.ucase ? "ON COMMIT " : "on commit ");
         switch (stmt.getOnCommit()) {
            case preserveRows:
               this.print0(this.ucase ? "PRESERVE ROWS" : "preserve rows");
               break;
            case deleteRows:
               this.print0(this.ucase ? "DELETE ROWS" : "delete rows");
               break;
            case drop:
               this.print0(this.ucase ? "DROP" : "drop");
         }
      }

      if (stmt.getTablespace() != null) {
         this.println();
         this.print0(this.ucase ? "TABLESPACE " : "tablespace ");
         stmt.getTablespace().accept(this);
      }

      if (stmt.getSelect() != null) {
         this.printUcase(" AS ");
         stmt.getSelect().accept(this);
         if (stmt.getWithData() != null && stmt.getWithData()) {
            this.printUcase(" WITH DATA ");
         }

         if (stmt.getWithNoData() != null && stmt.getWithNoData()) {
            this.printUcase(" WITH NO DATA ");
         }
      }

      if (stmt.getDistributedBy() != null) {
         this.println();
         stmt.getDistributedBy().accept(this);
      }

      if (stmt.getPartitioning() != null) {
         this.println();
         stmt.getPartitioning().accept(this);
      }

      return false;
   }

   public void endVisit(GaussCreateTableStatement.GaussTableDistributedBy x) {
   }

   public boolean visit(GaussColumnDefinition d) {
      this.incrementIndent();
      this.printIndent();
      d.getName().accept(this);
      this.space();
      if (d.isWith()) {
         this.print0(this.ucase ? "WITH OPTIONS " : "with options ");
      } else {
         if (d.getType() != null) {
            d.getType().accept(this);
         } else if (d.getDataType() != null) {
            d.getDataType().accept(this);
         }

         this.space();
         if (d.getCollateExpr() != null) {
            this.print0(this.ucase ? "COLLATE " : "collate ");
            d.getCollateExpr().accept(this);
         }
      }

      List<SQLColumnConstraint> constraints = d.getConstraints();
      if (constraints != null && constraints.size() > 0) {
         for(int i = 0; i < constraints.size(); ++i) {
            ((SQLColumnConstraint)constraints.get(i)).accept(this);
         }
      }

      List<SQLExpr> encodings = d.getEncodings();
      if (encodings != null && encodings.size() > 0) {
         this.println();
         this.print0(this.ucase ? "ENCODING " : "encoding ");
         this.print0("(");

         for(int i = 0; i < encodings.size(); ++i) {
            SQLExpr sqlExpr = (SQLExpr)encodings.get(i);
            sqlExpr.accept(this);
            if (i != encodings.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (d.getTableConstraint() != null) {
         d.getTableConstraint().accept(this);
      }

      if (d.getLike() != null) {
         this.print0(this.ucase ? "LIKE " : "like ");
         d.getLike().accept(this);
         this.space();
         List<GaussColumnDefinition.ColumnLikeOption> likeOptions = d.getLikeOptions();
         if (likeOptions != null && likeOptions.size() > 0) {
            for(int i = 0; i < likeOptions.size(); ++i) {
               GaussColumnDefinition.ColumnLikeOption option = (GaussColumnDefinition.ColumnLikeOption)likeOptions.get(i);
               switch (option.getIncludeType()) {
                  case including:
                     this.print0(this.ucase ? "INCLUDING " : "including ");
                     break;
                  case excluding:
                     this.print0(this.ucase ? "EXCLUDING " : "excluding ");
               }

               switch (option.getOption()) {
                  case defaults:
                     this.print0(this.ucase ? "DEFAULTS " : "defaults ");
                     break;
                  case constraints:
                     this.print0(this.ucase ? "CONSTRAINTS " : "constraints ");
                     break;
                  case indexes:
                     this.print0(this.ucase ? "INDEXES " : "indexes ");
                     break;
                  case storage:
                     this.print0(this.ucase ? "STORAGE " : "storage ");
                     break;
                  case comments:
                     this.print0(this.ucase ? "COMMENTS " : "comments ");
                     break;
                  case all:
                     this.print0(this.ucase ? "ALL " : "all ");
               }
            }
         }
      }

      List<GaussConstraint.GaussReference> columnReferenceStorageDirectives = d.getColumnReferenceStorageDirectives();
      if (columnReferenceStorageDirectives != null && columnReferenceStorageDirectives.size() > 0) {
         for(int i = 0; i < columnReferenceStorageDirectives.size(); ++i) {
            GaussConstraint.GaussReference GaussReference = (GaussConstraint.GaussReference)columnReferenceStorageDirectives.get(i);
            GaussReference.accept(this);
            if (i != columnReferenceStorageDirectives.size() - 1) {
               this.print0(",");
            }
         }
      }

      this.decrementIndent();
      return false;
   }

   public void endVisit(GaussCreateTableStatement x) {
   }

   public boolean visit(GaussConstraint constraint) {
      if (constraint.getName() != null) {
         this.println();
         this.print0(this.ucase ? "CONSTRAINT " : "constraint ");
         constraint.getName().accept(this);
      }

      if (constraint.getiNull() != null && constraint.getiNull()) {
         this.println();
         this.print0(this.ucase ? "NULL " : "null ");
      }

      if (constraint.getNotNull() != null && constraint.getNotNull()) {
         this.println();
         this.print0(this.ucase ? "NOT NULL " : "not null ");
      }

      if (constraint.getCheck() != null) {
         this.println();
         this.print0(this.ucase ? "CHECK " : "check ");
         this.print0("(");
         constraint.getCheck().getExpr().accept(this);
         this.print0(")");
         this.space();
         if (constraint.getCheck().isNoInherit()) {
            this.print0(this.ucase ? "NO INHERIT " : "no inherit ");
         }
      }

      if (constraint.getDefValue() != null) {
         this.println();
         this.print0(this.ucase ? "DEFAULT " : "default ");
         constraint.getDefValue().accept(this);
      }

      if (constraint.getUnique() != null) {
         this.println();
         this.print0(this.ucase ? "UNIQUE " : "unique ");
         List<SQLName> columns = constraint.getUnique().getColumns();
         if (columns != null && columns.size() > 0) {
            this.print0("(");

            for(int i = 0; i < columns.size(); ++i) {
               ((SQLName)columns.get(i)).accept(this);
               if (i != columns.size() - 1) {
                  this.print0(",");
               }
            }

            this.print0(") ");
         }

         GaussConstraint.GaussIndexParamaters indexParamaters = constraint.getUnique().getIndexParamaters();
         if (indexParamaters != null) {
            indexParamaters.accept(this);
         }
      }

      if (constraint.getPrimaryKey() != null) {
         this.println();
         this.print0(this.ucase ? "PRIMARY KEY " : "primary key ");
         GaussConstraint.GaussIndexParamaters indexParamaters = constraint.getPrimaryKey().getIndexParamaters();
         if (indexParamaters != null) {
            indexParamaters.accept(this);
         }
      }

      if (constraint.getReference() != null) {
         this.println();
         constraint.getReference().accept(this);
      }

      if (constraint.getType() != null) {
         switch (constraint.getType()) {
            case deferrable:
               this.print0(this.ucase ? "DEFERRABLE " : "deferrable ");
               break;
            case notDeferrable:
               this.print0(this.ucase ? "NOT DEFERRABLE " : "not deferrable ");
               break;
            case initiallyDeferred:
               this.print0(this.ucase ? "INITIALLY DEFERRED " : "initially deferred ");
               break;
            case initiallyImmediate:
               this.print0(this.ucase ? "INITIALLY IMMEDIATE " : "initially immediate ");
         }
      }

      return false;
   }

   public void endVisit(GaussConstraint.GaussConstraintCheck x) {
   }

   public boolean visit(GaussConstraint.GaussConstraintCheck x) {
      return true;
   }

   public void endVisit(GaussConstraint.GaussUnique x) {
   }

   public boolean visit(GaussConstraint.GaussUnique x) {
      return true;
   }

   public void endVisit(GaussConstraint.GaussPrimaryKey x) {
   }

   public boolean visit(GaussConstraint.GaussPrimaryKey x) {
      return true;
   }

   public void endVisit(GaussConstraint.GaussForeignKey x) {
   }

   public boolean visit(GaussConstraint.GaussForeignKey x) {
      return true;
   }

   public void endVisit(GaussOptionValue x) {
   }

   public boolean visit(GaussConstraint.GaussIndexParamaters r) {
      List<GaussStorageParameter> parameters = r.getParameters();
      if (parameters != null && parameters.size() > 0) {
         this.print0(this.ucase ? "WITH (" : "with (");

         for(int i = 0; i < parameters.size(); ++i) {
            ((GaussStorageParameter)parameters.get(i)).accept(this);
            if (i != parameters.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(") ");
      }

      if (r.getTablespace() != null) {
         this.print0(this.ucase ? "USING INDEX TABLESPACE " : "using index tablespace ");
         r.getTablespace().accept(this);
         this.space();
      }

      return false;
   }

   public void endVisit(GaussConstraint.GaussReference x) {
   }

   public boolean visit(GaussConstraint.GaussReference r) {
      this.print0(this.ucase ? "REFERENCES " : "references ");
      r.getRefTable().accept(this);
      this.space();
      List<SQLExpr> columns = r.getColumns();
      if (columns != null && columns.size() > 0) {
         this.print0("(");

         for(int i = 0; i < columns.size(); ++i) {
            ((SQLExpr)columns.get(i)).accept(this);
            if (i != columns.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(") ");
      }

      GaussConstraint.GaussReference.MatchType matchType = r.getMatchType();
      if (matchType != null) {
         switch (matchType) {
            case full:
               this.print0(this.ucase ? "MATCH FULL " : "match full ");
               break;
            case partial:
               this.print0(this.ucase ? "MATCH PARTIAL " : "match partial ");
               break;
            case simple:
               this.print0(this.ucase ? "MATCH SIMPLE " : "match simple ");
         }
      }

      if (r.getDeleteAction() != null) {
         this.print0(this.ucase ? "ON DELETE " : "on delete ");
         switch (r.getDeleteAction()) {
            case onDelete:
               this.print0(this.ucase ? "ON DELETE " : "on delete ");
               break;
            case onUpdate:
               this.print0(this.ucase ? "ON UPDATE " : "on update ");
               break;
            case noAction:
               this.print0(this.ucase ? "NO ACTION " : "no action ");
               break;
            case restrict:
               this.print0(this.ucase ? "RESTRICT " : "restrict ");
               break;
            case cascade:
               this.print0(this.ucase ? "CASCADE " : "cascade ");
               break;
            case setNull:
               this.print0(this.ucase ? "SET NULL " : "set null ");
               break;
            case setDefault:
               this.print0(this.ucase ? "SET DEFAULT " : "set default ");
         }
      }

      if (r.getUpdateAction() != null) {
         this.print0(this.ucase ? "ON UPDATE " : "on update ");
         switch (r.getUpdateAction()) {
            case onDelete:
               this.print0(this.ucase ? "ON DELETE " : "on delete ");
               break;
            case onUpdate:
               this.print0(this.ucase ? "ON UPDATE " : "on update ");
               break;
            case noAction:
               this.print0(this.ucase ? "NO ACTION " : "no action ");
               break;
            case restrict:
               this.print0(this.ucase ? "RESTRICT " : "restrict ");
               break;
            case cascade:
               this.print0(this.ucase ? "CASCADE " : "cascade ");
               break;
            case setNull:
               this.print0(this.ucase ? "SET NULL " : "set null ");
               break;
            case setDefault:
               this.print0(this.ucase ? "SET DEFAULT " : "set default ");
         }
      }

      return false;
   }

   public void endVisit(GaussColumnDefinition x) {
   }

   public boolean visit(GaussCreateTableStatement.GaussTableDistributedBy by) {
      this.print0(this.ucase ? "DISTRIBUTED " : "distributed ");
      List<GaussOptionValue> columns = by.getColumns();
      if (columns != null && columns.size() > 0) {
         this.print0(this.ucase ? "BY (" : "by (");

         for(int i = 0; i < columns.size(); ++i) {
            ((GaussOptionValue)columns.get(i)).accept(this);
            if (i != columns.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(") ");
      }

      GaussCreateTableStatement.GaussTableDistributedBy.Option option = by.getOption();
      if (option != null) {
         switch (option) {
            case randomly:
               this.print0(this.ucase ? "RANDOMLY " : "randomly ");
               break;
            case replicated:
               this.print0(this.ucase ? "REPLICATED " : "replicated ");
         }
      }

      return false;
   }

   public void endVisit(GaussSQLObjectCollection x) {
   }

   public boolean visit(GaussOptionValue value) {
      value.getOption().accept(this);
      if (value.isEq()) {
         if (value.getValue() != null) {
            this.print0("=");
            value.getValue().accept(this);
         }
      } else {
         this.print0(" ");
         if (value.getValue() != null) {
            value.getValue().accept(this);
            this.print0(" ");
         }
      }

      return false;
   }

   public void endVisit(GaussStorageParameter x) {
   }

   public boolean visit(GaussStorageParameter x) {
      return true;
   }

   public void endVisit(GaussConstraint.GaussIndexParamaters x) {
   }

   public boolean visit(GaussSQLObjectCollection datas) {
      if (datas != null && datas.size() > 0) {
         for(int i = 0; i < datas.size(); ++i) {
            datas.get(i).accept(this);
            if (i != datas.size() - 1) {
               this.print0(",");
            }
         }
      }

      return false;
   }

   public void endVisit(GaussSchemaTables x) {
   }

   public boolean visit(GaussSchemaTables datas) {
      if (datas != null && datas.size() > 0) {
         this.print0(this.ucase ? "ALL TABLES IN SCHEMA " : "all tables in schema ");

         for(int i = 0; i < datas.size(); ++i) {
            datas.get(i).accept(this);
            if (i != datas.size() - 1) {
               this.print0(",");
            }
         }
      }

      return false;
   }

   public void endVisit(GaussGrantStatement x) {
   }

   private void space() {
      this.print0(" ");
   }

   public boolean visit(GaussAlterViewStatement x) {
      if (x.isMaterialized()) {
         this.print0(this.ucase ? " ALTER MATERIALIZED VIEW " : " alter materialized view ");
      } else {
         this.print0(this.ucase ? " ALTER VIEW " : " alter view ");
      }

      if (x.isIfExists()) {
         this.printUcase(" IF EXISTS ");
      }

      x.getViewName().accept(this);
      if (x.isRenameTo()) {
         this.print0(this.ucase ? " RENAME TO " : " rename to ");
         x.getNewViewName().accept(this);
      } else if (x.isAlter()) {
         this.print0(this.ucase ? " ALTER COLUMN  " : " alter column ");
         x.getColumnName().accept(this);
         if (x.isSetDefault()) {
            this.print0(this.ucase ? " SET DEFAULT  " : " set default ");
            x.getDefaultValue().accept(this);
            this.print0(";");
         } else if (x.isDropDefault()) {
            this.print0(this.ucase ? " DROP DEFAULT  " : " drop default ");
         }
      } else if (x.isOwnerTo()) {
         this.print0(this.ucase ? " OWNER TO " : " owner to ");
         x.getNewOwner().accept(this);
      } else if (x.isSetSchema()) {
         this.print0(this.ucase ? " SET SCHEMA " : " set schema ");
         x.getNewSchema().accept(this);
      } else if (x.isSet()) {
         this.print0(this.ucase ? " SET " : " set ");
         List<SQLUpdateSetItem> parameterList = x.getParameterList();
         if (parameterList != null && parameterList.size() > 0) {
            this.print0("(");
            this.printAndAccept(parameterList, ", ");
            this.print0(")");
         } else {
            List<SQLExpr> itemList = x.getItemList();
            if (itemList != null && itemList.size() > 0) {
               this.print0("(");
               this.printAndAccept(itemList, ", ");
               this.print0(")");
            }
         }
      } else if (x.isReset()) {
         this.print0(this.ucase ? " RESET " : " reset ");
         List<SQLExpr> itemList = x.getItemList();
         if (itemList != null && itemList.size() > 0) {
            this.print0("(");
            this.printAndAccept(itemList, ", ");
            this.print0(")");
         }
      }

      if (x.isRename() && !x.isRenameTo()) {
         this.printUcase(" RENAME ");
         if (x.isColumn()) {
            this.printUcase("COLUMN ");
         }

         x.getColumnName().accept(this);
         this.printUcase(" TO ");
         x.getNewColumnName().accept(this);
      }

      return false;
   }

   public boolean visit(GaussCreateSeqenceStatement x) {
      this.print0(this.ucase ? " CREATE " : " create ");
      if (x.isLarge()) {
         this.print0(this.ucase ? " LARGE " : " LARGE ");
      }

      this.print0(this.ucase ? " SEQUENCE " : " sequence ");
      x.getSqeunceName().accept(this);
      if (x.isIncrement()) {
         this.print0(this.ucase ? " INCREMENT " : " increment ");
         x.getIncrementValue().accept(this);
      }

      if (x.isIncrementBy()) {
         this.print0(this.ucase ? " INCREMENT BY " : " increment by ");
         x.getIncrementValue().accept(this);
      }

      if (x.isMin()) {
         this.print0(this.ucase ? " MINVALUE " : " minvalue ");
         x.getMinValue().accept(this);
      }

      if (x.isMax()) {
         this.print0(this.ucase ? " MAXVALUE " : " maxvalue ");
         x.getMaxValue().accept(this);
      }

      if (x.isNoMax()) {
         this.print0(this.ucase ? " NO MAXVALUE " : " no maxvalue ");
      }

      if (x.isNoMin()) {
         this.print0(this.ucase ? " NO MINVALUE " : " no minvalue ");
      }

      if (x.isStart()) {
         this.print0(this.ucase ? " START " : " start ");
         x.getStartValue().accept(this);
      }

      if (x.isStartWith()) {
         this.print0(this.ucase ? " START WITH " : " start with ");
         x.getStartValue().accept(this);
      }

      if (x.isCache()) {
         this.print0(this.ucase ? " CACHE " : " cache ");
         x.getCacheName().accept(this);
      }

      if (x.isCycle()) {
         this.print0(this.ucase ? " CYCLE " : " cycle ");
      }

      if (x.isNoCycle()) {
         this.print0(this.ucase ? " NO CYCLE " : " no cycle ");
      }

      if (x.isOwnedBy()) {
         this.print0(this.ucase ? " OWNED BY " : " owned by ");
         x.getOwnedByName().accept(this);
      }

      return false;
   }

   public boolean visit(GaussCreateTableSpaceStatement x) {
      this.print0(this.ucase ? " CREATE TABLESPACE " : " create tablespace ");
      x.getTableSpaceName().accept(this);
      if (x.isOwner()) {
         this.print0(this.ucase ? " OWNER " : " owner ");
         x.getOwnerName().accept(this);
      }

      if (x.isRelative()) {
         this.print0(this.ucase ? " RELATIVE " : " RELATIVE ");
      }

      this.print0(this.ucase ? " LOCATION " : " location ");
      x.getLocationDir().accept(this);
      if (x.isWith()) {
         this.print0(this.ucase ? " WITH " : " with ");
         List<SQLUpdateSetItem> parameterList = x.getParameterList();
         if (parameterList != null && parameterList.size() > 0) {
            this.print0("(");
            this.printAndAccept(parameterList, ", ");
            this.print0(")");
         }
      }

      if (x.getMaxsize() != null) {
         this.print0(this.ucase ? " MAXSIZE " : " maxsize ");
         x.getMaxsize().accept(this);
         this.print0(" ");
      }

      return false;
   }

   public boolean visit(GaussAlterTableSpaceStatement x) {
      this.print0(this.ucase ? "ALTER TABLESPACE " : "alter tablespace ");
      if (x.getTableSpaceName() != null) {
         x.getTableSpaceName().accept(this);
         this.print0(" ");
      }

      if (x.isRenameTo()) {
         this.printUcase("RENAME TO ");
         x.getNewTableSpaceName().accept(this);
      }

      if (x.isOwnerTo()) {
         this.printUcase("OWNER TO ");
         x.getOwnerName().accept(this);
      }

      if (x.isResizeMaxsize()) {
         this.printUcase("RESIZE MAXSIZE ");
         if (x.isUnlimited()) {
            this.printUcase("UNLIMITED ");
         }

         if (x.getSpaceSize() != null) {
            x.getSpaceSize().accept(this);
         }
      }

      return false;
   }

   public void endVisit(GaussAlterTableModify x) {
   }

   public boolean visit(GaussCreateViewStatement x) {
      this.print0(this.ucase ? " CREATE " : " create ");
      if (x.isOrReplace()) {
         this.print0(this.ucase ? " OR REPLACE " : " or replace ");
      }

      if (x.isTemp()) {
         this.print0(this.ucase ? " TEMP " : " temp ");
      }

      if (x.isTemporary()) {
         this.print0(this.ucase ? " TEMPORARY " : " temporary ");
      }

      if (x.isRecursiveView()) {
         this.print0(this.ucase ? " RECURSIVE " : " recursive ");
      }

      this.print0(this.ucase ? " VIEW " : " view ");
      x.getViewName().accept(this);
      List<SQLExpr> columnList = x.getColumnList();
      if (columnList != null && columnList.size() > 0) {
         this.print0("(");
         this.printAndAccept(columnList, ", ");
         this.print0(")");
      }

      if (x.isWithOption()) {
         this.print0(this.ucase ? " WITH" : " with");
         List<SQLUpdateSetItem> withList = x.getWithList();
         this.print0("(");
         this.printAndAccept(withList, ", ");
         this.print0(")");
      }

      this.print0(this.ucase ? " AS " : " as ");
      if (x.isAsWithRecursive()) {
         x.getWithSubqueryClause().accept(this);
      } else {
         x.getSubQuery().accept(this);
         if (x.isWithCascaded()) {
            this.print0(this.ucase ? " WITH CASCADED CHECK OPTION " : " with cascaded check option ");
         }

         if (x.isWithLocal()) {
            this.print0(this.ucase ? " WITH LOCAL CHECK OPTION " : " with local check option ");
         }
      }

      return false;
   }

   public boolean visit(GaussCreateMaterializedViewStatement x) {
      this.printUcase(" CREATE MATERIALIZED VIEW ");
      x.getViewName().accept(this);
      List<SQLExpr> columnList = x.getColumnList();
      if (columnList != null && columnList.size() > 0) {
         this.print0("(");
         this.printAndAccept(columnList, ", ");
         this.print0(")");
      }

      if (x.isWithOption()) {
         this.print0(this.ucase ? " WITH" : " with");
         List<SQLUpdateSetItem> withList = x.getWithList();
         this.print0("(");
         this.printAndAccept(withList, ", ");
         this.print0(")");
      }

      this.print0(this.ucase ? " AS " : " as ");
      x.getSubQuery().accept(this);
      this.print0(" ");
      if (x.isWithData()) {
         this.printUcase("WITH ");
         if (x.isNo()) {
            this.printUcase("NO ");
         }

         this.printUcase("DATA ");
      }

      return false;
   }

   public void endVisit(GaussDropSequenceStatement x) {
   }

   public void endVisit(GaussCreateSynonymStatement x) {
   }

   public boolean visit(GaussCreateSynonymStatement x) {
      this.printUcase("CREATE ");
      if (x.isOrReplace()) {
         this.printUcase("OR REPLACE ");
      }

      this.printUcase("SYNONYM ");
      if (x.getName() != null) {
         x.getName().accept(this);
         this.print0(" ");
      }

      this.printUcase("FOR ");
      if (x.getObject() != null) {
         x.getObject().accept(this);
         this.print0(" ");
      }

      return false;
   }

   public void endVisit(GaussAlterSynonymStatement x) {
   }

   public boolean visit(GaussAlterSynonymStatement x) {
      this.printUcase("ALTER SYNONYM ");
      if (x.getName() != null) {
         x.getName().accept(this);
         this.print0(" ");
      }

      this.printUcase("OWNER TO ");
      if (x.getNewName() != null) {
         x.getNewName().accept(this);
         this.print0(" ");
      }

      return false;
   }

   public void endVisit(GaussCreateRoleStatement x) {
   }

   public boolean visit(GaussDropSequenceStatement x) {
      this.print0(this.ucase ? "DROP " : " drop ");
      if (x.isLarge()) {
         this.print0(this.ucase ? "LARGE " : "large ");
      }

      this.print0(this.ucase ? "SEQUENCE " : "sequence ");
      if (x.isIfExists()) {
         this.print0(this.ucase ? " IF EXISTS " : " if exists ");
      }

      ArrayList<SQLIdentifierExpr> seqList = x.getSeqList();
      if (seqList != null && seqList.size() > 0) {
         this.printAndAccept(seqList, ", ");
      }

      if (x.isCascade()) {
         this.print0(this.ucase ? " CASCADE " : " cascade ");
      } else if (x.isRestrict()) {
         this.print0(this.ucase ? " RESTRICT " : " restrict ");
      }

      return false;
   }

   public boolean visit(SQLDropTableStatement x) {
      this.print0(this.ucase ? "DROP TABLE " : " drop table ");
      if (x.isIfExists()) {
         this.print0(this.ucase ? " IF EXISTS " : " if exists ");
      }

      this.printAndAccept(x.getTableSources(), ",");
      if (x.isCascade()) {
         this.print0(this.ucase ? " CASCADE " : " cascade ");
      } else if (x.isRestrict()) {
         this.print0(this.ucase ? " RESTRICT " : " restrict ");
      }

      return false;
   }

   public boolean visit(SQLCommitStatement x) {
      this.print0(this.ucase ? "COMMIT" : "commit");
      if (x.isWork()) {
         this.print0(this.ucase ? " WORK" : " work");
      } else if (x.isTransaction()) {
         this.print0(this.ucase ? " TRANSACTION" : " transaction");
      }

      return false;
   }

   public boolean visit(SQLRollbackStatement x) {
      this.print0(this.ucase ? "ROLLBACK" : "rollback");
      if (x.isWork()) {
         this.print0(this.ucase ? " WORK" : " work");
      } else if (x.isTransaction()) {
         this.print0(this.ucase ? " TRANSACTION" : " transaction");
      }

      if (x.getTo() != null) {
         this.print0(this.ucase ? " TO " : " to ");
         if (x.isHasSavepoint()) {
            this.print0(this.ucase ? " SAVEPOINT " : " savepoint ");
         }

         x.getTo().accept(this);
      }

      return false;
   }

   public boolean visit(GaussSQLPartitionBy x) {
      this.print0(this.ucase ? "PARTITION BY " : " partition by ");
      SQLName partitionType = x.getPartitionType();
      partitionType.accept(this);
      this.print0(" (");
      x.getColumn().accept(this);
      this.print0(")\n");
      ArrayList<GaussSQLPartitionBy> subPartitionByList = x.getSubPartitionByList();
      if (subPartitionByList != null && subPartitionByList.size() > 0) {
         boolean ifUseTemplate = ((GaussSQLPartitionBy)subPartitionByList.get(0)).isIfUseTemplate();
         if (!ifUseTemplate) {
            for(GaussSQLPartitionBy subPartitionBy : subPartitionByList) {
               this.print0(this.ucase ? " SUBPARTITION BY " : " subpartition by ");
               this.print0("(");
               subPartitionBy.getPartitionType().accept(this);
               this.print0(")");
               this.print0("\n ");
            }

            this.print0(this.visitPartitionRecursive(x, 0));
            return false;
         }

         for(GaussSQLPartitionBy subPartitionBy : subPartitionByList) {
            this.print0(this.ucase ? " SUBPARTITION BY " : " subpartition by ");
            subPartitionBy.getPartitionType().accept(this);
            this.print0(" (");
            subPartitionBy.getColumn().accept(this);
            this.print0(")\n");
            this.print0(this.ucase ? "  SUBPARTITION TEMPLATE" : "  subpartition template");
            this.print0(" (\n ");
            ArrayList<GaussSQLPartition> subPartitionList = subPartitionBy.getPartitionList();
            if (subPartitionList != null && subPartitionList.size() > 0) {
               this.printAndAccept(subPartitionList, ",\n ");
            }

            this.print0(")\n");
         }
      }

      this.print0("(");
      List<GaussSQLPartition> specList = x.getPartitionList();
      if (specList != null && specList.size() > 0) {
         this.printAndAccept(specList, ",\n");
      }

      this.print0("\n) ");
      return false;
   }

   private String visitPartitionRecursive(GaussSQLPartitionBy partitionBy, int level) {
      ArrayList<GaussSQLPartitionBy> subPartitionByList = partitionBy.getSubPartitionByList();
      ArrayList<GaussSQLPartition> crtPartitions;
      if (level == 0) {
         crtPartitions = partitionBy.getPartitionList();
      } else {
         crtPartitions = ((GaussSQLPartitionBy)subPartitionByList.get(level - 1)).getPartitionList();
      }

      if (level == subPartitionByList.size()) {
         return "(" + StringJoin.join(crtPartitions, ",") + ")";
      } else {
         String result = "(";

         for(GaussSQLPartition crtPartition : crtPartitions) {
            if (!"(".equals(result)) {
               result = result + ",\n";
            }

            result = result + crtPartition + "\n" + this.visitPartitionRecursive(partitionBy, level + 1);
         }

         result = result + ")";
         return result;
      }
   }

   public boolean visit(GaussSQLPartition x) {
      SQLName name = x.getName();
      if (name != null) {
         boolean subPartition = x.isSubPartition();
         if (x.isIfDefault()) {
            this.print0(this.ucase ? " DEFAULT PARTITION " : " default partition ");
            x.getName().accept(this);
            return false;
         }

         if (subPartition) {
            this.print0(this.ucase ? " SUBPARTITION " : " subpartition ");
         } else {
            this.print0(this.ucase ? " PARTITION " : " partition ");
         }

         x.getName().accept(this);
      }

      ArrayList<SQLExpr> valueList = x.getValueList();
      if (valueList != null && valueList.size() > 0) {
         this.print0(this.ucase ? " VALUES " : " values ");
         this.print0(" (");
         this.printAndAccept(valueList, ", ");
         this.print0(") ");
      } else {
         if (x.isStart()) {
            this.print0(this.ucase ? " START" : " star ");
            this.print0("(");
            SQLExpr startDataType = x.getStartDataType();
            if (startDataType != null) {
               startDataType.accept(this);
               this.print0(" ");
            }

            x.getStartValue().accept(this);
            this.print0(")");
            if (x.isStartInclusive()) {
               this.print0(this.ucase ? " INCLUSIVE " : " inclusive ");
            }

            if (x.isStartExclusive()) {
               this.print0(this.ucase ? " EXCLUSIVE " : " exclusive ");
            }
         }

         if (x.isEnd()) {
            this.print0(this.ucase ? " END" : " end");
            this.print0("(");
            SQLExpr endDataType = x.getEndDataType();
            if (endDataType != null) {
               endDataType.accept(this);
               this.print0(" ");
            }

            x.getEndValue().accept(this);
            this.print0(")");
            if (x.isEndInclusive()) {
               this.print0(this.ucase ? " INCLUSIVE " : " inclusive ");
            }

            if (x.isEndExclusive()) {
               this.print0(this.ucase ? " EXCLUSIVE " : " exclusive ");
            }
         }

         if (x.isEvery()) {
            this.print0(this.ucase ? " EVERY " : " every ");
            this.print0("(");
            SQLExpr everyDataType = x.getEveryDataType();
            if (everyDataType != null) {
               everyDataType.accept(this);
               this.print0(" ");
            }

            x.getEveryValue().accept(this);
            this.print0(")");
         }
      }

      if (x.isWith()) {
         this.print0(this.ucase ? " WITH " : " with ");
         List<SQLUpdateSetItem> withList = x.getWithList();
         if (withList != null && withList.size() > 0) {
            this.printAndAccept(withList, ",");
         }
      }

      SQLName tableSpace = x.getTableSpace();
      if (tableSpace != null) {
         this.print0(this.ucase ? " TABLESPACE " : " tablespace ");
         tableSpace.accept(this);
      }

      return false;
   }

   public boolean visit(GaussSQLIndexSpec x) {
      x.getName().accept(this);
      SQLExpr collateParam = x.getCollateParam();
      if (collateParam != null) {
         this.print0(this.ucase ? " COLLATE " : " collate ");
         collateParam.accept(this);
      }

      SQLName opclass = x.getOpclass();
      if (opclass != null) {
         this.print0(" ");
         opclass.accept(this);
      }

      if (x.isAsc()) {
         this.print0(this.ucase ? " ASC " : " asc ");
      } else if (x.isDesc()) {
         this.print0(this.ucase ? " DESC " : " desc ");
      }

      if (x.isNullsFirst()) {
         this.print0(this.ucase ? " NULLS FIRST " : " nulls first ");
      } else if (x.isNullsLast()) {
         this.print0(this.ucase ? " NULLS LAST " : " nulls last ");
      }

      return false;
   }

   public boolean visit(GaussCreateIndexStatement x) {
      this.print0(this.ucase ? "CREATE " : "create ");
      if (x.getType() != null) {
         this.print0(x.getType());
         this.print(' ');
      }

      this.print0(this.ucase ? "INDEX" : "index");
      if (x.isConcurrently()) {
         this.printUcase(" CONCURRENTLY ");
      }

      SQLName name = x.getName();
      if (name != null) {
         this.print(' ');
         name.accept(this);
      }

      this.print0(this.ucase ? " ON " : " on ");
      x.getTable().accept(this);
      if (x.getUsing() != null) {
         this.print0(this.ucase ? " USING " : " using ");
         this.print0(x.getUsing());
      }

      this.print0(" (");
      this.printAndAccept(x.getSpecList(), ", ");
      this.print(')');
      List<SQLUpdateSetItem> withList = x.getWithList();
      if (withList != null && withList.size() > 0) {
         this.print0(this.ucase ? " WITH " : " with ");
         this.print0(" (");
         this.printAndAccept(withList, ",");
         this.print(')');
      }

      SQLName tablespace = x.getTablespace();
      if (tablespace != null) {
         this.print0(this.ucase ? " TABLESPACE " : " tablespace ");
         tablespace.accept(this);
      }

      SQLExpr where = x.getWhere();
      if (where != null) {
         this.print0(this.ucase ? " WHERE " : " where ");
         where.accept(this);
      }

      return false;
   }

   public void endVisit(GaussAlterSessionStatement x) {
   }

   public boolean visit(GaussAlterTableModify x) {
      this.print0(this.ucase ? "MODIFY (" : "modify (");
      ++this.indentCount;
      int i = 0;

      for(int size = x.getColumns().size(); i < size; ++i) {
         this.println();
         SQLColumnDefinition column = (SQLColumnDefinition)x.getColumns().get(i);
         column.accept(this);
         if (i != size - 1) {
            this.print0(", ");
         }
      }

      --this.indentCount;
      this.println();
      this.print(')');
      return false;
   }

   public void endVisit(GaussCreateUserStatement x) {
   }

   public boolean visit(GaussCreateTableAsStatement stmt) {
      this.print0(this.ucase ? "CREATE " : "create ");
      if (stmt.getTableType() != null) {
         switch (stmt.getTableType()) {
            case GLOBAL_TEMPORARY:
               this.print0(this.ucase ? "GLOBAL TEMPORARY " : "golbal temporary ");
               break;
            case LOCAL_TEMPORARY:
               this.print0(this.ucase ? "LOCAL TEMPORARY " : "local temporary ");
               break;
            case GLOBAL_TEMP:
               this.print0(this.ucase ? "GLOBAL TEMP " : "golbal temp ");
               break;
            case LOCAL_TEMP:
               this.print0(this.ucase ? "LOCAL TEMP " : "local temp ");
               break;
            case GLOBAL_UNLOGGED:
               this.print0(this.ucase ? "GLOBAL UNLOGGED " : "golbal unlogged ");
               break;
            case LOCAL_UNLOGGED:
               this.print0(this.ucase ? "LOCAL UNLOGGED " : "local unlogged ");
               break;
            case TEMPORARY:
               this.print0(this.ucase ? "TEMPORARY " : "temporary ");
               break;
            case TEMP:
               this.print0(this.ucase ? "TEMP " : "temp ");
               break;
            case UNLOGGED:
               this.print0(this.ucase ? "UNLOGGED " : "unlogged ");
         }
      }

      this.print0(this.ucase ? "TABLE " : "table ");
      if (stmt.isIfNotExists()) {
         this.print0(this.ucase ? "IF NOT EXISTS " : "if not exists ");
      }

      stmt.getTableSource().accept(this);
      this.print0(" ");
      if (stmt.getOfType() != null) {
         this.print0(this.ucase ? "OF " : "of ");
         stmt.getOfType().accept(this);
         this.print0(" ");
      }

      if (stmt.getTableElementList() != null && stmt.getTableElementList().size() > 0) {
         this.print0("(");

         for(int i = 0; i < stmt.getTableElementList().size(); ++i) {
            this.println();
            SQLTableElement element = (SQLTableElement)stmt.getTableElementList().get(i);
            element.accept(this);
            if (i != stmt.getTableElementList().size() - 1) {
               this.print0(",");
            }
         }

         this.println();
         this.print0(")");
      }

      List<SQLExpr> parentTables = stmt.getParentTables();
      if (parentTables != null && parentTables.size() > 0) {
         this.println();
         this.print0(this.ucase ? "INHERITS " : "inherits ");
         this.print0("(");

         for(int i = 0; i < parentTables.size(); ++i) {
            ((SQLExpr)parentTables.get(i)).accept(this);
            if (i != parentTables.size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (stmt.getParameters() != null && stmt.getParameters().size() > 0) {
         this.println();
         this.print0(this.ucase ? "WITH " : "with ");
         this.print0("(");

         for(int i = 0; i < stmt.getParameters().size(); ++i) {
            GaussStorageParameter paramter = (GaussStorageParameter)stmt.getParameters().get(i);
            paramter.accept(this);
            this.println();
            if (i != stmt.getParameters().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (stmt.getTableOptions() != null && stmt.getTableOptions().size() > 0) {
         this.println();
         this.print0(this.ucase ? "WITH " : "with ");
         this.print0("(");

         for(int i = 0; i < stmt.getTableOptions().size(); ++i) {
            SQLAssignItem paramter = (SQLAssignItem)stmt.getTableOptions().get(i);
            paramter.accept(this);
            this.println();
            if (i != stmt.getTableOptions().size() - 1) {
               this.print0(",");
            }
         }

         this.print0(")");
      }

      if (stmt.getOnCommit() != null) {
         this.println();
         this.print0(this.ucase ? "ON COMMIT " : "on commit ");
         switch (stmt.getOnCommit()) {
            case preserveRows:
               this.print0(this.ucase ? "PRESERVE ROWS" : "preserve rows");
               break;
            case deleteRows:
               this.print0(this.ucase ? "DELETE ROWS" : "delete rows");
               break;
            case drop:
               this.print0(this.ucase ? "DROP" : "drop");
         }
      }

      if (stmt.getTablespace() != null) {
         this.println();
         this.print0(this.ucase ? "TABLESPACE " : "tablespace ");
         stmt.getTablespace().accept(this);
      }

      if (stmt.getSelect() != null) {
         stmt.getSelect().accept(this);
      }

      if (stmt.getDistributedBy() != null) {
         this.println();
         stmt.getDistributedBy().accept(this);
      }

      if (stmt.getPartitioning() != null) {
         this.println();
         stmt.getPartitioning().accept(this);
      }

      return false;
   }

   public void endVisit(GaussRevokeStatement x) {
   }

   public boolean visit(GaussAlterTriggerStatement x) {
      this.print0(this.ucase ? "ALTER TRIGGER " : "alter trigger ");
      x.getName().accept(this);
      this.print0(this.ucase ? " ON " : " on ");
      x.getTableName().accept(this);
      this.print0(this.ucase ? " RENAME TO " : " rename to ");
      x.getNewName().accept(this);
      return true;
   }

   public void endVisit(GaussDropTriggerStatement x) {
   }

   public boolean visit(GaussDropTriggerStatement x) {
      this.print0(this.ucase ? "DROP TRIGGER " : "drop trigger ");
      if (x.isIfExists()) {
         this.print0(this.ucase ? "IF EXISTS " : "if exists ");
      }

      x.getName().accept(this);
      this.print0(this.ucase ? " ON " : " on ");
      x.getTableName().accept(this);
      if (x.isCascade()) {
         this.print0(this.ucase ? " CASCADE " : " cascade ");
      }

      if (x.isRestrict()) {
         this.print0(this.ucase ? " RESTRICT " : " restrict ");
      }

      return true;
   }

   public boolean visit(GaussCreateTriggerStatement x) {
      this.print0(this.ucase ? "CREATE " : "create ");
      if (x.isConstraint()) {
         this.printUcase("CONSTRAINT ");
      }

      this.print0(this.ucase ? "TRIGGER " : "trigger ");
      x.getName().accept(this);
      ++this.indentCount;
      this.println();
      if (SQLCreateTriggerStatement.TriggerType.INSTEAD_OF.equals(x.getTriggerType())) {
         this.print0(this.ucase ? "INSTEAD OF" : "instead of");
      } else {
         String triggerTypeName = x.getTriggerType().name();
         this.print0(this.ucase ? triggerTypeName : triggerTypeName.toLowerCase());
      }

      if (x.isInsert()) {
         this.print0(this.ucase ? " INSERT" : " insert");
      }

      if (x.isDelete()) {
         if (x.isInsert()) {
            this.print0(this.ucase ? " OR" : " or");
         }

         this.print0(this.ucase ? " DELETE" : " delete");
      }

      if (x.isUpdate()) {
         if (x.isInsert() || x.isDelete()) {
            this.print0(this.ucase ? " OR" : " or");
         }

         this.print0(this.ucase ? " UPDATE" : " update");

         for(SQLName colum : x.getUpdateOfColumns()) {
            this.print(' ');
            colum.accept(this);
         }
      }

      this.println();
      this.print0(this.ucase ? "ON " : "on ");
      x.getOn().accept(this);
      if (x.isForEachRow()) {
         this.println();
         this.print0(this.ucase ? "FOR EACH ROW" : "for each row");
      }

      SQLExpr when = x.getWhen();
      if (when != null) {
         this.println();
         this.print0(this.ucase ? "WHEN " : "when ");
         when.accept(this);
      }

      if (x.isExecuteProcedure()) {
         this.println();
         this.printUcase("EXECUTE PROCEDURE ");
         x.getFunctionName().accept(this);
      }

      --this.indentCount;
      this.println();
      if (x.getBody() != null) {
         x.getBody().accept(this);
      }

      return false;
   }

   public void endVisit(GaussAlterTriggerStatement x) {
   }
}
