Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempting to alter a table with a column with default value (JSON_ARRAY()) by adding a foreign constraint fails with an error on SQLite #52655

Closed
lorenzolosa opened this issue Sep 5, 2024 · 3 comments · Fixed by #52678
Labels

Comments

@lorenzolosa
Copy link
Contributor

lorenzolosa commented Sep 5, 2024

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);
@driesvints
Copy link
Member

@hafezdivandari anything we can do here maybe?

@driesvints driesvints added the bug label Sep 5, 2024
@hafezdivandari
Copy link
Contributor

@driesvints I'll look into this asap.

hafezdivandari added a commit to hafezdivandari/framework that referenced this issue Sep 6, 2024
@hafezdivandari
Copy link
Contributor

You may check #52678

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants