{"record":{"id":"38e3992dc6a164af","repo":"phalcon/cphalcon","slug":"altering-a-db-column-is-not-supported-by-sqlite","errorCode":null,"errorMessage":"Altering a DB column is not supported by SQLite","messagePattern":"Altering a DB column is not supported by SQLite","errorType":"exception","errorClass":"Phalcon\\Db\\Exceptions\\SqliteAlterColumnNotSupported","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Dialect/Sqlite.zep","lineNumber":656,"sourceCode":"    public function listTables(string schemaName = null) -> string\n    {\n        return \"SELECT tbl_name FROM sqlite_master WHERE type = 'table' ORDER BY tbl_name\";\n    }\n\n    /**\n     * Generates the SQL to list all views of a schema or user\n     */\n    public function listViews( string schemaName = null) -> string\n    {\n        return \"SELECT tbl_name FROM sqlite_master WHERE type = 'view' ORDER BY tbl_name\";\n    }\n\n    /**\n     * Generates SQL to modify a column in a table\n     */\n    public function modifyColumn( string tableName,  string schemaName, <ColumnInterface> column, <ColumnInterface> currentColumn = null) -> string\n    {\n        throw new SqliteAlterColumnNotSupported();\n    }\n\n    /**\n     * Appends a `RETURNING` clause to the supplied INSERT/UPDATE/DELETE\n     * statement. Supported by SQLite 3.35+. Pass `[\"*\"]` for `RETURNING *`,\n     * or a list of column names.\n     */\n    public function returning( string sqlQuery,  array columns) -> string\n    {\n        var first;\n\n        if unlikely empty columns {\n            throw new ReturningRequiresColumn();\n        }\n\n        if count(columns) == 1 {\n            let first = (string) columns[0];\n","sourceCodeStart":638,"sourceCodeEnd":674,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Dialect/Sqlite.zep#L638-L674","documentation":"Phalcon\\Db\\Dialect\\Sqlite::modifyColumn() always throws SqliteAlterColumnNotSupported. SQLite offers no ALTER TABLE ... MODIFY/ALTER COLUMN statement — changing a column's type or size requires the create-new-table / copy / drop / rename procedure — so the dialect refuses rather than emitting invalid SQL.","triggerScenarios":"Generic migration code calling $connection->modifyColumn('posts', null, new Column('title', ['type' => Column::TYPE_VARCHAR, 'size' => 500])) against a SQLite connection; migration sets written against MySQL being replayed on SQLite in tests.","commonSituations":"Dev/test environments on SQLite while production runs MySQL/PostgreSQL; scaffolding tools generating uniform ALTER steps for every dialect; widening varchar columns — a routine MySQL migration that cannot map to SQLite.","solutions":["Branch on $connection->getDialectType() === 'sqlite' and use the rebuild procedure instead","Rebuild: CREATE TABLE posts_new with the modified column, INSERT INTO posts_new SELECT * FROM posts, DROP TABLE posts, ALTER TABLE posts_new RENAME TO posts","Batch incompatible column changes into one rebuild per table to avoid repeated copies"],"exampleFix":"// before\n$connection->modifyColumn('posts', null, new Column('title', ['type' => Column::TYPE_VARCHAR, 'size' => 500]));\n\n// after\nif ($connection->getDialectType() === 'sqlite') {\n    $connection->execute('CREATE TABLE posts_new (...)');\n    $connection->execute('INSERT INTO posts_new SELECT * FROM posts');\n    $connection->execute('DROP TABLE posts');\n    $connection->execute('ALTER TABLE posts_new RENAME TO posts');\n} else {\n    $connection->modifyColumn('posts', null, new Column('title', ['type' => Column::TYPE_VARCHAR, 'size' => 500]));\n}","handlingStrategy":"try-catch","validationCode":"if ($connection->getDialectType() === 'sqlite') {\n    // rebuild: create posts_new with the modified column, copy, drop, rename\n} else {\n    $connection->modifyColumn('posts', null, $newColumn);\n}","typeGuard":null,"tryCatchPattern":"try {\n    $connection->modifyColumn('posts', null, $newColumn);\n} catch (\\Phalcon\\Db\\Exceptions\\SqliteAlterColumnNotSupported $e) {\n    // SQLite has no ALTER COLUMN; run the table-rebuild procedure instead\n    rebuildSqliteTable($connection, 'posts', $newDefinition);\n}","preventionTips":["Route every column modification through a dialect-aware migration helper","Batch multiple column changes into one SQLite table rebuild","Run migrations on SQLite in CI so unsupported alters fail early"],"tags":["sqlite","phalcon-db","ddl","alter-column","unsupported-operation","migrations"],"backgroundTag":"sqlite-alter-limitation","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}