CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-flywaydb--flyway-database-postgresql

PostgreSQL database support module for Flyway migration tool with specialized implementations for PostgreSQL and CockroachDB databases

Pending
Overview
Eval results
Files

cockroachdb-support.mddocs/

CockroachDB Support

Specialized database support for CockroachDB databases, providing retry logic, version detection, and database-specific optimizations within the Flyway migration framework.

Capabilities

CockroachDB Database Type

Database type implementation that provides CockroachDB-specific functionality while maintaining PostgreSQL wire protocol compatibility.

/**
 * CockroachDB database type implementation
 */
public class CockroachDBDatabaseType extends BaseDatabaseType {
    /**
     * Returns the database name identifier
     * @return "CockroachDB"
     */
    public String getName();
    
    /**
     * Returns the null type identifier for this database
     * @return Types.NULL
     */
    public int getNullType();
    
    /**
     * Indicates whether CockroachDB supports read-only transactions
     * @return false (CockroachDB does not support read-only transactions)
     */
    public boolean supportsReadOnlyTransactions();
    
    /**
     * Checks if this database type can handle the given JDBC URL
     * Uses PostgreSQL driver but with CockroachDB-specific detection
     * @param url JDBC URL to check
     * @return true for PostgreSQL URLs (detection happens later)
     */
    public boolean handlesJDBCUrl(String url);
    
    /**
     * Returns the priority for database type selection
     * @return 1 (higher than PostgreSQL to be checked first)
     */
    public int getPriority();
    
    /**
     * Returns the JDBC driver class for CockroachDB
     * @param url JDBC URL
     * @param classLoader Class loader for loading driver
     * @return PostgreSQL driver class name
     */
    public String getDriverClass(String url, ClassLoader classLoader);
    
    /**
     * Detects CockroachDB by checking database product name and version output
     * @param databaseProductName Database product name from JDBC metadata
     * @param databaseProductVersion Database version
     * @param connection JDBC connection for additional queries
     * @return true if SELECT VERSION() output contains "CockroachDB"
     */
    public boolean handlesDatabaseProductNameAndVersion(String databaseProductName, 
                                                       String databaseProductVersion, 
                                                       Connection connection);
    
    /**
     * Creates a CockroachDB database instance
     * @param configuration Flyway configuration
     * @param jdbcConnectionFactory Connection factory
     * @param statementInterceptor Statement interceptor
     * @return CockroachDBDatabase instance
     */
    public Database createDatabase(Configuration configuration, 
                                  JdbcConnectionFactory jdbcConnectionFactory, 
                                  StatementInterceptor statementInterceptor);
    
    /**
     * Creates a CockroachDB parser instance
     * @param configuration Flyway configuration
     * @param resourceProvider Resource provider for loading SQL files
     * @param parsingContext Parsing context
     * @return CockroachDBParser instance
     */
    public Parser createParser(Configuration configuration, 
                              ResourceProvider resourceProvider, 
                              ParsingContext parsingContext);
    
    /**
     * Creates CockroachDB-specific execution strategy with retry logic
     * @param connection JDBC connection
     * @return CockroachDBRetryingStrategy for handling transaction retries
     */
    public DatabaseExecutionStrategy createExecutionStrategy(Connection connection);
    
    /**
     * Creates transactional execution template with CockroachDB retry logic
     * @param connection JDBC connection
     * @param rollbackOnException Whether to rollback on exceptions
     * @return CockroachRetryingTransactionalExecutionTemplate
     */
    public ExecutionTemplate createTransactionalExecutionTemplate(Connection connection, 
                                                                 boolean rollbackOnException);
}

Usage Examples:

import org.flywaydb.database.cockroachdb.CockroachDBDatabaseType;

// Database type is automatically registered and detected
// CockroachDB connections use PostgreSQL JDBC URLs
Flyway flyway = Flyway.configure()
    .dataSource("jdbc:postgresql://localhost:26257/mydb", "root", "")
    .locations("classpath:db/migration")
    .load();

// CockroachDB is automatically detected via version string
CockroachDBDatabaseType dbType = new CockroachDBDatabaseType();
boolean hasHigherPriority = dbType.getPriority() > 0; // true - checked before PostgreSQL

// Verify database capabilities
boolean supportsReadOnly = dbType.supportsReadOnlyTransactions(); // false

CockroachDB Database

Main database implementation providing CockroachDB-specific operations and version detection.

/**
 * CockroachDB database implementation
 */
