В проекте, над которым я работаю, используется MySQL на RDS (специально для mysql2).
Когда я использую хэш условий, включая диапазон в выражении where
, я получаю немного странное дополнение к моему запросу.
User.where(id: [1..5])
и
User.where(id: [1...5])
Результат в следующих запросах соответственно:
SELECT `users`.* FROM `users` WHERE ((`users`.`id` BETWEEN 1 AND 5 OR 1=0))
SELECT `users`.* FROM `users` WHERE ((`users`.`id` >= 1 AND `users`.`id` < 5 OR 1=0))
Запросы отлично работают, поскольку OR FALSE
фактически не работает. Мне просто интересно, почему Rails или ARel добавляют этот фрагмент в запрос.
ИЗМЕНИТЬ
Похоже, что строка, которая может объяснить это, строка 26 в ActiveRecord::PredicateBuilder
. По-прежнему не знаю, как хэш может быть empty?
в этот момент, но, возможно, кто-то другой делает.
EDIT 2
Это интересно. Я смотрел на комментарий Филиппа, чтобы понять, почему он сделал это, так как это похоже на разъяснение, но он прав, что 1..5 != [1..5]
. Первый является инклюзивным диапазоном от 1 до 5, где последний является массивом, первым элементом которого является первый. Я попытался поместить их в вызов ARel where
, чтобы увидеть произведенный SQL и OR 1=0
не существует!
User.where(id: 1..5) #=> SELECT "users".* FROM "users" WHERE ("users"."id" BETWEEN 1 AND 5)
User.where(id: 1...5) #=> SELECT "users".* FROM "users" WHERE ("users"."id" >= 1 AND "users"."id" < 5)
Пока я до сих пор не знаю, почему AREL добавляет OR 1=0
, который всегда будет ложным и, казалось бы, ненужным. Это может быть связано с тем, как Array
и Range
обрабатываются по-разному.