Closed rajnishmishra20 closed 4 years ago
@rajnishmishra20 Thanks for reporting this. Could you provide the complete stack trace entry from /storage/logs/laravel.log
? Thanks!
@rajnishmishra20 Thanks, that helps. I will try to get a fix out today or tomorrow.
@rajnishmishra20 Are you able to reproduce this in a model that doesn't use UUID?
Also, can you provide me the string value of Category::encodeUuid($uuid)
? Thanks. I am currently unable to replicate the issue using the following query:
$parents = (new Book)
->where('author_id', 1)
->with('stores')
->with('publisher')
->withCount('stores')
->get();
Hi I am \Ramsey\Uuid\Uuid for primary keys
This is Category::decodeUuid($uuid) 8eae24c5cd3a484fb95259066fa9e83f
This is Category::encodeUuid($uuid) b"Ž®$ÅÍ:HO¹RY\x06o©è?"
Hope this helps.
@rajnishmishra20 Thanks, this helps. The problem is the question mark in the ID. I will see what I can do to work around this. Hopefully I will have an update ready sometime in the next few days.
@rajnishmishra20 This should now be fixed in release 0.7.3. Could you let me know how that works for you? Thanks!
Its fine now. Thanks!
Hey Sorry to open this again but it did not work. I had MODEL_CACHE_ENABLED set to false
After enabling , same error occurs
My Query
Category::with('word')->with('contents')->with('category')->doesntHave('category')->with('packswithcontents')->simplePaginate($pages)
for a temporary access here is the url https://dev.coloursapp.com/api/content/v1/categories
protected function getInAndNotInClauses(array $where) : string
{
if (! in_array($where["type"], ["In", "NotIn", "InRaw"])) {
return "";
}
$type = strtolower($where["type"]);
$subquery = $this->getValuesFromWhere($where);
$values = collect($this->query->bindings["where"][$this->currentBinding] ?? []);
$this->currentBinding += count($where["values"]);
$subquery = preg_replace('/\?(?=(?:[^"]*"[^"]*")*[^"]*\Z)/m', "_??_", $subquery);
### $subquery = collect(vsprintf(str_replace("_??_", "%s", $subquery), $values->toArray()));
$values = $this->recursiveImplode($subquery->toArray(), "_");
return "-{$where["column"]}_{$type}{$values}";
}
Hi @rajnishmishra20, could you provide the stacktrace again, as well as the category UUIDs that cause this error? Thanks!
Just saw you added the example link, thanks for that. Inspecting the queries that are being run, the following looks odd to me:
select * from `categories` where `categories`.`id` in ('????????????????') and `categories`.`deleted_at` is null and `categories`.`deleted_at` is null
Hi may be, I found the root of problem. when ever I try to egarload a relation with another elager loaded relation all having a binary id th problem occurs.
Ex if from Category::with('word')->with('contents')->with('category')->doesntHave('category')->with('packs')->simplePaginate($pages);
Suppose ->with('packs') contains another relation on model definition of relation the problem occurs public function packs() { return $this->hasMany(Category::class, 'category_id')->with('contents'); }
if I remove ->with('contents') above it will work , else it will not.
https://dev.coloursapp.com/api/content/v1/categories link is working as changes made above.
@rajnishmishra20 I need the values that are being passed in to work around the binary data.
Some example categories
array:22 [▼ 0 => b"Ž€E6Ó\x19Jý°\x1Ak%‚®éí" 1 => b"ÄÇEâ3ÎM¦ñ┌?╬³çÅC" 2 => b"Ž€E¯{ÔJ›…\x03¨)L/òº" 3 => b"Ž€Eç?ML%µ\x1EGUY\x128«" 4 => b"Ž€F\x03\½JÚšbå.ª\x124ö" 5 => b"Ž€F›Â…E\x03’ÇÄá]4Ÿ1" 6 => b"Ž€F»JœEf˜\x1FYÌZ»óJ" 7 => b"Ž€G›{CL%½¾\x07Â@Çû¤" 8 => b"""ÄÇHVJAÅÉïƒ ¶ÌÖj""" 9 => b"Ž€IS †I:ŽrÐ\x1Fç¤Û\x13" 10 => b"Ž€K¹ë\eIc™ˆor6ÄIK" 11 => b"Ž€LS¤‡Kð’ûcº_ï\x139" 12 => b"Ž€L¨¶ôFü§pvà1À?~" 13 => b"Ž€LîlâLö™Ï÷,&ÿ\x08±" 14 => b"ÄÇM>¨NK¶ñÃh\x04Ø├gA" 15 => b"ÄäMì┴×Gù½ôWÝ\x11ES²" 16 => b"Žñ\x02\x08\x17\x00NP†o«ã\tvžt" 17 => b"Žñ\x03\x05]ðH•†7¼o…Sþ\x05" 18 => b"Žñ\x03/¡~M¨—Ó1a\x7FN`)" 19 => b"Žñ\x03[N\x1DA˼ú½¥r\x10äá" 20 => b"Žñ\x1EzÃh@{’7Î4ÿ–Á-" 21 => b"Žñ )XmN;·RÒö\x03À3c" ]
array:1 [▼ 0 => b"ÄÇEâ3ÎM¦ñ┌?╬³çÅC" ]
array:21 [▼ 0 => b"Ž€E6Ó\x19Jý°\x1Ak%‚®éí" 2 => b"Ž€E¯{ÔJ›…\x03¨)L/òº" 3 => b"Ž€Eç?ML%µ\x1EGUY\x128«" 4 => b"Ž€F\x03\½JÚšbå.ª\x124ö" 5 => b"Ž€F›Â…E\x03’ÇÄá]4Ÿ1" 6 => b"Ž€F»JœEf˜\x1FYÌZ»óJ" 7 => b"Ž€G›{CL%½¾\x07Â@Çû¤" 8 => b"""ÄÇHVJAÅÉïƒ ¶ÌÖj""" 9 => b"Ž€IS †I:ŽrÐ\x1Fç¤Û\x13" 10 => b"Ž€K¹ë\eIc™ˆor6ÄIK" 11 => b"Ž€LS¤‡Kð’ûcº_ï\x139" 12 => b"Ž€L¨¶ôFü§pvà1À?~" 13 => b"Ž€LîlâLö™Ï÷,&ÿ\x08±" 14 => b"ÄÇM>¨NK¶ñÃh\x04Ø├gA" 15 => b"ÄäMì┴×Gù½ôWÝ\x11ES²" 16 => b"Žñ\x02\x08\x17\x00NP†o«ã\tvžt" 17 => b"Žñ\x03\x05]ðH•†7¼o…Sþ\x05" 18 => b"Žñ\x03/¡~M¨—Ó1a\x7FN`)" 19 => b"Žñ\x03[N\x1DA˼ú½¥r\x10äá" 20 => b"Žñ\x1EzÃh@{’7Î4ÿ–Á-" 21 => b"Žñ )XmN;·RÒö\x03À3c" ]
Category::whereIn('id', $parents)
passing last array in $parents makes the above exception
some binary ids have """
@mikebronner, this exception happens to me frequently :-(
My models uses \Ramsey\Uuid\Uuid too. An example:
`vsprintf(): Too few arguments {"userId":15,"exception":"[object] (ErrorException(code: 0): vsprintf(): Too few arguments at /var/app/current/vendor/genealabs/laravel-model-caching/src/CacheKey.php:233) [stacktrace]
`
Thanks for the great library.
@mikebronner Sometimes the exception vsprintf(): Too few arguments and other times vsprintf(): Argument number must be greater than zero in CacheKey.php:233
It's to be used binary uuid
I made the following fix in and the problem has not recurred:
protected function getInAndNotInClauses(array $where) : string
{
if (! in_array($where["type"], ["In", "NotIn", "InRaw"])) {
return "";
}
$type = strtolower($where["type"]);
$subquery = $this->getValuesFromWhere($where);
$values = collect($this->query->bindings["where"][$this->currentBinding] ?? []);
$this->currentBinding += count($where["values"]);
if(!is_numeric($subquery) && !is_numeric(str_replace("_","",$subquery))){
try{
$subquery = \Ramsey\Uuid\Uuid::fromBytes($subquery);
$values = $this->recursiveImplode([$subquery], "_");
return "-{$where["column"]}_{$type}{$values}";
}
catch (\Exception $e){
}
}
$subquery = preg_replace('/\?(?=(?:[^"]*"[^"]*")*[^"]*\Z)/m', "_??_", $subquery);
$subquery = collect(vsprintf(str_replace("_??_", "%s", $subquery), $values->toArray()));
$values = $this->recursiveImplode($subquery->toArray(), "_");
return "-{$where["column"]}_{$type}{$values}";
}
@padre the UUID package you linked to should not be used as the primary key. However, I have added the code you recommended, as it does not break any test. Unfortunately the tests for this are very impractical. I would definitely appreciate a PR from you, if you have the time. Thanks!
Closing this for now. Please check release 0.7.4 and let me know how it works for you.
Hello,
I'm getting trouble with vsprintf
too and also using UUID as PK whatever the uuid was not the issue
Document::select()
->with('author')
->whereIn('id', function ($query) use ($args) {
return $query->from('comments')
->select('document_id')
->distinct()
->where('user_id', auth()->user()->getAuthIdentifier()) // deleting this line and works nice
->where('folder_id', $args['folder_id'])
->whereNull([
'replaced_id',
'archived_at',
'deleted_at'
]);
})
->paginate($args['limit'], [], 'page', $args['page']);
Laravel: 5.8 Model Cache: 0.5.6 (PS.: I tried the most recent version and also didn't wokt)
Stacktrace:
ERROR: vsprintf(): Too few arguments at vendor/genealabs/laravel-model-caching/src/CacheKey.php:232
[stacktrace]
#0 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(2, 'vsprintf(): Too...', '/home/edtsz/R...', 232, Array)
#1 vendor/genealabs/laravel-model-caching/src/CacheKey.php(232): vsprintf('select distinct...', Array)
#2 vendor/genealabs/laravel-model-caching/src/CacheKey.php(197): GeneaLabs\\LaravelModelCaching\\CacheKey->getInAndNotInClauses(Array)
#3 [internal function]: GeneaLabs\\LaravelModelCaching\\CacheKey->GeneaLabs\\LaravelModelCaching\\{closure}(NULL, Array)
#4 vendor/laravel/framework/src/Illuminate/Support/Collection.php(1512): array_reduce(Array, Object(Closure), NULL)
#5 vendor/genealabs/laravel-model-caching/src/CacheKey.php(201): Illuminate\\Support\\Collection->reduce(Object(Closure))
#6 vendor/genealabs/laravel-model-caching/src/CacheKey.php(40): GeneaLabs\\LaravelModelCaching\\CacheKey->getWhereClauses()
#7 vendor/genealabs/laravel-model-caching/src/Traits/Caching.php(161): GeneaLabs\\LaravelModelCaching\\CacheKey->make(Array, NULL, '-paginate_by_60...')
#8 vendor/genealabs/laravel-model-caching/src/Traits/Buildable.php(160): GeneaLabs\\LaravelModelCaching\\CachedBuilder->makeCacheKey(Array, NULL, '-paginate_by_60...')
#9 app/GraphQL/Queries/Document/DocumentsByFolderQuery.php(143): GeneaLabs\\LaravelModelCaching\\CachedBuilder->paginate(60, Array, 'page', 1)
"}
Digging into the code I realize that $values
is receiving just one of the where()
params at this line
So I decide to make a few changes:
// so I changed from vvvvvvvvvvvvvvvvvvvvvvv
// $values = collect($this->query->bindings["where"][$this->currentBinding] ?? []);
// to
$values = collect(array_slice($this->query->bindings["where"], 1, substr_count($subquery, '?')) ?? []);
after that everything seems to be running well (yet) ps.: slice starting from 1 because my query has 2 wheres and I don't know why there is a 0 in front off them. the only thing I didn't like that much is the index name:
genealabs:laravel-model-caching:mysql:prod:documents:documents:appmodelsdocument_*-sandbox_=_0-id_in_select_distinct_`document_id`_from_`comments`_where_`user_id`_=_zzzzzzzzzzzzzzzzzzzzzzz_and_`folder_id`_=_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx_and_`replaced_id`_is_null_and_`archived_at`_is_null_and_`deleted_at`_is_null-documents.deleted_at_null-mysql:prod:comments-comments.children-comments.children.user-comments.children.user.emails-comments.action-comments.events-comments.user-comments.user.emails-comments.user.organization-comments.user.organization.user-comments.link_orderBy_created_at_desc-paginate_by_60_page_1
Something weird happens here, my other environment $this->query->bindings["where"]
is correct, with just 2 indexes (my where params).. and $this->currentBinding
has 0 value.
in this case this works:
$values = collect($this->query->bindings["where"] ?? []);
@edtsz You indicate you are running Laravel 5.8. The most recent version is only compatible with Laravel 7.x. You mentioned you tried the latest version of the package, did you try it with Laravel 7?
@mikebronner while testing I tried replacing CacheKey.php
file by a new one. Everything works fine (except with more then one where). Laravel still 5.8
@edtsz Sounds good ... sorry, we don't support older versions of this package. You're welcome to fork this project and make any fixes you need on your own branch for your own purposes.
$subquery = collect(**vsprintf**(str_replace("?", "%s", $subquery), $values->toArray()));
replace to
$subquery = collect(**vsprintf**(str_replace("?", "%%s", $subquery), $values->toArray()));
Describe the bug Exception occurs when using eagerLoadRelation on Model with Cachable trait.
Eloquent Query
Stack Trace vsprintf(): Too few arguments
Environment
Model uses \Ramsey\Uuid\Uuid for primary keys