{"record":{"id":"f7a6eb94582a9bb3","repo":"phalcon/cphalcon","slug":"adding-a-check-constraint-to-an-existing-table-is","errorCode":null,"errorMessage":"Adding a CHECK constraint to an existing table is not supported by SQLite","messagePattern":"Adding a CHECK constraint to an existing table is not supported by SQLite","errorType":"exception","errorClass":"SqliteAlterCheckNotSupported","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Dialect/Sqlite.zep","lineNumber":93,"sourceCode":"            let sql .= \" NOT NULL\";\n        } else {\n            let sql .= \" NULL\";\n        }\n\n        if !column->isGenerated() && column->isAutoincrement() {\n            let sql .= \" PRIMARY KEY AUTOINCREMENT\";\n        }\n\n        return sql;\n    }\n\n    /**\n     * SQLite cannot ALTER an existing table to add a CHECK constraint;\n     * the constraint must be declared at CREATE TABLE time.\n     */\n    public function addCheck( string tableName,  string schemaName, <CheckInterface> check) -> string\n    {\n        throw new SqliteAlterCheckNotSupported();\n    }\n\n    /**\n     * Generates SQL to add an index to a table\n     */\n    public function addForeignKey( string tableName,  string schemaName, <ReferenceInterface> reference) -> string\n    {\n        throw new SqliteAlterForeignKeyNotSupported();\n    }\n\n    /**\n     * Generates SQL to add an index to a table\n     */\n    public function addIndex( string tableName,  string schemaName, <IndexInterface> index) -> string\n    {\n        var indexType;\n        string sql;\n","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Dialect/Sqlite.zep#L75-L111","documentation":"The SQLite dialect's addCheck() always throws SqliteAlterCheckNotSupported. SQLite has no ALTER TABLE ... ADD CONSTRAINT CHECK statement: CHECK constraints must be part of the original CREATE TABLE statement. Phalcon surfaces this engine limitation as an exception instead of emitting SQL SQLite would reject.","triggerScenarios":"Calling $sqliteAdapter->addCheck('robots', null, $check) or any migration/DDL pipeline that invokes addCheck() on an SQLite connection; running cross-database migration code written for MySQL/PostgreSQL against SQLite tests.","commonSituations":"Test suites running migrations on SQLite while production runs MySQL/Postgres; shared migration files that add CHECK constraints after table creation; CI pipelines switching the adapter to SQLite for speed.","solutions":["Declare the CHECK in createTable() using a Phalcon\\Db\\Check constraint in the definition array, so it lands in the CREATE TABLE statement","If the constraint must be added later, use SQLite's 12-step procedure: create a new table with the constraint, copy data, drop the old table, rename","Skip addCheck() on SQLite via dialect check: if (!($adapter->getDialect() instanceof Sqlite)) { $adapter->addCheck(...); }"],"exampleFix":"// before\n$connection->addCheck('robots', null, new Check('chk_price', ['price > 0']));\n\n// after — declare at CREATE TABLE time on SQLite\n$connection->createTable('robots', null, [\n    'columns' => [new Column('price', ['type' => Column::TYPE_DECIMAL, 'size' => 10, 'scale' => 2])],\n    'checks'  => [new Check('chk_price', ['price > 0'])],\n]);","handlingStrategy":"type-guard","validationCode":"if ($adapter->getDialect() instanceof \\Phalcon\\Db\\Dialect\\Sqlite) {\n    // fold the CHECK into CREATE TABLE instead of addCheck()\n    $definition['checks'] = $definition['checks'] ?? [];\n    $definition['checks'][] = $check;\n} else {\n    $adapter->addCheck($table, $schema, $check);\n}","typeGuard":"function supportsAddCheck(\\Phalcon\\Db\\Adapter\\AdapterInterface $adapter): bool\n{\n    return !($adapter->getDialect() instanceof \\Phalcon\\Db\\Dialect\\Sqlite);\n}","tryCatchPattern":"try {\n    $adapter->addCheck($table, $schema, $check);\n} catch (\\Phalcon\\Db\\Exceptions\\SqliteAlterCheckNotSupported $e) {\n    // rebuild the table with the CHECK declared inline\n    rebuildSqliteTableWithChecks($adapter, $table, [$check]);\n}","preventionTips":["Declare all CHECK constraints in createTable() when targeting SQLite","Gate ALTER-based migration steps on the dialect type","Run migrations against SQLite in CI to catch unsupported ALTERs early"],"tags":["phalcon","sqlite","ddl","check-constraint","alter-table"],"backgroundTag":"alter-table-unsupported","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}