- Notifications
You must be signed in to change notification settings - Fork 11.7k
Description
Laravel Version
11.22.0
PHP Version
8.3.6
Database Driver & Version
SQLite 3.45.1 for Linux on amd64
Description
In Laravel 11.15.0, #51373 introduced the ability to add / drop foreign keys in SQLite, by re-creating the table and copying all data.
However, I run into an error when the table being altered includes a JSON column with JSON_ARRAY() as default value. The error is something like:
SQLSTATE[HY000]: General error: 1 near "(": syntax error (Connection: sqlite, SQL: create table "__temp__items" ("id" integer primary key autoincrement not null, "flags" text not null default JSON_ARRAY(), "item_id" integer, foreign key("item_id") references "items"("id")))
The issue is that the SQL query the column definition should be something like "column_name" text not null default (JSON_ARRAY())), while the query executed has "flags" text not null default JSON_ARRAY()) (without the brackets). This results in a syntax error.
Steps To Reproduce
Create a table with a JSON column with (JSON_ARRAY()) as default value:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('items', function (Blueprint $table) { $table->id(); $table->json('flags')->default(new Expression('(JSON_ARRAY())')); }); } };Alter the table to add a foreign key constraint:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up(): void { Schema::table('items', function (Blueprint $table) { $table->foreignId('item_id')->nullable(); $table->foreign('item_id') ->references('id') ->on('items'); } }Running the second migration results in an error like:
SQLSTATE[HY000]: General error: 1 near "(": syntax error (Connection: sqlite, SQL: create table "__temp__items" ("id" integer primary key autoincrement not null, "flags" text not null default JSON_ARRAY(), "item_id" integer, foreign key("item_id") references "items"("id")))
Under the hood, the first migration execute the following SQL statement:
create table "items" ("id" integer primary key autoincrement not null, "flags" text not null default (JSON_ARRAY()))while the second migration executes:
create table "__temp__items" ("id" integer primary key autoincrement not null, "flags" text not null default JSON_ARRAY(), "item_id" integer, foreign key("item_id") references "items"("id"))"The issue is that the second statement includes JSON_ARRAY() instead of (JSON_ARRAY()).
As a comparison, manually running the .schema items in SQLite we get:
sqlite> .schema items CREATE TABLE IF NOT EXISTS "items" ("id" integer primary key autoincrement not null, "flags" text not null default (JSON_ARRAY()), "item_id" integer);