laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

Allow Schema to work with the same JSON grammar as Query #2500

Open LarsGrevelink opened 3 years ago

LarsGrevelink commented 3 years ago

We are working with Laravel's migrations and are using these to set up both our local databases (MySQL) and our testing database (SQLite). While doing so we encountered a difference between the query and schema grammar with handling JSON columns, in this case with virtual columns.

The example we ran was similar to this;

Schema::table('my_table', function (Blueprint $table) {
    $table->string('my_extracted_value')->virtualAs('json_field->extract_me');
});

Which resulted in;

alter table "my_table" add column "my_extracted_value" varchar as (json_field->extract_me)

-- Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 near ">": syntax error (SQL: alter table "my_table" add column "my_extracted_value" varchar as (json_field->extract_me))

In the current situation, the expression is left untouched. It would be great if we could use the grammar applied to queries on the schema side as well. Is there a reason it is left untouched at this point?

If that's not the case, would you be open to moving the following functions into Illuminate\Database\Grammar?

Or copy them into Illuminate\Database\Schema\Grammar? In order to handle the virtual columns similar to query related occurrences;

// Illuminate\Database\Schema\Grammars\SQLiteGrammar
protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column)
{
    if (! is_null($virtualAs = $column->virtualAs)) {
        if ($this->isJsonSelector($virtualAs)) {
            $virtualAs = $this->wrapJsonSelector($virtualAs);
        }

        return " as ({$virtualAs})";
    }
}

Would love to make a PR for this change but wanted to check whether there was an additional reason for the current functionality. If you have more locations besides the virtual columns where we should change this I would love to take this along.

Cheers!