class MariaDBDatabase extends MySQLDatabase {
    private static final String PRODUCT_NAME = "MariaDB";

    public MariaDBDatabase() {
        addReservedWords(Collections.singletonList("PERIOD"));
        super.sequenceNextValueFunction = "NEXT VALUE FOR %s";
        // According to https://mariadb.com/kb/en/library/data-types/, retrieved on 2019-02-12
        super.unmodifiableDataTypes.addAll(Arrays.asList(
           "boolean", "tinyint", "smallint", "mediumint", "int", "integer", "bigint", "dec", "numeric",
           "fixed", "float", "bit"
        ));
    }

    @Override
    public String getShortName() {
        return "mariadb";
    }

    @Override
    protected String getDefaultDatabaseProductName() {
        return MariaDBDatabase.PRODUCT_NAME;
    }

    @Override
    public String getDefaultDriver(String url) {
        if (url.startsWith("jdbc:mariadb")) {
            return "org.mariadb.jdbc.Driver";
        }
        return null;
    }

    @Override
    public int getMaxFractionalDigitsForTimestamp() {

        int major = 0;
        int minor = 0;
        int patch = 0;
        String productVersion = null;

        try {
            productVersion = getDatabaseProductVersion();
            if (productVersion != null && productVersion.toLowerCase().contains("clustrix")) {
                return 6;
            }
        } catch (DatabaseException dbe) {

        }
        try {
            major = getDatabaseMajorVersion();
            minor = getDatabaseMinorVersion();
            patch = getDatabasePatchVersion();
        } catch (DatabaseException x) {
            Scope.getCurrentScope().getLog(getClass()).warning(
                    "Unable to determine exact database server version"
                            + " - specified TIMESTAMP precision"
                            + " will not be set: ", x);
            return 0;
        }

        // MariaDB 5.3 introduced fractional support...
        // https://mariadb.com/kb/en/library/microseconds-in-mariadb/
        String minimumVersion = "5.3.0";

        if (StringUtil.isMinimumVersion(minimumVersion, major, minor, patch))
            return 6;
        else
            return 0;
    }

    @Override
    public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {<FILL_FUNCTION_BODY>}

    @Override
    protected String getMinimumVersionForFractionalDigitsForTimestamp() {
        // Since MariaDB 5.3, the TIME, DATETIME, and TIMESTAMP types,
        // along with the temporal functions, CAST and dynamic columns,
        // have supported microseconds.
        // https://mariadb.com/kb/en/library/microseconds-in-mariadb/
        return "5.3.0";
    }


    @Override
    public boolean supports(Class<? extends DatabaseObject> object) {
        if (Sequence.class.isAssignableFrom(object)) {
            try {
                // From https://liquibase.jira.com/browse/CORE-3457 (by Lijun Liao) corrected
                int majorVersion = getDatabaseMajorVersion();
                return majorVersion > 10 || (majorVersion == 10 && getDatabaseMinorVersion() >= 3);
            } catch (DatabaseException e) {
                Scope.getCurrentScope().getLog(getClass()).fine("Cannot retrieve database version", e);
                return false;
            }
        }
        return super.supports(object);
    }

    @Override
    public boolean supportsSequences() {
        try {
            // From https://liquibase.jira.com/browse/CORE-3457 (by Lijun Liao) corrected
            int majorVersion = getDatabaseMajorVersion();
            return majorVersion > 10 || (majorVersion == 10 && getDatabaseMinorVersion() >= 3);
        } catch (DatabaseException e) {
            Scope.getCurrentScope().getLog(getClass()).fine("Cannot retrieve database version", e);
            return false;
        }
    }

    @Override
    public boolean supportsCreateIfNotExists(Class<? extends DatabaseObject> type) {
        return type.isAssignableFrom(Table.class);
    }

    @Override
    public boolean supportsDatabaseChangeLogHistory() {
        return true;
    }
}

        // Presumbably for compatiblity reasons, a MariaDB instance might identify with getDatabaseProductName()=MySQL.
        // To be certain, We search for "mariadb" in the version string.
        if (PRODUCT_NAME.equalsIgnoreCase(conn.getDatabaseProductName())) {
            return true; // Identified as MariaDB product
        } else {
            return ("MYSQL".equalsIgnoreCase(conn.getDatabaseProductName()) &&
                (conn.getDatabaseProductVersion().toLowerCase().contains("mariadb") ||
                 conn.getDatabaseProductVersion().toLowerCase().contains("clustrix")));
        }
    
<methods>public void <init>() ,public java.lang.String correctObjectName(java.lang.String, Class<? extends liquibase.structure.DatabaseObject>) ,public boolean createsIndexesForForeignKeys() ,public boolean disableForeignKeyChecks() throws liquibase.exception.DatabaseException,public void enableForeignKeyChecks() throws liquibase.exception.DatabaseException,public java.lang.String escapeIndexName(java.lang.String, java.lang.String, java.lang.String) ,public java.lang.String escapeStringForDatabase(java.lang.String) ,public java.lang.String generateDatabaseFunctionValue(liquibase.statement.DatabaseFunction) ,public transient java.lang.String getConcatSql(java.lang.String[]) ,public int getDatabasePatchVersion() throws liquibase.exception.DatabaseException,public java.lang.String getDefaultDriver(java.lang.String) ,public int getDefaultFractionalDigitsForTimestamp() ,public java.lang.Integer getDefaultPort() ,public java.lang.String getLineComment() ,public int getMaxFractionalDigitsForTimestamp() ,public int getPriority() ,public liquibase.CatalogAndSchema getSchemaFromJdbcInfo(java.lang.String, java.lang.String) ,public java.lang.String getShortName() ,public java.lang.String getTableOptionAutoIncrementStartWithClause(java.math.BigInteger) ,public boolean getUseAffectedRows() throws liquibase.exception.DatabaseException,public boolean isCorrectDatabaseImplementation(liquibase.database.DatabaseConnection) throws liquibase.exception.DatabaseException,public boolean isMinimumMySQLVersion(java.lang.String) ,public boolean isReservedWord(java.lang.String) ,public boolean supports(Class<? extends liquibase.structure.DatabaseObject>) ,public boolean supportsCatalogs() ,public boolean supportsCreateIfNotExists(Class<? extends liquibase.structure.DatabaseObject>) ,public boolean supportsDatabaseChangeLogHistory() ,public boolean supportsForeignKeyDisable() ,public boolean supportsInitiallyDeferrableColumns() ,public boolean supportsSchemas() ,public boolean supportsSequences() ,public boolean supportsTablespaces() ,public void warnAboutAlterColumn(java.lang.String, liquibase.exception.Warnings) <variables>public static final java.util.regex.Pattern PRECISION_PATTERN,private static final java.lang.String PRECISION_REGEX,private static final java.lang.String PRODUCT_NAME,private static final Set<java.lang.String> RESERVED_WORDS