public class CockroachDBDatabase extends Database<CockroachDBConnection> {
    /**
     * Creates a new CockroachDB database instance
     * Automatically detects and stores the CockroachDB version
     * @param configuration Flyway configuration
     * @param jdbcConnectionFactory Connection factory
     * @param statementInterceptor Statement interceptor
     */
    public CockroachDBDatabase(Configuration configuration, 
                              JdbcConnectionFactory jdbcConnectionFactory, 
                              StatementInterceptor statementInterceptor);
    
    /**
     * Creates a CockroachDB connection wrapper
     * @param connection Raw JDBC connection
     * @return CockroachDBConnection instance
     */
    protected CockroachDBConnection doGetConnection(Connection connection);
    
    /**
     * Ensures the CockroachDB version is supported by Flyway
     * @param configuration Flyway configuration
     * @throws FlywayException if version is not supported
     */
    public void ensureSupported(Configuration configuration);
    
    /**
     * Generates the SQL script for creating the Flyway schema history table
     * Uses CREATE TABLE IF NOT EXISTS for CockroachDB compatibility
     * @param table The table to create
     * @param baseline Whether to include baseline entry
     * @return SQL script for table creation with CockroachDB-specific syntax
     */
    public String getRawCreateScript(Table table, boolean baseline);
    
    /**
     * Determines the CockroachDB version from database metadata
     * @return Parsed version (e.g., "22.1" from "v22.1.2")
     */
    protected MigrationVersion determineVersion();
    
    /**
     * Checks if this CockroachDB version supports schemas
     * @return true for version 20.2 and later
     */
    boolean supportsSchemas();
    
    /**
     * Gets the current database user
     * @return Current user name from SHOW SESSION_USER
     * @throws SQLException if user cannot be determined
     */
    protected String doGetCurrentUser() throws SQLException;
    
    /**
     * Indicates whether CockroachDB supports DDL transactions
     * @return false (CockroachDB limitation)
     */
    public boolean supportsDdlTransactions();
    
    /**
     * Returns the CockroachDB boolean true literal
     * @return "TRUE"
     */
    public String getBooleanTrue();
    
    /**
     * Returns the CockroachDB boolean false literal
     * @return "FALSE"
     */
    public String getBooleanFalse();
    
    /**
     * Indicates whether catalog equals schema in CockroachDB
     * @return false
     */
    public boolean catalogIsSchema();
    
    /**
     * Determines connection usage strategy for CockroachDB
     * @return false (always use multiple connections due to retry requirements)
     */
    public boolean useSingleConnection();
}

CockroachDB Connection Management

CockroachDB-specific connection handling with schema support and database version awareness.

/**
 * CockroachDB connection implementation
 */
public class CockroachDBConnection extends Connection<CockroachDBDatabase> {
    /**
     * Creates a new CockroachDB connection wrapper
     * @param database The CockroachDB database instance
     * @param connection The raw JDBC connection
     */
    public CockroachDBConnection(CockroachDBDatabase database, java.sql.Connection connection);
    
    /**
     * Gets a schema by name (requires CockroachDB 20.2+)
     * @param name Schema name
     * @return CockroachDBSchema instance
     */
    public Schema getSchema(String name);
    
    /**
     * Gets the current schema for this connection
     * @return Current schema or null if schemas not supported
     * @throws SQLException if current schema cannot be determined
     */
    public Schema doGetCurrentSchema() throws SQLException;
}

CockroachDB SQL Parsing

CockroachDB-specific SQL parser that extends PostgreSQL parsing capabilities.

/**
 * CockroachDB SQL parser implementation
 */
public class CockroachDBParser extends Parser {
    /**
     * Creates a new CockroachDB parser
     * @param configuration Flyway configuration
     * @param parsingContext Parser context information
     */
    public CockroachDBParser(Configuration configuration, ParsingContext parsingContext);
}

Usage Examples:

import org.flywaydb.database.cockroachdb.CockroachDBDatabase;

// Database is typically created via CockroachDBDatabaseType.createDatabase()
CockroachDBDatabase database = (CockroachDBDatabase) flyway.getConfiguration()
    .getDatabaseType()
    .createDatabase(config, connectionFactory, interceptor);

// Check version-specific capabilities
boolean hasSchemaSupport = database.supportsSchemas(); // true for v20.2+
boolean supportsDdlTx = database.supportsDdlTransactions(); // false

// Version information
MigrationVersion version = database.getVersion();
System.out.println("CockroachDB version: " + version.getVersion());

// Table creation with CockroachDB syntax
Table historyTable = database.getTable("flyway_schema_history");
String createScript = database.getRawCreateScript(historyTable, false);
// Uses "CREATE TABLE IF NOT EXISTS" syntax

Retry Logic

