@Override
    public Sql[] generateSql(CreateTableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
        StringBuilder buffer = new StringBuilder();

        // CREATE TABLE table_name ...
        buffer.append("CREATE TABLE ")
                .append(database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()))
                .append(" ");
        buffer.append("(");

        Iterator<String> columnIterator = statement.getColumns().iterator();
        List<String> primaryKeyColumns = new LinkedList<>();

        /*
         * Build the list of columns and constraints in the form
         * (
         *   column1,
         *   ...,
         *   columnN,
         *   constraint1,
         *   ...,
         *   constraintN
         * )
         */
        while (columnIterator.hasNext()) {
            String column = columnIterator.next();
            
            buffer.append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), column));
            buffer.append(" ").append(statement.getColumnTypes().get(column).toDatabaseDataType(database).toSql());
            
            AutoIncrementConstraint autoIncrementConstraint = null;
            
            for (AutoIncrementConstraint currentAutoIncrementConstraint : statement.getAutoIncrementConstraints()) {
                if (column.equals(currentAutoIncrementConstraint.getColumnName())) {
                    autoIncrementConstraint = currentAutoIncrementConstraint;
                    break;
                }
            }

            boolean isAutoIncrementColumn = autoIncrementConstraint != null;            
            boolean isPrimaryKeyColumn = (statement.getPrimaryKeyConstraint() != null) && statement
                .getPrimaryKeyConstraint().getColumns().contains(column);

            if (isPrimaryKeyColumn) {
                primaryKeyColumns.add(column);
            }
            
            if (statement.getDefaultValue(column) != null) {
                Object defaultValue = statement.getDefaultValue(column);
                buffer.append(" DEFAULT ");
                buffer.append(statement.getColumnTypes().get(column).objectToSql(defaultValue, database));
            }

            if (isAutoIncrementColumn) {
                // TODO: check if database supports auto increment on non primary key column
                if (database.supportsAutoIncrement()) {
                    String autoIncrementClause = database.getAutoIncrementClause(autoIncrementConstraint.getStartWith(), autoIncrementConstraint.getIncrementBy());
                
                    if (!autoIncrementClause.isEmpty()) {
                        buffer.append(" ").append(autoIncrementClause);
                    }
                } else {
                    Scope.getCurrentScope().getLog(getClass()).warning(LogType.LOG, database.getShortName()+" does not support autoincrement columns as requested for "+(database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())));
                }
            }

            if (statement.getNotNullColumns().get(column) != null) {
                buffer.append(" NOT NULL");
            }

            if (columnIterator.hasNext()) {
                buffer.append(", ");
            }
        }

        buffer.append(",");

        /*
         * We only create a PRIMARY KEY constraint if one is defined and has at least 1 column.
         * General Informix SQL syntax, according to the docs for 11.5
         * https://www.ibm.com/support/knowledgecenter/SSGU8G_11.50.0/com.ibm.sqls.doc/ids_sqs_0100.htm
         * is:
         * ( columns ... --> PRIMARY KEY (column1, ..., columnN) [CONSTRAINT pk_name]
          */
        //

        PrimaryKeyConstraint pkConstraint = statement.getPrimaryKeyConstraint();
        if ((statement.getPrimaryKeyConstraint() != null) && !statement.getPrimaryKeyConstraint().getColumns().isEmpty()) {
            buffer.append(" PRIMARY KEY (");
            buffer.append(StringUtil.join(primaryKeyColumns, ", "));
            buffer.append(")");

            if (! StringUtil.isEmpty(pkConstraint.getConstraintName() )) {
                buffer.append(" CONSTRAINT ");
                buffer.append(database.escapeConstraintName(pkConstraint.getConstraintName()));
            }
            // Setting up table space for PK's index if it exist
            buffer.append(",");
        }

        for (ForeignKeyConstraint fkConstraint : statement.getForeignKeyConstraints()) {
            String referencesString = fkConstraint.getReferences();
            if (!referencesString.contains(".") && (database.getDefaultSchemaName() != null)) {
                referencesString = database.getDefaultSchemaName()+"."+referencesString;
            }
            buffer.append(" FOREIGN KEY (")
                .append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), fkConstraint.getColumn()))
                .append(") REFERENCES ")
                .append(referencesString);

            if (fkConstraint.isDeleteCascade()) {
                buffer.append(" ON DELETE CASCADE");
            }

            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));

            if (fkConstraint.isInitiallyDeferred()) {
                buffer.append(" INITIALLY DEFERRED");
            }
            if (fkConstraint.isDeferrable()) {
                buffer.append(" DEFERRABLE");
            }
            buffer.append(",");
        }

        // TODO: code duplication. Maybe we can merge this whole class into CreateTableGenerator again.
        for (UniqueConstraint uniqueConstraint : statement.getUniqueConstraints()) {
            if ((uniqueConstraint.getConstraintName() != null) && !constraintNameAfterUnique(database)) {
                buffer.append(" CONSTRAINT ");
                buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
            }
            buffer.append(" UNIQUE (");
            buffer.append(database.escapeColumnNameList(StringUtil.join(uniqueConstraint.getColumns(), ", ")));
            buffer.append(")");
            if ((uniqueConstraint.getConstraintName() != null) && constraintNameAfterUnique(database)) {
                buffer.append(" CONSTRAINT ");
                buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
            }
            buffer.append(",");
        }

        /*
         * Here, the list of columns and constraints in the form
         * ( column1, ..., columnN, constraint1, ..., constraintN,
         * ends. We cannot leave an expression like ", )", so we remove the last comma.
         */
        String sql = buffer.toString().replaceFirst(",\\s*$", "") + ")";

        if ((statement.getTablespace() != null) && database.supportsTablespaces()) {
            sql += " IN " + statement.getTablespace();
        }

        return new Sql[] { new UnparsedSql(sql, new Table().setName(statement.getTableName()).setSchema(new Schema(statement.getCatalogName(), statement.getSchemaName()))) };
    }
