tursodatabase / turso-driver-laravel

Turso Driver for Laravel with Native libSQL
https://turso.tech/sdk/php/guides/laravel
MIT License
59 stars 6 forks source link

[Bug]: This database engine does not support JSON operations. #9

Closed ineersa closed 2 months ago

ineersa commented 2 months ago

What happened?

I've got quite interesting error, even tho it should support JSON operations.

The problem is that we use incorrect grammar for queries when we use Eloquent models.

Stacktrace:

[2024-07-08 15:29:29] local.ERROR: This database engine does not support JSON operations. {"userId":1,"exception":"[object] (RuntimeException(code: 0): This database engine does not support JSON operations. at /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Grammar.php:166)
[stacktrace]
#0 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Grammar.php(94): Illuminate\\Database\\Grammar->wrapJsonSelector()
#1 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(296): Illuminate\\Database\\Grammar->wrap()
#2 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(253): Illuminate\\Database\\Query\\Grammars\\Grammar->whereBasic()
#3 [internal function]: Illuminate\\Database\\Query\\Grammars\\Grammar->Illuminate\\Database\\Query\\Grammars\\{closure}()
#4 /var/www/notes/vendor/laravel/framework/src/Illuminate/Collections/Arr.php(605): array_map()
#5 /var/www/notes/vendor/laravel/framework/src/Illuminate/Collections/Collection.php(759): Illuminate\\Support\\Arr::map()
#6 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(252): Illuminate\\Support\\Collection->map()
#7 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(237): Illuminate\\Database\\Query\\Grammars\\Grammar->compileWheresToArray()
#8 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(540): Illuminate\\Database\\Query\\Grammars\\Grammar->compileWheres()
#9 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(253): Illuminate\\Database\\Query\\Grammars\\Grammar->whereNested()
#10 [internal function]: Illuminate\\Database\\Query\\Grammars\\Grammar->Illuminate\\Database\\Query\\Grammars\\{closure}()
#11 /var/www/notes/vendor/laravel/framework/src/Illuminate/Collections/Arr.php(605): array_map()
#12 /var/www/notes/vendor/laravel/framework/src/Illuminate/Collections/Collection.php(759): Illuminate\\Support\\Arr::map()
#13 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(252): Illuminate\\Support\\Collection->map()
#14 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(237): Illuminate\\Database\\Query\\Grammars\\Grammar->compileWheresToArray()
#15 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(114): Illuminate\\Database\\Query\\Grammars\\Grammar->compileWheres()
#16 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php(88): Illuminate\\Database\\Query\\Grammars\\Grammar->compileComponents()
#17 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2876): Illuminate\\Database\\Query\\Grammars\\Grammar->compileSelect()
#18 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2994): Illuminate\\Database\\Query\\Builder->toSql()
#19 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2978): Illuminate\\Database\\Query\\Builder->runSelect()
#20 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3566): Illuminate\\Database\\Query\\Builder->Illuminate\\Database\\Query\\{closure}()
#21 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2977): Illuminate\\Database\\Query\\Builder->onceWithColumns()
#22 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(748): Illuminate\\Database\\Query\\Builder->get()
#23 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(730): Illuminate\\Database\\Eloquent\\Builder->getModels()
#24 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php(335): Illuminate\\Database\\Eloquent\\Builder->get()
#25 /var/www/notes/vendor/spatie/laravel-tags/src/Tag.php(78): Illuminate\\Database\\Eloquent\\Builder->first()
#26 /var/www/notes/vendor/spatie/laravel-tags/src/Tag.php(95): Spatie\\Tags\\Tag::findFromString()
#27 /var/www/notes/vendor/spatie/laravel-tags/src/Tag.php(57): Spatie\\Tags\\Tag::findOrCreateFromString()
#28 [internal function]: Spatie\\Tags\\Tag::Spatie\\Tags\\{closure}()
#29 /var/www/notes/vendor/laravel/framework/src/Illuminate/Collections/Arr.php(605): array_map()
#30 /var/www/notes/vendor/laravel/framework/src/Illuminate/Collections/Collection.php(759): Illuminate\\Support\\Arr::map()
#31 /var/www/notes/vendor/spatie/laravel-tags/src/Tag.php(52): Illuminate\\Support\\Collection->map()
#32 /var/www/notes/vendor/spatie/laravel-tags/src/HasTags.php(171): Spatie\\Tags\\Tag::findOrCreate()
#33 /var/www/notes/vendor/spatie/laravel-tags/src/HasTags.php(45): App\\Models\\Note->attachTags()
#34 /var/www/notes/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(458): App\\Models\\Note::Spatie\\Tags\\{closure}()
#35 /var/www/notes/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(286): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}()
#36 /var/www/notes/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(266): Illuminate\\Events\\Dispatcher->invokeListeners()
#37 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php(215): Illuminate\\Events\\Dispatcher->dispatch()
#38 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1324): Illuminate\\Database\\Eloquent\\Model->fireModelEvent()
#39 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1142): Illuminate\\Database\\Eloquent\\Model->performInsert()
#40 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(1068): Illuminate\\Database\\Eloquent\\Model->save()
#41 /var/www/notes/vendor/laravel/framework/src/Illuminate/Support/helpers.php(380): Illuminate\\Database\\Eloquent\\Builder->Illuminate\\Database\\Eloquent\\{closure}()
#42 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(1067): tap()
#43 /var/www/notes/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(23): Illuminate\\Database\\Eloquent\\Builder->create()
#44 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2340): Illuminate\\Database\\Eloquent\\Model->forwardCallTo()
#45 /var/www/notes/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2352): Illuminate\\Database\\Eloquent\\Model->__call()
#46 /var/www/notes/app/Services/NotesService.php(17): Illuminate\\Database\\Eloquent\\Model::__callStatic()
#47 /var/www/notes/resources/views/livewire/pages/notes/form.blade.php(57): App\\Services\\NotesService->createNote()
#48 /var/www/notes/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Livewire\\Volt\\Component@anonymous->submit()
#49 /var/www/notes/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#50 /var/www/notes/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\\Container\\Util::unwrapIfClosure()
#51 /var/www/notes/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod()
#52 /var/www/notes/vendor/livewire/livewire/src/Wrapped.php(23): Illuminate\\Container\\BoundMethod::call()
#53 /var/www/notes/vendor/livewire/livewire/src/Mechanisms/HandleComponents/HandleComponents.php(474): Livewire\\Wrapped->__call()
#54 /var/www/notes/vendor/livewire/livewire/src/Mechanisms/HandleComponents/HandleComponents.php(101): Livewire\\Mechanisms\\HandleComponents\\HandleComponents->callMethods()
#55 /var/www/notes/vendor/livewire/livewire/src/LivewireManager.php(97): Livewire\\Mechanisms\\HandleComponents\\HandleComponents->update()
#56 /var/www/notes/vendor/livewire/volt/src/LivewireManager.php(35): Livewire\\LivewireManager->update()
#57 /var/www/notes/vendor/livewire/livewire/src/Mechanisms/HandleRequests/HandleRequests.php(93): Livewire\\Volt\\LivewireManager->update()
#58 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(46): Livewire\\Mechanisms\\HandleRequests\\HandleRequests->handleUpdate()
#59 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/Route.php(260): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#60 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/Route.php(206): Illuminate\\Routing\\Route->runController()
#61 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/Router.php(806): Illuminate\\Routing\\Route->run()
#62 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#63 /var/www/notes/app/Http/Middleware/SetUserDatabase.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#64 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\SetUserDatabase->handle()
#65 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#66 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#67 /var/www/notes/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(88): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#68 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#69 /var/www/notes/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#70 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#71 /var/www/notes/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#72 /var/www/notes/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#73 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Session\\Middleware\\StartSession->handle()
#74 /var/www/notes/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#75 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#76 /var/www/notes/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(75): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#77 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#78 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#79 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/Router.php(805): Illuminate\\Pipeline\\Pipeline->then()
#80 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/Router.php(784): Illuminate\\Routing\\Router->runRouteWithinStack()
#81 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/Router.php(748): Illuminate\\Routing\\Router->runRoute()
#82 /var/www/notes/vendor/laravel/framework/src/Illuminate/Routing/Router.php(737): Illuminate\\Routing\\Router->dispatchToRoute()
#83 /var/www/notes/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\\Routing\\Router->dispatch()
#84 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#85 /var/www/notes/vendor/livewire/livewire/src/Features/SupportDisablingBackButtonCache/DisableBackButtonCacheMiddleware.php(19): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#86 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Livewire\\Features\\SupportDisablingBackButtonCache\\DisableBackButtonCacheMiddleware->handle()
#87 /var/www/notes/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(66): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#88 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle()
#89 /var/www/notes/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#90 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#91 /var/www/notes/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(47): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#92 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#93 /var/www/notes/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#94 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\ValidatePostSize->handle()
#95 /var/www/notes/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#96 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#97 /var/www/notes/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#98 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\HandleCors->handle()
#99 /var/www/notes/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#100 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\TrustProxies->handle()
#101 /var/www/notes/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#102 /var/www/notes/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\\Pipeline\\Pipeline->then()
#103 /var/www/notes/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#104 /var/www/notes/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1183): Illuminate\\Foundation\\Http\\Kernel->handle()
#105 /var/www/notes/public/index.php(17): Illuminate\\Foundation\\Application->handleRequest()
#106 {main}
"} 

As you can see we are using default grammar, instead of LibSQLQueryGrammar.

Why this is happening?

When we try to query from model method \Illuminate\Database\Eloquent\Model::newBaseQueryBuilder will be called, which would call connection->query() method.

This will call base method for connection since in https://github.com/tursodatabase/turso-driver-laravel/blob/main/src/Database/LibSQLConnection.php we are not changing default grammar and not rewrituing method.

How to reproduce the bug

Create new model. Set model connection to libsql

protected $connection = 'libsql_name_connection';

Add JSON column in model. Try to create new model.

Package Version

latest

PHP Version

8.3.8

Laravel Version

11

Which operating systems does with happen with?

Linux

Notes

No response

ineersa commented 2 months ago

I'll make PR later for this issue, I've fixed it in https://github.com/ineersa/turso-driver-laravel/tree/fix-grammar