The $conditions parameter on the entity loader was deprecated 6 years ago, but for some reason Commerce was never updated to use EntityFieldQuery in its place instead. This has been alright as far as it goes - it seemed the change was largely cosmetic, a means to stop developers from requesting increasingly greater support through the $conditions parameter.
However, within Commerce itself, this causes an issue when product SKUs are near identical - if you attempt to load products by the SKUs '12345' and '012345', the entity loader will return the cached value from the first load to the second load request.
Since this is a deprecated core feature, let's just update all of our functions to drop using that parameter and use EFQs instead. This will result in an extra load, unfortunately, but one thing we can do is update commerce_product_load_by_sku() to first manually check the product cache for pre-loaded products using an identical operator to compare cached SKUs against the requested SKU.
Comments
Comment #2
nullkernel CreditAttribution: nullkernel commentedI've recently been affected by this bug. So far, I've written test cases that reproduce the problem. Attaching a patch with the test cases.
The patch will fail at this time (due to test failures), but the test cases can be used to prove correctness of commerce_product_load_by_sku() moving forward.
Comment #4
nullkernel CreditAttribution: nullkernel commentedThe problem isn't limited to static cache. The test failures in my previous patch happened with static cache bypassed ($reset parameter set to TRUE). The entity loader is basically generating "sku IN" SQL, and does not use quotes when the SKU is an integer. At least for MySQL, the following queries have different results:
I've updated my testcases patch and attached it along with an interdiff. This patch will generate more failures with the current codebase. Key changes include:
Using EntityFieldQuery instead of entity loader $conditions should resolve these test failures. Careful matching of the cache key also needs to happen.
Comment #6
nullkernel CreditAttribution: nullkernel commentedI've patched function commerce_product_load_by_sku() to use EntityFieldQuery instead of commerce_product_load_multiple(). All test cases should pass now. When testing locally, all 72 out of 72 assertions pass. With the existing implementation there were 15 failed assertions with the patch I uploaded in my previous comment (#4). I realize I got my comment number wrong in my last patch's filename - sorry about that.