@Override
    public Sql[] generateSql(CreateTableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
        StringBuilder buffer = new StringBuilder();

        
        buffer.append("CREATE TABLE ")
                .append(database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()))
                .append(" ");
        buffer.append("(");

        Iterator<String> columnIterator = statement.getColumns().iterator();
        List<String> primaryKeyColumns = new LinkedList<>();

        
        while (columnIterator.hasNext()) {
            String column = columnIterator.next();
            
            buffer.append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), column));
            buffer.append(" ").append(statement.getColumnTypes().get(column).toDatabaseDataType(database).toSql());
            
            AutoIncrementConstraint autoIncrementConstraint = null;
            
            for (AutoIncrementConstraint currentAutoIncrementConstraint : statement.getAutoIncrementConstraints()) {
                if (column.equals(currentAutoIncrementConstraint.getColumnName())) {
                    autoIncrementConstraint = currentAutoIncrementConstraint;
                    break;
                }
            }

            boolean isAutoIncrementColumn = autoIncrementConstraint != null;            
            boolean isPrimaryKeyColumn = (statement.getPrimaryKeyConstraint() != null) && statement
                .getPrimaryKeyConstraint().getColumns().contains(column);

            if (isPrimaryKeyColumn) {
                primaryKeyColumns.add(column);
            }
            
            if (statement.getDefaultValue(column) != null) {
                Object defaultValue = statement.getDefaultValue(column);
                buffer.append(" DEFAULT ");
                buffer.append(statement.getColumnTypes().get(column).objectToSql(defaultValue, database));
            }

            if (isAutoIncrementColumn) {
                
                if (database.supportsAutoIncrement()) {
                    String autoIncrementClause = database.getAutoIncrementClause(autoIncrementConstraint.getStartWith(), autoIncrementConstraint.getIncrementBy());
                
                    if (!autoIncrementClause.isEmpty()) {
                        buffer.append(" ").append(autoIncrementClause);
                    }
                } else {
                    Scope.getCurrentScope().getLog(getClass()).warning(LogType.LOG, database.getShortName()+" does not support autoincrement columns as requested for "+(database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())));
                }
            }

            if (statement.getNotNullColumns().get(column) != null) {
                buffer.append(" NOT NULL");
            }

            if (columnIterator.hasNext()) {
                buffer.append(", ");
            }
        }

        buffer.append(",");

        
        

        PrimaryKeyConstraint pkConstraint = statement.getPrimaryKeyConstraint();
        if ((statement.getPrimaryKeyConstraint() != null) && !statement.getPrimaryKeyConstraint().getColumns().isEmpty()) {
            buffer.append(" PRIMARY KEY (");
            buffer.append(StringUtil.join(primaryKeyColumns, ", "));
            buffer.append(")");

            if (! StringUtil.isEmpty(pkConstraint.getConstraintName() )) {
                buffer.append(" CONSTRAINT ");
                buffer.append(database.escapeConstraintName(pkConstraint.getConstraintName()));
            }
            
            buffer.append(",");
        }

        for (ForeignKeyConstraint fkConstraint : statement.getForeignKeyConstraints()) {
            String referencesString = fkConstraint.getReferences();
            if (!referencesString.contains(".") && (database.getDefaultSchemaName() != null)) {
                referencesString = database.getDefaultSchemaName()+"."+referencesString;
            }
            buffer.append(" FOREIGN KEY (")
                .append(database.escapeColumnName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName(), fkConstraint.getColumn()))
                .append(") REFERENCES ")
                .append(referencesString);

            if (fkConstraint.isDeleteCascade()) {
                buffer.append(" ON DELETE CASCADE");
            }

            buffer.append(" CONSTRAINT ");
            buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));

            if (fkConstraint.isInitiallyDeferred()) {
                buffer.append(" INITIALLY DEFERRED");
            }
            if (fkConstraint.isDeferrable()) {
                buffer.append(" DEFERRABLE");
            }
            buffer.append(",");
        }

        
        for (UniqueConstraint uniqueConstraint : statement.getUniqueConstraints()) {
            if ((uniqueConstraint.getConstraintName() != null) && !constraintNameAfterUnique(database)) {
                buffer.append(" CONSTRAINT ");
                buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
            }
            buffer.append(" UNIQUE (");
            buffer.append(database.escapeColumnNameList(StringUtil.join(uniqueConstraint.getColumns(), ", ")));
            buffer.append(")");
            if ((uniqueConstraint.getConstraintName() != null) && constraintNameAfterUnique(database)) {
                buffer.append(" CONSTRAINT ");
                buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
            }
            buffer.append(",");
        }

        
        String sql = buffer.toString().replaceFirst(",\\s*$", "") + ")";

        if ((statement.getTablespace() != null) && database.supportsTablespaces()) {
            sql += " IN " + statement.getTablespace();
        }

        return new Sql[] { new UnparsedSql(sql, new Table().setName(statement.getTableName()).setSchema(new Schema(statement.getCatalogName(), statement.getSchemaName()))) };
    }
