Код для обратной загрузки значков

Я изучаю процесс восполнения бейджей, который происходит здесь:

https://github.com/discourse/discourse/blob/master/app/services/badge_granter.rb

В частности, следующий запрос, похоже, содержит некоторые проблемы (см. Long-Running Sidekiq Jobs):

    sql = <<~SQL
      DELETE FROM user_badges
        WHERE id IN (
          SELECT ub.id
          FROM user_badges ub
          LEFT JOIN (
            #{badge.query}
          ) q ON q.user_id = ub.user_id
          #{post_clause}
          WHERE ub.badge_id = :id AND q.user_id IS NULL
        )
    SQL

Этот запрос выполняет LEFT JOIN, поэтому все записи из user_badges будут возвращены независимо от наличия совпадений, но эта часть кажется очень запутанной:

ON q.user_id = ub.user_id
...
AND q.user_id IS NULL

Запрос соединяет строки, где user_id совпадает, но затем отбрасывает эти строки через условие WHERE, делая такое соединение бессмысленным. Поэтому я задаюсь вопросом:

  1. Какова цель функции восполнения? Похоже, она полностью удаляет обрабатываемый бейдж, а затем заново строит его целиком. Необходимо ли это?

  2. В чем разница между бейджем, который ориентирован на сообщения, и бейджем, который не ориентирован на сообщения, в контексте этой функции? При использовании LEFT JOIN имеет ли это вообще значение при поиске правильного badge_id для удаления перед повторной сборкой?

3 лайка