{"id":"58de220de6e5dbee","repo":"laravel/framework","slug":"this-database-driver-does-not-support-modifying-ge","errorCode":null,"errorMessage":"This database driver does not support modifying generated columns.","messagePattern":"This database driver does not support modifying generated columns\\.","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php","lineNumber":1283,"sourceCode":"        }\n    }\n\n    /**\n     * Get the SQL for a generated virtual column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     *\n     * @throws \\LogicException\n     */\n    protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)\n    {\n        if ($column->change) {\n            if (array_key_exists('virtualAs', $column->getAttributes())) {\n                return is_null($column->virtualAs)\n                    ? 'drop expression if exists'\n                    : throw new LogicException('This database driver does not support modifying generated columns.');\n            }\n\n            return null;\n        }\n\n        if (! is_null($column->virtualAs)) {\n            return \" generated always as ({$this->getValue($column->virtualAs)}) virtual\";\n        }\n    }\n\n    /**\n     * Get the SQL for a generated stored column modifier.\n     *\n     * @param  \\Illuminate\\Database\\Schema\\Blueprint  $blueprint\n     * @param  \\Illuminate\\Support\\Fluent  $column\n     * @return string|null\n     *\n     * @throws \\LogicException","sourceCodeStart":1265,"sourceCodeEnd":1301,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php#L1265-L1301","documentation":"PostgreSQL cannot ALTER a generated virtual column to a new expression; it can only drop the expression. modifyVirtualAs() throws LogicException specifically when a change-modify operation ($column->change === true) supplies a non-null virtualAs value. Passing virtualAs(null) is allowed and emits 'drop expression if exists'.","triggerScenarios":"Using $table->string('col')->virtualAs('new_expr')->change() in a Postgres migration — i.e. trying to update an existing generated column's expression via the change() modifier. The same call with virtualAs(null)->change() succeeds (drops the expression).","commonSituations":"Refactoring a generated column's formula in Postgres; running a migration that worked on MySQL (which permits modifying generated columns) against a Postgres database; auto-sync tools that diff columns and try to change the expression.","solutions":["Drop the existing generated column and recreate it with the new expression instead of using change().","If you only want to remove the expression, call ->virtualAs(null)->change() which emits 'drop expression if exists'.","Move the expression into a view or a generated-as-identity approach if frequent changes are expected.","Confirm the target driver: this works on MySQL but not Postgres — split driver-specific migrations."],"exampleFix":"// before (throws on Postgres)\nSchema::table('orders', function (Blueprint $table) {\n    $table->integer('total')->virtualAs('price * qty')->change();\n});\n\n// after (drop then recreate)\nSchema::table('orders', function (Blueprint $table) {\n    $table->integer('total')->virtualAs(null)->change(); // drop expression\n});\nSchema::table('orders', function (Blueprint $table) {\n    $table->integer('total')\n          ->virtualAs('price * qty + tax')\n          ->change();\n});\n// cleanest: dropColumn + add the column fresh","handlingStrategy":"validation","validationCode":"// On Postgres, never change() a non-null virtualAs\nif (Schema::getConnection()->getDriverName() === 'pgsql') {\n    // drop the column and re-add it instead of ->change()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Postgres cannot modify generated expressions — only drop them via ->virtualAs(null)->change().","For formula changes, dropColumn then re-add the generated column.","Driver-split migrations that change generated columns."],"tags":["database","schema","postgres","migrations","generated-columns"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}