Incorrect SELECT query generation including "LIMIT" clause and "M:N" association with "where" clause returns unexpected results
See original GitHub issueHello,
I’ve come across a bug with query generation which include limiting results with including belongsToMany
relation containing WHERE
clause.
I made executable script to demonstrate this behavior as they are cases when generated query might return expected result if query and data in database are in specific state.
if you investigate the file the following are queries generated for particular demonstration cases:
“Test 1”: Works
Student.findAndCount({
offset: 6,
order: [["id", "DESC"]],
include: [
{
model: Teacher,
as: 'teachers',
where: {
id: {$in: [3, 2]}
}
}
]
});
SELECT "student"."id", "student"."age", "student"."name",
"student"."created_at", "student"."updated_at", "teachers"."id" AS
"teachers.id", "teachers"."age" AS "teachers.age", "teachers"."name" AS
"teachers.name", "teachers"."created_at" AS "teachers.created_at",
"teachers"."updated_at" AS "teachers.updated_at",
"teachers.student_teacher"."id" AS "teachers.student_teacher.id",
"teachers.student_teacher"."teacher_id" AS
"teachers.student_teacher.teacher_id", "teachers.student_teacher"."student_id"
AS "teachers.student_teacher.student_id"
FROM "student" AS "student"
INNER JOIN (
"student_teacher" AS "teachers.student_teacher"
INNER JOIN "teacher" AS "teachers"
ON "teachers"."id" = "teachers.student_teacher"."teacher_id"
)
ON "student"."id" = "teachers.student_teacher"."student_id"
AND "teachers"."id" IN (3, 2)
ORDER BY "student"."id" DESC OFFSET 6;
“Test 2”: Bug - Wrong query generated… but this case returns expected result by “coincidence”
Student.findAndCount({
limit: 5,
offset: 6,
order: [["id", "DESC"]],
include: [
{
model: Teacher,
as: 'teachers',
where: {
id: {$in: [3, 2]}
}
}
]
});
SELECT "student".*, "teachers"."id" AS "teachers.id", "teachers"."age" AS
"teachers.age", "teachers"."name" AS "teachers.name", "teachers"."created_at"
AS "teachers.created_at", "teachers"."updated_at" AS "teachers.updated_at",
"teachers.student_teacher"."id" AS "teachers.student_teacher.id",
"teachers.student_teacher"."teacher_id" AS
"teachers.student_teacher.teacher_id", "teachers.student_teacher"."student_id"
AS "teachers.student_teacher.student_id"
FROM (
SELECT "student"."id", "student"."age", "student"."name",
"student"."created_at", "student"."updated_at"
FROM "student" AS "student"
WHERE (
SELECT "student_teacher"."id"
FROM "student_teacher" AS "student_teacher"
INNER JOIN "teacher" AS "teacher"
ON "student_teacher"."teacher_id" = "teacher"."id"
WHERE ("student"."id" = "student_teacher"."student_id")
LIMIT 1
) IS NOT NULL
ORDER BY "student"."id" DESC LIMIT 5 OFFSET 6
) AS "student"
INNER JOIN (
"student_teacher" AS "teachers.student_teacher"
INNER JOIN "teacher" AS "teachers"
ON "teachers"."id" = "teachers.student_teacher"."teacher_id"
)
ON "student"."id" = "teachers.student_teacher"."student_id"
AND "teachers"."id" IN (3, 2)
ORDER BY "student"."id" DESC;
“Test 3”: Bug - Wrong query - returns unexpected results
Student.findAndCount({
limit: 5,
offset: 6,
include: [
{
model: Teacher,
as: 'teachers',
where: {
id: {$in: [3, 2]}
}
}
]
});
SELECT "student".*, "teachers"."id" AS "teachers.id", "teachers"."age" AS
"teachers.age", "teachers"."name" AS "teachers.name", "teachers"."created_at"
AS "teachers.created_at", "teachers"."updated_at" AS "teachers.updated_at",
"teachers.student_teacher"."id" AS "teachers.student_teacher.id",
"teachers.student_teacher"."teacher_id" AS
"teachers.student_teacher.teacher_id", "teachers.student_teacher"."student_id"
AS "teachers.student_teacher.student_id"
FROM (
SELECT "student"."id", "student"."age", "student"."name",
"student"."created_at", "student"."updated_at"
FROM "student" AS "student"
WHERE (
SELECT "student_teacher"."id"
FROM "student_teacher" AS "student_teacher"
INNER JOIN "teacher" AS "teacher"
ON "student_teacher"."teacher_id" = "teacher"."id"
WHERE ("student"."id" = "student_teacher"."student_id")
LIMIT 1
) IS NOT NULL LIMIT 5 OFFSET 6
) AS "student"
INNER JOIN (
"student_teacher" AS "teachers.student_teacher"
INNER JOIN "teacher" AS "teachers"
ON "teachers"."id" = "teachers.student_teacher"."teacher_id"
)
ON "student"."id" = "teachers.student_teacher"."student_id"
AND "teachers"."id" IN (3, 2);
As I look at queries it seems it would be great if generated queries for test cases 2
and 3
would be the same as in 1
with LIMIT
included at the end of query, wouldn’t it?
Thank you for your work!
Issue Analytics
- State:
- Created 8 years ago
- Reactions:2
- Comments:23 (13 by maintainers)
Top Results From Across the Web
SELECT LIMIT 1 query returns unexpected results when the ...
My question is: Why does this happen? There is no WHERE clause in the query so there should be no reason for MySQL...
Read more >SELECT query with LIMIT clause returns non-deterministic ...
This article explains why SELECT query with LIMIT clause returns non-deterministic result although ORDER BY exists in a different level like ...
Read more >Difference between WHERE and ON in SQL - Data School
Filtering data. Both the ON and WHERE clause can be used to filter data in a query. There are readability and accuracy concerns...
Read more >Advanced SQL
INNER JOIN clause is an alternative to WHERE clause, and is used to match primary and foreign keys. An INNER join will only...
Read more >SELECT
limit -clause ::= [ LIMIT [offset,] row_count | row_count OFFSET offset | ALL ... When the topmost SELECT query finishes, all resources associated...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@janmeier my case is exactly the same as @fogine first post.
I have noticed that adding the option
subQuery: false
seems to produce the desired mysql query. Is there any downside of using this?Same issue here. Any progress or workaround?
Is there any reason for those subqueries being there?