@ Override public Sql [ ] generateSql ( CreateTableStatement statement , Database database , SqlGeneratorChain sqlGeneratorChain ) { StringBuilder buffer = new StringBuilder ( ) ; // CREATE TABLE table_name ... buffer . append ( "CREATE TABLE " ) . append ( database . escapeTableName ( statement . getCatalogName ( ) , statement . getSchemaName ( ) , statement . getTableName ( ) ) ) . append ( " " ) ; buffer . append ( "(" ) ; Iterator < String > columnIterator = statement . getColumns ( ) . iterator ( ) ; List < String > primaryKeyColumns = new LinkedList <> ( ) ; /*
         * Build the list of columns and constraints in the form
         * (
         *   column1,
         *   ...,
         *   columnN,
         *   constraint1,
         *   ...,
         *   constraintN
         * )
         */ while ( columnIterator . hasNext ( ) ) { String column = columnIterator . next ( ) ; buffer . append ( database . escapeColumnName ( statement . getCatalogName ( ) , statement . getSchemaName ( ) , statement . getTableName ( ) , column ) ) ; buffer . append ( " " ) . append ( statement . getColumnTypes ( ) . get ( column ) . toDatabaseDataType ( database ) . toSql ( ) ) ; AutoIncrementConstraint autoIncrementConstraint = null ; for ( AutoIncrementConstraint currentAutoIncrementConstraint : statement . getAutoIncrementConstraints ( ) ) { if ( column . equals ( currentAutoIncrementConstraint . getColumnName ( ) ) ) { autoIncrementConstraint = currentAutoIncrementConstraint ; break ; } } boolean isAutoIncrementColumn = autoIncrementConstraint != null ; boolean isPrimaryKeyColumn = ( statement . getPrimaryKeyConstraint ( ) != null ) && statement . getPrimaryKeyConstraint ( ) . getColumns ( ) . contains ( column ) ; if ( isPrimaryKeyColumn ) { primaryKeyColumns . add ( column ) ; } if ( statement . getDefaultValue ( column ) != null ) { Object defaultValue = statement . getDefaultValue ( column ) ; buffer . append ( " DEFAULT " ) ; buffer . append ( statement . getColumnTypes ( ) . get ( column ) . objectToSql ( defaultValue , database ) ) ; } if ( isAutoIncrementColumn ) { // TODO: check if database supports auto increment on non primary key column if ( database . supportsAutoIncrement ( ) ) { String autoIncrementClause = database . getAutoIncrementClause ( autoIncrementConstraint . getStartWith ( ) , autoIncrementConstraint . getIncrementBy ( ) ) ; if ( ! autoIncrementClause . isEmpty ( ) ) { buffer . append ( " " ) . append ( autoIncrementClause ) ; } } else { Scope . getCurrentScope ( ) . getLog ( getClass ( ) ) . warning ( LogType . LOG , database . getShortName ( ) + " does not support autoincrement columns as requested for " + ( database . escapeTableName ( statement . getCatalogName ( ) , statement . getSchemaName ( ) , statement . getTableName ( ) ) ) ) ; } } if ( statement . getNotNullColumns ( ) . get ( column ) != null ) { buffer . append ( " NOT NULL" ) ; } if ( columnIterator . hasNext ( ) ) { buffer . append ( ", " ) ; } } buffer . append ( "," ) ; /*
         * We only create a PRIMARY KEY constraint if one is defined and has at least 1 column.
         * General Informix SQL syntax, according to the docs for 11.5
         * https://www.ibm.com/support/knowledgecenter/SSGU8G_11.50.0/com.ibm.sqls.doc/ids_sqs_0100.htm
         * is:
         * ( columns ... --> PRIMARY KEY (column1, ..., columnN) [CONSTRAINT pk_name]
          */ // PrimaryKeyConstraint pkConstraint = statement . getPrimaryKeyConstraint ( ) ; if ( ( statement . getPrimaryKeyConstraint ( ) != null ) && ! statement . getPrimaryKeyConstraint ( ) . getColumns ( ) . isEmpty ( ) ) { buffer . append ( " PRIMARY KEY (" ) ; buffer . append ( StringUtil . join ( primaryKeyColumns , ", " ) ) ; buffer . append ( ")" ) ; if ( ! StringUtil . isEmpty ( pkConstraint . getConstraintName ( ) ) ) { buffer . append ( " CONSTRAINT " ) ; buffer . append ( database . escapeConstraintName ( pkConstraint . getConstraintName ( ) ) ) ; } // Setting up table space for PK's index if it exist buffer . append ( "," ) ; } for ( ForeignKeyConstraint fkConstraint : statement . getForeignKeyConstraints ( ) ) { String referencesString = fkConstraint . getReferences ( ) ; if ( ! referencesString . contains ( "." ) && ( database . getDefaultSchemaName ( ) != null ) ) { referencesString = database . getDefaultSchemaName ( ) + "." + referencesString ; } buffer . append ( " FOREIGN KEY (" ) . append ( database . escapeColumnName ( statement . getCatalogName ( ) , statement . getSchemaName ( ) , statement . getTableName ( ) , fkConstraint . getColumn ( ) ) ) . append ( ") REFERENCES " ) . append ( referencesString ) ; if ( fkConstraint . isDeleteCascade ( ) ) { buffer . append ( " ON DELETE CASCADE" ) ; } buffer . append ( " CONSTRAINT " ) ; buffer . append ( database . escapeConstraintName ( fkConstraint . getForeignKeyName ( ) ) ) ; if ( fkConstraint . isInitiallyDeferred ( ) ) { buffer . append ( " INITIALLY DEFERRED" ) ; } if ( fkConstraint . isDeferrable ( ) ) { buffer . append ( " DEFERRABLE" ) ; } buffer . append ( "," ) ; } // TODO: code duplication. Maybe we can merge this whole class into CreateTableGenerator again. for ( UniqueConstraint uniqueConstraint : statement . getUniqueConstraints ( ) ) { if ( ( uniqueConstraint . getConstraintName ( ) != null ) && ! constraintNameAfterUnique ( database ) ) { buffer . append ( " CONSTRAINT " ) ; buffer . append ( database . escapeConstraintName ( uniqueConstraint . getConstraintName ( ) ) ) ; } buffer . append ( " UNIQUE (" ) ; buffer . append ( database . escapeColumnNameList ( StringUtil . join ( uniqueConstraint . getColumns ( ) , ", " ) ) ) ; buffer . append ( ")" ) ; if ( ( uniqueConstraint . getConstraintName ( ) != null ) && constraintNameAfterUnique ( database ) ) { buffer . append ( " CONSTRAINT " ) ; buffer . append ( database . escapeConstraintName ( uniqueConstraint . getConstraintName ( ) ) ) ; } buffer . append ( "," ) ; } /*
         * Here, the list of columns and constraints in the form
         * ( column1, ..., columnN, constraint1, ..., constraintN,
         * ends. We cannot leave an expression like ", )", so we remove the last comma.
         */ String sql = buffer . toString ( ) . replaceFirst ( ",\\s*$" , "" ) + ")" ; if ( ( statement . getTablespace ( ) != null ) && database . supportsTablespaces ( ) ) { sql += " IN " + statement . getTablespace ( ) ; } return new Sql [ ] { new UnparsedSql ( sql , new Table ( ) . setName ( statement . getTableName ( ) ) . setSchema ( new Schema ( statement . getCatalogName ( ) , statement . getSchemaName ( ) ) ) ) } ; }
Informix SQL-specific implementation of the CREATE TABLE SQL generator.
@param statement The properties of the statement that we will translate into SQL
@param database For this implementation always an object of the InformixDatabase type
@param sqlGeneratorChain Other generators in the pipeline for this command
@return An array of Sql[] statements containing the requested SQL statements for Informix SQL
Informix SQL - specific implementation of the CREATE TABLE SQL generator .