phalcon/cphalcon · error · Phalcon\Db\Exceptions\SqliteDropCheckNotSupported

Dropping a CHECK constraint is not supported by SQLite

Error message

Dropping a CHECK constraint is not supported by SQLite

What it means

Phalcon\Db\Dialect\Sqlite::dropCheck() always throws SqliteDropCheckNotSupported. SQLite has no ALTER TABLE ... DROP CONSTRAINT statement — a CHECK constraint can only be removed by recreating the table — so the dialect refuses to generate SQL instead of emitting a statement the engine would reject.

Source

Thrown at phalcon/Db/Dialect/Sqlite.zep:366

     * Generates SQL to delete a column from a table.
     *
     * SQLite 3.35+ supports `ALTER TABLE ... DROP COLUMN ...` directly. On
     * older versions the server rejects the statement at execution time;
     * cphalcon no longer pre-empts that rejection at the dialect level so
     * callers on 3.35+ can use the feature.
     */
    public function dropColumn( string tableName,  string schemaName,  string columnName) -> string
    {
        return "ALTER TABLE " . this->prepareTable(tableName, schemaName)
            . " DROP COLUMN \"" . columnName . "\"";
    }

    /**
     * SQLite cannot DROP a CHECK constraint from an existing table.
     */
    public function dropCheck( string tableName,  string schemaName,  string checkName) -> string
    {
        throw new SqliteDropCheckNotSupported();
    }

    /**
     * Generates SQL to delete a foreign key from a table
     */
    public function dropForeignKey( string tableName,  string schemaName,  string referenceName) -> string
    {
        throw new SqliteDropForeignKeyNotSupported();
    }

    /**
     * Generates SQL to delete an index from a table
     */
    public function dropIndex( string tableName,  string schemaName,  string indexName) -> string
    {
        if schemaName {
            return "DROP INDEX \"" . schemaName . "\".\"" . indexName . "\"";
        }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Gate the call on the dialect: skip dropCheck() when $connection->getDialectType() === 'sqlite'
  2. Emulate with the SQLite table-rebuild procedure: create a new table without the CHECK, copy the rows, drop the old table, rename the new one
  3. Move the constraint drop into a migration tagged for databases that support it (MySQL/PostgreSQL)

Example fix

// before
$connection->dropCheck('posts', 'chk_title');

// after
if ($connection->getDialectType() !== 'sqlite') {
    $connection->dropCheck('posts', 'chk_title');
}
// on SQLite, rebuild the table instead of dropping the CHECK
Defensive patterns

Strategy: try-catch

Validate before calling

if ($connection->getDialectType() !== 'sqlite') {
    $connection->dropCheck('posts', 'chk_title');
}

Try / catch

try {
    $connection->dropCheck('posts', 'chk_title');
} catch (\Phalcon\Db\Exceptions\SqliteDropCheckNotSupported $e) {
    // SQLite cannot drop CHECK constraints; rebuild the table or skip
    $logger->info('Skipped dropCheck on SQLite', ['table' => 'posts']);
}

Prevention

When it happens

Trigger: Running shared migration code that calls $connection->dropCheck('posts', 'chk_title') while the connection's dialect is Sqlite; re-applying constraint changes uniformly across MySQL/PostgreSQL and SQLite environments.

Common situations: CI suites running migrations against an in-memory SQLite database; multi-database applications reusing MySQL migrations; scaffolding tools that introspect and re-apply constraints identically on every dialect.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/f10b741e1801f05a. Report an issue: GitHub.