mikebronner / laravel-model-caching

Eloquent model-caching made easy.
MIT License
2.24k stars 214 forks source link

Undefined offset: # in CacheKey getValuesFromBindings #333

Closed irvine1231 closed 4 years ago

irvine1231 commented 4 years ago

Describe the bug I get a Undefined offset: 6 error after the eloquent query called below.

Eloquent Query Please provide the complete eloquent query that caused the bug, for example:

Class::where('store_id', $store->id)->withAndWhereHas('enrollment', function ($query) use ($week_start, $week_end, $model_class_enrollment) {
    $query->whereIn('state', [$model_class_enrollment::STATE_PUBLISHED, $model_class_enrollment::STATE_BOOKABLE, $model_class_enrollment::STATE_STARTED, $model_class_enrollment::STATE_ENDED])->whereBetween('start_time', [$week_start->toDateTimeString(), $week_end->toDateTimeString()]);
})->get()

class Class extends Model
{
    public function scopeWithAndWhereHas($query, $relation, $constraint)
    {
        return $query->whereHas($relation, $constraint)
                    ->with([$relation => $constraint]);
    }
}

Stack Trace

[2020-04-13 11:52:31] local.ERROR: Undefined offset: 6 {"exception":"[object] (ErrorException(code: 0): Undefined offset: 6 at /private/var/www/project/vendor/genealabs/laravel-model-caching/src/CacheKey.php:181)
[stacktrace]
#0 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/CacheKey.php(181): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Undefined offse...', '/private/var/ww...', 181, Array)
#1 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/CacheKey.php(149): GeneaLabs\\LaravelModelCaching\\CacheKey->getValuesFromBindings(Array, '2020-04-19 15:5...')
#2 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/CacheKey.php(321): GeneaLabs\\LaravelModelCaching\\CacheKey->getValuesClause(Array)
#3 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/CacheKey.php(204): GeneaLabs\\LaravelModelCaching\\CacheKey->getOtherClauses(Array)
#4 [internal function]: GeneaLabs\\LaravelModelCaching\\CacheKey->GeneaLabs\\LaravelModelCaching\\{closure}('-classes_enroll...', Array)
#5 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Support/Collection.php(892): array_reduce(Array, Object(Closure), NULL)
#6 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/CacheKey.php(207): Illuminate\\Support\\Collection->reduce(Object(Closure))
#7 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/CacheKey.php(42): GeneaLabs\\LaravelModelCaching\\CacheKey->getWhereClauses()
#8 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/Traits/Caching.php(161): GeneaLabs\\LaravelModelCaching\\CacheKey->make(Array, NULL, '')
#9 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/Traits/Buildable.php(95): GeneaLabs\\LaravelModelCaching\\CachedBuilder->makeCacheKey(Array)
#10 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php(155): GeneaLabs\\LaravelModelCaching\\CachedBuilder->get(Array)
#11 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php(144): Illuminate\\Database\\Eloquent\\Relations\\Relation->get()
#12 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(587): Illuminate\\Database\\Eloquent\\Relations\\Relation->getEager()
#13 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(556): Illuminate\\Database\\Eloquent\\Builder->eagerLoadRelation(Array, 'enrollment', Object(Closure))
#14 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(524): Illuminate\\Database\\Eloquent\\Builder->eagerLoadRelations(Array)
#15 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/Traits/Buildable.php(290): Illuminate\\Database\\Eloquent\\Builder->get()
#16 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(418): GeneaLabs\\LaravelModelCaching\\CachedBuilder->GeneaLabs\\LaravelModelCaching\\Traits\\{closure}()
#17 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/Traits/Buildable.php(292): Illuminate\\Cache\\Repository->rememberForever('ba47b6b9c9c293d...', Object(Closure))
#18 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/Traits/Buildable.php(227): GeneaLabs\\LaravelModelCaching\\CachedBuilder->retrieveCachedValue(Array, 'genealabs:larav...', Array, 'ba47b6b9c9c293d...', 'get')
#19 /private/var/www/project/vendor/genealabs/laravel-model-caching/src/Traits/Buildable.php(97): GeneaLabs\\LaravelModelCaching\\CachedBuilder->cachedValue(Array, 'genealabs:larav...')
#20 /private/var/www/project/app/Http/Controllers/Modules/Class.php(737): GeneaLabs\\LaravelModelCaching\\CachedBuilder->get()
#21 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): App\\Http\\Controllers\\Modules\\Class->getClassListWithDate('8cfc1df9-61f3-4...', Object(Carbon\\Carbon))
#22 /private/var/www/project/app/Http/Controllers/Modules/FQDN/ClassController.php(74): Illuminate\\Support\\Facades\\Facade::__callStatic('getClassListWit...', Array)
#23 [internal function]: App\\Http\\Controllers\\Modules\\FQDN\\ClassController->list(Object(Illuminate\\Http\\Request))
#24 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): call_user_func_array(Array, Array)
#25 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction('list', Array)
#26 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/Route.php(225): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\Modules\\FQDN\\ClassController), 'list')
#27 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/Route.php(182): Illuminate\\Routing\\Route->runController()
#28 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(685): Illuminate\\Routing\\Route->run()
#29 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#30 /private/var/www/project/submodules/ppppppp/laravel-pkg-locale/src/ppppppp/LaravelPkgLocale/Middleware/LocaleRedirect.php(62): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#31 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): ppppppp\\LaravelPkgLocale\\Middleware\\LocaleRedirect->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#32 /private/var/www/project/app/Http/Middleware/FQDNWebsite.php(41): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#33 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\FQDNWebsite->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#34 /private/var/www/project/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#35 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#36 /private/var/www/project/app/Http/Middleware/TenantStartSession.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#37 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\TenantStartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#38 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#39 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#40 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(66): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#41 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#42 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#43 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(687): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#44 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(662): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#45 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(628): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#46 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Routing/Router.php(617): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#47 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(165): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#48 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#49 /private/var/www/project/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#50 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#51 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#52 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#53 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#54 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#55 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#56 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#57 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(63): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#58 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#59 /private/var/www/project/vendor/hyn/multi-tenant/src/Middleware/EagerIdentification.php(29): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#60 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Hyn\\Tenancy\\Middleware\\EagerIdentification->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#61 /private/var/www/project/vendor/hyn/multi-tenant/src/Middleware/HostnameActions.php(75): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#62 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Hyn\\Tenancy\\Middleware\\HostnameActions->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#63 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#64 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(140): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#65 /private/var/www/project/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(109): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#66 /private/var/www/project/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#67 {main}
"}

Environment

Additional context Below is the raw query triggered by the laravel eager loading. screenshot 2020-04-13 下午7 24 24

I dump out the type, subquery and query bindings in the getInAndNotInClauses function and found out that the InRaw's value is not in the query bindings so that cause the currentBinding calculation goes wrong. screenshot 2020-04-13 下午8 15 59

I add a check before adding the current binding, and it seems to work fine.

if (Str::startsWith($subquery, $values->first())) {
    $this->currentBinding += count($where["values"]);
}
mikebronner commented 4 years ago

@irvine1231 Can you confirm that this issue is now fixed? :) Thanks!

irvine1231 commented 4 years ago

@mikebronner Yes, it has been fixed, tested with the 0.8.2 version two days ago. :)

mikebronner commented 4 years ago

@irvine1231 Awesome!