Столкнулись с проблемой разного поведения MySql и MariaDB (sqlmode => TRADITIONAL) для кода:
$products = $collection->getProducts('id', $offset, $count);
Для теста берем стандартную "чистую" установку SS 8.22.x или SS 9.0.5 с автозаполением товарами через мастер (мобльные, планшеты и т.п.). В списке категорий есть
+Мобильные телефоны
- Apple(4)
- Samsung(4)
- Nokia (4)
Берем и добавляем новую подкатегорию Яблоки ( type=0 ) с родителем "Мобильные телефоны" и в нее добавляем товары из Apple, пока все хорошо.
После чего начинается магия для кода:
$collection = new shopProductsCollection($product_ids, [no_plugins => true]);
...
$products = $collection->getProducts('id', $offset, $count);
Внутри вызывается примерно такой sql:
SELECT p.id FROM shop_product p JOIN shop_category_products cp1 ON p.id = cp1.product_id WHERE cp1.category_id IN(1,2,4,6,2260) GROUP BY cp1.sort, p.id ORDER BY cp1.sort ASC, p.id LIMIT 12
Где 2260 это ID y=нашей созданной категории Яблоки
И вот тут на MySql все ок:
63
67
71
64
62
72
65
69
73
66
70
74
, а на MariaDB результат совершенно другой
63
67
68
71
64
68
69
72
65
69
70
73
т.е. появились дубли 68, 69 и в результат не попали нужные id.
Лечится или DISTINCT() или заменой GROUP BY cp1.sort, p.id на GROUP BY p.id. Но это все внутри коллекции shopProductsCollection поэтому надо менять код там.
Есть предложения как это обойти (может подкрутить настройки sql сервера для MariaDB)?
Или все же это баг коллекции и надо ждать решения от разработчиков Shop-Script?
20 комментариев
После каких конкретно действий она начинается?
Лучше точно, а не примерно. Иначе трудно анализировать ваше сообщение об ошибке.
Михаил, в плагине который реагирует на стандартный хук при сохранении категории вызывается код
т.е. ничего сверхъестественного, просто запрос к коллекции.
Далее дается перехваченный SQL, сформированный коллекцией.
"Примерный" , потому что на стенде у проверяющего могут быть другие id категорий != 2260, а какие то свои.
Сам запрос SQL полностью такой как формирует shopProductsCollection.
в shopProductsCollection есть 2 места
и
которые надо изменить, чтобы решить проблему с MariaDB (и думается это второе условие для GROUP BY).
ты об этом запросе?
если так то чем какая-то чушь - DISTINCT аналогичен GROUP BY(рекомендуется использовать GROUP BY т.к. DISTINCT это mysql расширение)
А кто тебе сказал что они должны работать одинаково? "совместимы" не тоже самое что "идентичны"/"аналогичны". Базовое руководство:
в данном случае проблема в том, что разработчик не понимает/не знает разницу между
Это ладно. Вот зачем ВА группирует по значению сортировки (cp1.sort) -- никак не могу сообразить.
без этого запрос работать не будет: если поле не указано в group by, то оно не попадет и в последующий order by
вернее будет, но только если не используется sql_model only_full_group_by
sqlmode => TRADITIONAL не влияет на запросы (т.е. SELECT)
Эта часть в запросе значит, что вы формируете коллекцию из товаров, содержащихся в некоторой категории и вложенных в неё подкатегориях, и при этом пытаетесь применять значение сортировки «вручную» (настроенное путём перетаскивания товаров в категории)?
Но при отображении внутри категории товаров из вложенных подкатегорий сортировка, настроенная вручную, не может осмысленно работать — такая логика в Shop-Script никогда не закладывалась (пока что).
Проверьте — возможно, что-то не так в вашей логике формирования коллекции.
Вот еще пример утрированного кода, который вызывает данный баг при сохранении категории:
нужны товары именно всей родительской категории и подкатегорий. Получается он ломает коллекцию для MariaDB и обойти условие
по ветке else не получается т.к. нет "защиты от дурака", если у родителя стоит ручная сортировка и включена настройка "Включить товары из подкатегорий".
Тут явно надо доработать:
Хорошо если это вскоре появится в обновлениях, но нам то как быть в этом случае? Не видим механизма обхода без явных хаков, к которым бы не хотелось прибегать.
Средствами интерфейса Shop-Script такое сочетание настроек выбрать не получается, насколько в вижу. Если у вас получается, расскажите, как этого можно добиться.
Хах, сюрприз - тестовая база с товарами "из коробки" вся содержит взаимоисключающие условия. А тест с багами полностью на ней делали.
Поправьте хотя бы ее, чтобы на такое не попадать больше. С остальным тогда разберемся. И возможно в cron, который repair DB делает, тоже исправления внести для категорий с включенным параметром "Включить товары из подкатегорий" для пустых sort_products присвоить сортировку.
Спасибо!
Михаил, все же баг остался для категорий родителей у кого включена ручная сортировка и есть товары, которые принадлежат родителю (из практике такое часто может быть, когда в категорию накидали товары, а потом начали дробить на дочерние) SQL на MariaDB все равно остается невалидным из-за
Но в этом случае исключены дубли и код вернет желаемые 4 элемента.
Ну и проблему с взаимоисключающими параметрами на старых сайтах никто не исключал.
Заметил еще, что некоторые плагины импорта из XML/YML грешат такими багами.
И может все же в коллекции условие
надо заменить на
Не улавливаю, что вы тут имеете в виду. Приведите пример для этого случая:
Ну для этого случая, что описал МарияДБ вернет такой же результат, что и MySQL, т.к в этом примере не будет дублей товаров при выключенном параметре показа товаров дочерних категорий.
Но вот если вернуться к предыдущим примерам:
порождает серию SQL-запросов, среди которых
и
и если убрать LIMIT 12
То на удивление число элементов будет больше чем 12, т.к. МарияДБ вернет результат с дублями (на тестовом стенде 19 элементов вернул).
Т.е.
учитывает DISTINCT
а
в МарииДБ не сохраняет уникальность p.id в запросе
Поэтому есть подозрение, что для общего теоретиского случая вызова (не проверял на тестовом стенде)
если товары повторяются внутри категорий
и есть сортировка Вручную, то будут снова проблемы для
из-за дублей p.id в результате, т.к. ожидаю получить
элементов, но получив это количество результат будет с дублями и часть уникальных id просто не будет учтено.
Давайте обсуждать конкретные практические случаи. Если проблема не возникает на практике в магазинах, настроенных стандартным образом, боюсь, мы не можем тратить ресурсы на её «исправление», рискуя что-то сломать в работающих магазинах.
Исправим, спасибо!
Настройки категорий в демонстрационной базе товаров исправили. Сообщите, пожалуйста, если вдруг снова столкнётесь с этой проблемой.