liquibase-core/src/main/java/liquibase/sqlgenerator/core/CreateIndexGeneratorFirebird.java
@Override
    public Sql[] generateSql(CreateIndexStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain)  {
        /*
         * According to https://firebirdsql.org/refdocs/langrefupd20-create-table.html#langrefupd20-ct-using-index ,
         * Firebird automatically creates indexes for PRIMARY KEY, UNIQUE KEY and FOREIGN KEY constraints,
         * so we should not duplicate that functionality (=we should not issue CREATE INDEX statements for them)
         */
        List<String> associatedWith = StringUtil.splitAndTrim(statement.getAssociatedWith(), ",");
        if ((associatedWith != null) && (associatedWith.contains(Index.MARK_PRIMARY_KEY) || associatedWith.contains
            (Index.MARK_UNIQUE_CONSTRAINT) || associatedWith.contains(Index.MARK_FOREIGN_KEY))) {
            return new Sql[0];
        }

        StringBuffer buffer = new StringBuffer();

        buffer.append("CREATE ");

        // If the statement wants a UNIQUE index, issue a CREATE UNIQUE ... INDEX statement.
        if ((statement.isUnique() != null) && statement.isUnique()) {
            buffer.append("UNIQUE ");
        }

        /*
         * Examine the direction (ASCending or DESCending) of all columns of the planned index. If _all_ of them
         * are DESC, issue a CREATE DESCENDING INDEX statement. If all of them are ASC, we do not need to do anything
         * special (ASCENDING is the default). However, since Firebird does not seem to support mixed ASC/DESC
         * columns within a single index, we must error out.
         *
         * The syntax we want to create is this:
         * CREATE [UNIQUE] [ASC[ENDING] | DESC[ENDING]] INDEX index_name ON table_name
          * {(col [, col …]) | COMPUTED BY (<expression>)};
         */
        ColumnAnalysisResult result = analyseColumns(statement, database);

        if (result.isFoundDescColumns())
            buffer.append("DESCENDING ");

        buffer.append("INDEX ");

        if (statement.getIndexName() != null) {
            String indexSchema = statement.getTableSchemaName();
            buffer.append(database.escapeIndexName(statement.getTableCatalogName(), indexSchema,
                    statement.getIndexName())).append(" ");
        }

        buffer.append("ON ");
        // append table name
        buffer.append(database.escapeTableName(statement.getTableCatalogName(), statement.getTableSchemaName(),
                statement.getTableName()));

        if (result.getNumComputedCols() > 0)
            buffer.append("COMPUTED BY ");

        buffer.append(String.format("(%s)", result.getColumnExpression()));

        return new Sql[]{new UnparsedSql(buffer.toString(), getAffectedIndex(statement))};
    }
@Override
    public Sql[] generateSql(CreateIndexStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain)  {
        /*
         * According to https://firebirdsql.org/refdocs/langrefupd20-create-table.html#langrefupd20-ct-using-index ,
         * Firebird automatically creates indexes for PRIMARY KEY, UNIQUE KEY and FOREIGN KEY constraints,
         * so we should not duplicate that functionality (=we should not issue CREATE INDEX statements for them)
         */
        List<String> associatedWith = StringUtil.splitAndTrim(statement.getAssociatedWith(), ",");
        if ((associatedWith != null) && (associatedWith.contains(Index.MARK_PRIMARY_KEY) || associatedWith.contains
            (Index.MARK_UNIQUE_CONSTRAINT) || associatedWith.contains(Index.MARK_FOREIGN_KEY))) {
            return new Sql[0];
        }

        StringBuffer buffer = new StringBuffer();

        buffer.append("CREATE ");

        // If the statement wants a UNIQUE index, issue a CREATE UNIQUE ... INDEX statement.
        if ((statement.isUnique() != null) && statement.isUnique()) {
            buffer.append("UNIQUE ");
        }

        /*
         * Examine the direction (ASCending or DESCending) of all columns of the planned index. If _all_ of them
         * are DESC, issue a CREATE DESCENDING INDEX statement. If all of them are ASC, we do not need to do anything
         * special (ASCENDING is the default). However, since Firebird does not seem to support mixed ASC/DESC
         * columns within a single index, we must error out.
         *
         * The syntax we want to create is this:
         * CREATE [UNIQUE] [ASC[ENDING] | DESC[ENDING]] INDEX index_name ON table_name
          * {(col [, col …]) | COMPUTED BY (<expression>)};
         */
        ColumnAnalysisResult result = analyseColumns(statement, database);

        if (result.isFoundDescColumns())
            buffer.append("DESCENDING ");

        buffer.append("INDEX ");

        if (statement.getIndexName() != null) {
            String indexSchema = statement.getTableSchemaName();
            buffer.append(database.escapeIndexName(statement.getTableCatalogName(), indexSchema,
                    statement.getIndexName())).append(" ");
        }

        buffer.append("ON ");
        // append table name
        buffer.append(database.escapeTableName(statement.getTableCatalogName(), statement.getTableSchemaName(),
                statement.getTableName()));

        if (result.getNumComputedCols() > 0)
            buffer.append("COMPUTED BY ");

        buffer.append(String.format("(%s)", result.getColumnExpression()));

        return new Sql[]{new UnparsedSql(buffer.toString(), getAffectedIndex(statement))};
    }
Generate a CREATE INDEX SQL statement for Firebird databases.
@param statement A CreateIndexStatement with the desired properties of the SQL to be generated
@param database A database object (must be of FirebirdDatabase type, or we will error out)
@param sqlGeneratorChain The other generators in the current chain (ignored by this implementation)
@return An array with one entry containing the generated CREATE INDEX statement for Firebird.