/**
   * Overridden to generate add table statement to have domain/type level
   * check constraints be added on the table level. The reason why it is being
   * generated on the table level is because SQL Server does not allow
   * multiple named check constraints on a single column. Only one named or
   * unnamed check constraint per column is allowed.
   *
   * Since check constraints from multiple objects are being combined into the
   * table level, we must ensure that there are no name conflicts by
   * prepending tags to identify which SQLObject type and physical name the
   * check constraint is actually supposed to be applied on. e.g.
   * col_<column-name>_<constraint-name> or table_<table-name>_<constraint-name>.
   * This is especially important since actual table level check constraints
   * will be added in the future.
   */
  @Override
  public void addTable(SQLTable t) throws SQLException, SQLObjectException {
    Map<String, SQLObject> colNameMap =
        new HashMap<String, SQLObject>(); // for detecting duplicate column names
    // generate a new physical name if necessary
    createPhysicalName(topLevelNames, t); // also adds generated physical name to the map
    print("\nCREATE TABLE ");
    print(toQualifiedName(t));
    println(" (");
    boolean firstCol = true;

    List<SQLColumn> columns = t.getColumns();

    for (SQLColumn c : columns) {
      if (!firstCol) println(",");
      print("                ");

      print(columnDefinition(c, colNameMap));

      firstCol = false;
    }

    SQLIndex pk = t.getPrimaryKeyIndex();
    if (pk.getChildCount() > 0) {
      print(",\n");
      print("                ");
      writePKConstraintClause(pk);
    }

    for (SQLColumn c : columns) {
      UserDefinedSQLType type = c.getUserDefinedSQLType();
      List<SQLCheckConstraint> checkConstraints;
      SQLTypeConstraint constraintType = type.getConstraintType(getPlatformName());
      if (constraintType == null) {
        constraintType = type.getDefaultPhysicalProperties().getConstraintType();
        checkConstraints = type.getDefaultPhysicalProperties().getCheckConstraints();
      } else {
        checkConstraints = type.getCheckConstraints(getPlatformName());
      }

      if (constraintType == SQLTypeConstraint.CHECK) {
        print(",\n");
        print(columnCheckConstraint(c, checkConstraints));
      }
    }

    print("\n)");
    endStatement(StatementType.CREATE, t);
    addComment(t, true);
  }
  /**
   * SQL Server does not allow multiple named check constraints on the column level. Only one named
   * or unnamed check constraint is allowed. Instead, we must add them on the table level.
   *
   * @see #addTable(SQLTable)
   */
  @Override
  protected String columnDefinition(SQLColumn c, Map<String, SQLObject> colNameMap) {
    StringBuffer def = new StringBuffer();

    // Column name
    def.append(createPhysicalName(colNameMap, c));

    def.append(" ");
    def.append(columnType(c));

    UserDefinedSQLType type = c.getUserDefinedSQLType();
    String defaultValue = type.getDefaultValue(getPlatformName());
    if (defaultValue != null && !defaultValue.equals("")) {
      def.append(" ");
      def.append("DEFAULT ");
      def.append(defaultValue);
    }

    def.append(columnNullability(c));

    List<SQLEnumeration> enumerations;
    SQLTypeConstraint constraintType = type.getConstraintType(getPlatformName());
    if (constraintType == null) {
      constraintType = type.getDefaultPhysicalProperties().getConstraintType();
      enumerations =
          type.getDefaultPhysicalProperties().getChildrenWithoutPopulating(SQLEnumeration.class);
    } else {
      enumerations = type.getEnumerations(getPlatformName());
    }

    // Add enumeration.
    if (constraintType == SQLTypeConstraint.ENUM) {
      String columnEnumeration = columnEnumeration(c, enumerations);
      if (columnEnumeration != null && columnEnumeration.length() > 0) {
        def.append(" " + columnEnumeration);
      }
    }

    logger.debug("column definition " + def.toString());
    return def.toString();
  }