CockroachDB requires special handling for transaction retries due to its distributed nature:

/**
 * CockroachDB-specific execution strategy with retry logic
 */
public class CockroachDBRetryingStrategy implements DatabaseExecutionStrategy {
    // Implementation handles CockroachDB transaction retry logic
}

/**
 * Transactional execution template with CockroachDB retry handling
 */
public class CockroachRetryingTransactionalExecutionTemplate extends ExecutionTemplate {
    /**
     * Creates retry-enabled transactional execution template
     * @param connection JDBC connection
     * @param rollbackOnException Whether to rollback on exceptions
     */
    public CockroachRetryingTransactionalExecutionTemplate(Connection connection, 
                                                           boolean rollbackOnException);
}

Version Support

Supported Versions

  • Minimum Version: CockroachDB 1.1
  • Schema Support: CockroachDB 20.2+ (schemas were introduced in this version)
  • Latest Recommended: CockroachDB 22.1+

Version Detection

// Version detection from CockroachDB system tables
// SELECT value FROM crdb_internal.node_build_info WHERE field='Version'
// or field='Tag' as fallback

// Example version strings:
// "v22.1.2" -> parsed as MigrationVersion "22.1"
// "v21.2.15" -> parsed as MigrationVersion "21.2"

Database Differences from PostgreSQL

DDL Transactions

// CockroachDB does NOT support DDL in transactions
boolean supportsDdl = database.supportsDdlTransactions(); // returns false

// This means schema changes cannot be rolled back automatically
// Each DDL statement is committed immediately

Schema Support

// Schema support is version-dependent
if (database.supportsSchemas()) {
    // CockroachDB 20.2+ supports schemas
    Schema schema = connection.getSchema("my_schema");
    schema.create();
} else {
    // Pre-20.2 versions use default schema only
    System.out.println("Schema operations not supported in this CockroachDB version");
}

Connection Management

// CockroachDB always uses multiple connections
boolean singleConnection = database.useSingleConnection(); // always false

// This is required for proper retry logic handling
// Retry operations need separate connection contexts

Migration Best Practices

Handling Retries

// CockroachDB migrations automatically handle retries
// No special code needed - handled by CockroachRetryingTransactionalExecutionTemplate

Flyway flyway = Flyway.configure()
    .dataSource("jdbc:postgresql://localhost:26257/mydb", "root", "")
    .locations("classpath:db/migration")
    .load();

// Migrations automatically retry on serialization failures
flyway.migrate();

DDL Considerations

-- Each DDL statement is auto-committed in CockroachDB
-- Good practice: Keep DDL statements atomic and independent

-- Good: Simple, atomic operations
CREATE TABLE users (id SERIAL PRIMARY KEY, name STRING);
CREATE INDEX idx_users_name ON users(name);

-- Avoid: Complex multi-step DDL in single migration
-- Better to split across multiple migration files

Schema Usage

-- For CockroachDB 20.2+
CREATE SCHEMA app_schema;
CREATE TABLE app_schema.users (id SERIAL PRIMARY KEY, name STRING);

-- For older versions, use default schema
CREATE TABLE users (id SERIAL PRIMARY KEY, name STRING);

Error Handling

// CockroachDB-specific error handling
try {
    flyway.migrate();
} catch (FlywayException e) {
    if (e.getMessage().contains("restart transaction")) {
        System.out.println("Transaction retry handled automatically");
    } else if (e.getMessage().contains("schema operations not supported")) {
        System.out.println("Upgrade CockroachDB to 20.2+ for schema support");
    }
}

Integration Example

import org.flywaydb.core.Flyway;
import org.flywaydb.database.cockroachdb.CockroachDBDatabase;

// Complete CockroachDB integration
Flyway flyway = Flyway.configure()
    .dataSource("jdbc:postgresql://localhost:26257/mycompany", "root", "")
    .locations("classpath:db/migration")
    .table("schema_version")  // Custom history table name
    .load();

// Migrate with automatic CockroachDB detection and retry handling
flyway.migrate();

// Access CockroachDB-specific functionality
CockroachDBDatabase database = (CockroachDBDatabase) flyway.getConfiguration()
    .getDatabaseType()
    .createDatabase(flyway.getConfiguration(), null, null);

System.out.println("CockroachDB version: " + database.getVersion());
System.out.println("Schema support: " + database.supportsSchemas());

Install with Tessl CLI

npx tessl i tessl/maven-org-flywaydb--flyway-database-postgresql

docs

cockroachdb-support.md

index.md

postgresql-configuration.md

postgresql-connection.md

postgresql-database.md

postgresql-parser.md

postgresql-schema.md

tile.json