-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Wrapped fieldname to solve SQL Error when sorting #16044
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
Conversation
Wrapped fieldname with backticks, because when the primary key of a model is a reserved word, MySql will throw an error.
I think this will break every other driver apart from MySQL? right? |
This is a fair point. Is it an idea to replace it with upsert? Replacing $model
->newModelQuery()
->whereIn($modelKeyName, array_values($order))
->update([
$orderColumn => DB::raw(
'case ' . collect($order)
->map(fn ($recordKey, int $recordIndex): string => 'when `' . $modelKeyName . '` = ' . DB::getPdo()->quote($recordKey) . ' then ' . ($recordIndex + 1))
->implode(' ') . ' end'
),
]); with $collection = collect($order)
->map(fn ($recordKey, int $recordIndex) => [$modelKeyName => $recordKey, $orderColumn => $recordIndex]);
$model->upsert($collection->toArray(), [$modelKeyName], [$orderColumn]); |
Hmm I'm not sure I've seen upsert used in this way. Maybe get the query grammar object, and then use |
Used the grammar object to wrap the field name with the proper quotes
That was my first aproach, but google sent me through the doctrine/dbal rabbit hole. I have changed the code to: $wrappedModelKeyName = DB::connection()->getSchemaGrammar()->wrap($modelKeyName); And then used the new variable in the raw SQL. I have tested it on, MySql, MariaDB, SQLite and Postgres drivers, not on SQL server as I don't have a test bench for that. |
Thanks for fixing it! |
This cause #16076 error maybe something like that would work for all? $modelKeyName = $model->getKeyName();
$wrappedModelKeyName = $model->getConnection()->getSchemaGrammar()?->wrap($modelKeyName) ?? $modelKeyName; |
@DirtyRacer1337 can you please explain the situation why a "connection" object could return a null grammar object? |
In my case and mentioned issue I'm using postgresql, maybe that's important Just checked, everything works on previous version |
What does |
Does it work if you swap |
Query Grammar not null, Schema Grammar null |
Does it work though with the query grammar? |
I'm not sure what it should return, but in my case with |
so then solution would be like $modelKeyName = $model->getKeyName();
$modelGrammar = $model->getConnection()->getSchemaGrammar() ?? $model->getConnection()->getQueryGrammar();
$wrappedModelKeyName = $modelGrammar->wrap($modelKeyName); or all together $modelKeyName = $model->getKeyName();
$modelGrammar = $model->getConnection()->getSchemaGrammar() ?? $model->getConnection()->getQueryGrammar();
$wrappedModelKeyName = $modelGrammar?->wrap($modelKeyName) ?? $modelKeyName; |
Throws error when sorting:
DB driver is PostgreSQL. |
I think we can actually remove the |
Wrapped fieldname with backticks, because when the primary key of a model is a reserved word, MySql will throw an error.
Description
When the model has a reserved word as the PK e.g.
key
sorting records will throw the following SQL error.SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key = 'cZKBUpPyUR' then 1 when key = 'EQ5zh0Eqhf' then 2 when key = 'lwmhTQ8C...' at line 1 (Connection: mysql, SQL: update
age_groups
setsort
= case when key = 'cZKBUpPyUR' then 1 when key = 'EQ5zh0Eqhf' then 2 when key = 'lwmhTQ8Cjd' then 3 when key = '0XaE8LzBZN' then 4 when key = 'tUkKkfH3P2' then 5 when keyI've added backticks around $modelKeyName on line 47 of the CanReorderRecords concern, this will solve the issue.
Visual changes
No visual changes
Functional changes
composer cs
command.