Skip to content

Commit 4ff79dc

Browse files
tzellmansushantdhiman
authored andcommitted
fix(syntax): correct parentheses around union (#9813) (#10003) (#10121)
1 parent c6c2d17 commit 4ff79dc

File tree

3 files changed

+117
-14
lines changed

3 files changed

+117
-14
lines changed

lib/dialects/abstract/query-generator.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,7 @@ const QueryGenerator = {
10961096

10971097
// Caching the base query and splicing the where part into it is consistently > twice
10981098
// as fast than generating from scratch each time for values.length >= 5
1099-
const baseQuery = '(' + this.selectQuery(
1099+
const baseQuery = 'SELECT * FROM (' + this.selectQuery(
11001100
tableName,
11011101
{
11021102
attributes: options.attributes,
@@ -1107,7 +1107,7 @@ const QueryGenerator = {
11071107
model
11081108
},
11091109
model
1110-
).replace(/;$/, '') + ')';
1110+
).replace(/;$/, '') + ') AS sub'; // Every derived table must have its own alias
11111111
const placeHolder = this.whereItemQuery(Op.placeholder, true, { model });
11121112
const splicePos = baseQuery.indexOf(placeHolder);
11131113

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
'use strict';
2+
3+
const chai = require('chai');
4+
const expect = chai.expect;
5+
const Support = require('../../support');
6+
const DataTypes = require('../../../../lib/data-types');
7+
const Sequelize = require('../../../../lib/sequelize');
8+
const current = Support.sequelize;
9+
10+
describe(Support.getTestDialectTeaser('Model'), () => {
11+
describe('findAll', () => {
12+
describe('separate with limit', () => {
13+
it('should not throw syntax error (union)', () => {
14+
// #9813 testcase
15+
const Project = current.define('Project', { name: DataTypes.STRING });
16+
const LevelTwo = current.define('LevelTwo', { name: DataTypes.STRING });
17+
const LevelThree = current.define('LevelThree', { type: DataTypes.INTEGER });
18+
19+
Project.hasMany(LevelTwo);
20+
LevelTwo.belongsTo(Project);
21+
22+
LevelTwo.hasMany(LevelThree, { as: 'type_ones' });
23+
LevelTwo.hasMany(LevelThree, { as: 'type_twos' });
24+
LevelThree.belongsTo(LevelTwo);
25+
26+
return current.sync({ force: true }).then(() => {
27+
return Sequelize.Promise.all([
28+
Project.create({ name: 'testProject' }),
29+
LevelTwo.create({ name: 'testL21' }),
30+
LevelTwo.create({ name: 'testL22' })
31+
]);
32+
}).spread((project, level21, level22) => {
33+
return Sequelize.Promise.all([
34+
project.addLevelTwo(level21),
35+
project.addLevelTwo(level22)
36+
]);
37+
}).spread(() => {
38+
// one include case
39+
return Project.findAll({
40+
where: { name: 'testProject' },
41+
include: [
42+
{
43+
model: LevelTwo,
44+
include: [
45+
{
46+
model: LevelThree,
47+
as: 'type_ones',
48+
where: { type: 0 },
49+
separate: true,
50+
limit: 1,
51+
order: [['createdAt', 'DESC']]
52+
}
53+
]
54+
}
55+
]
56+
});
57+
}).then(projects => {
58+
expect(projects).to.have.length(1);
59+
expect(projects[0].LevelTwos).to.have.length(2);
60+
expect(projects[0].LevelTwos[0].type_ones).to.have.length(0);
61+
expect(projects[0].LevelTwos[1].type_ones).to.have.length(0);
62+
}, () => {
63+
expect.fail();
64+
}).then(() => {
65+
// two includes case
66+
return Project.findAll({
67+
where: { name: 'testProject' },
68+
include: [
69+
{
70+
model: LevelTwo,
71+
include: [
72+
{
73+
model: LevelThree,
74+
as: 'type_ones',
75+
where: { type: 0 },
76+
separate: true,
77+
limit: 1,
78+
order: [['createdAt', 'DESC']]
79+
},
80+
{
81+
model: LevelThree,
82+
as: 'type_twos',
83+
where: { type: 1 },
84+
separate: true,
85+
limit: 1,
86+
order: [['createdAt', 'DESC']]
87+
}
88+
]
89+
}
90+
]
91+
});
92+
}).then(projects => {
93+
expect(projects).to.have.length(1);
94+
expect(projects[0].LevelTwos).to.have.length(2);
95+
expect(projects[0].LevelTwos[0].type_ones).to.have.length(0);
96+
expect(projects[0].LevelTwos[1].type_ones).to.have.length(0);
97+
}, () => {
98+
expect.fail();
99+
});
100+
});
101+
});
102+
});
103+
});

test/unit/sql/select.test.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ suite(Support.getTestDialectTeaser('SQL'), () => {
6868
}, {
6969
default: 'SELECT [User].* FROM ('+
7070
[
71-
'(SELECT [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [User] WHERE [User].[companyId] = 1 ORDER BY [last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')',
72-
'(SELECT [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [User] WHERE [User].[companyId] = 5 ORDER BY [last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')'
71+
'SELECT * FROM (SELECT [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [User] WHERE [User].[companyId] = 1 ORDER BY [last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub',
72+
'SELECT * FROM (SELECT [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [User] WHERE [User].[companyId] = 5 ORDER BY [last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub'
7373
].join(current.dialect.supports['UNION ALL'] ?' UNION ALL ' : ' UNION ')
7474
+') AS [User];'
7575
});
@@ -121,8 +121,8 @@ suite(Support.getTestDialectTeaser('SQL'), () => {
121121
}, {
122122
default: 'SELECT [user].* FROM ('+
123123
[
124-
'(SELECT [user].[id_user] AS [id], [user].[last_name] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 1 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') + sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')',
125-
'(SELECT [user].[id_user] AS [id], [user].[last_name] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 5 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') +sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')'
124+
'SELECT * FROM (SELECT [user].[id_user] AS [id], [user].[last_name] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 1 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') + sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub',
125+
'SELECT * FROM (SELECT [user].[id_user] AS [id], [user].[last_name] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 5 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') +sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub'
126126
].join(current.dialect.supports['UNION ALL'] ?' UNION ALL ' : ' UNION ')
127127
+') AS [user] ORDER BY [subquery_order_0] ASC;'
128128
});
@@ -152,8 +152,8 @@ suite(Support.getTestDialectTeaser('SQL'), () => {
152152
}, {
153153
default: 'SELECT [user].* FROM ('+
154154
[
155-
'(SELECT [user].[id_user] AS [id], [user].[last_name] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 1 AND [project_users].[status] = 1 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') + sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')',
156-
'(SELECT [user].[id_user] AS [id], [user].[last_name] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 5 AND [project_users].[status] = 1 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') +sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')'
155+
'SELECT * FROM (SELECT [user].[id_user] AS [id], [user].[last_name] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 1 AND [project_users].[status] = 1 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') + sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub',
156+
'SELECT * FROM (SELECT [user].[id_user] AS [id], [user].[last_name] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 5 AND [project_users].[status] = 1 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') +sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub'
157157
].join(current.dialect.supports['UNION ALL'] ?' UNION ALL ' : ' UNION ')
158158
+') AS [user] ORDER BY [subquery_order_0] ASC;'
159159
});
@@ -184,8 +184,8 @@ suite(Support.getTestDialectTeaser('SQL'), () => {
184184
}, {
185185
default: 'SELECT [user].* FROM ('+
186186
[
187-
'(SELECT [user].[id_user] AS [id], [user].[id_user] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 1 WHERE [user].[age] >= 21 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') + sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')',
188-
'(SELECT [user].[id_user] AS [id], [user].[id_user] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 5 WHERE [user].[age] >= 21 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') +sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')'
187+
'SELECT * FROM (SELECT [user].[id_user] AS [id], [user].[id_user] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 1 WHERE [user].[age] >= 21 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') + sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub',
188+
'SELECT * FROM (SELECT [user].[id_user] AS [id], [user].[id_user] AS [subquery_order_0], [project_users].[user_id] AS [project_users.userId], [project_users].[project_id] AS [project_users.projectId] FROM [users] AS [user] INNER JOIN [project_users] AS [project_users] ON [user].[id_user] = [project_users].[user_id] AND [project_users].[project_id] = 5 WHERE [user].[age] >= 21 ORDER BY [subquery_order_0] ASC'+ (current.dialect.name === 'mssql' ? ', [user].[id_user]' : '') +sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub'
189189
].join(current.dialect.supports['UNION ALL'] ?' UNION ALL ' : ' UNION ')
190190
+') AS [user] ORDER BY [subquery_order_0] ASC;'
191191
});
@@ -270,8 +270,8 @@ suite(Support.getTestDialectTeaser('SQL'), () => {
270270
}, {
271271
default: 'SELECT [user].*, [POSTS].[id] AS [POSTS.id], [POSTS].[title] AS [POSTS.title] FROM ('+
272272
[
273-
'(SELECT [id_user] AS [id], [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [users] AS [user] WHERE [user].[companyId] = 1 ORDER BY [user].[last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: [['last_name', 'ASC']] })+')',
274-
'(SELECT [id_user] AS [id], [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [users] AS [user] WHERE [user].[companyId] = 5 ORDER BY [user].[last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: [['last_name', 'ASC']] })+')'
273+
'SELECT * FROM (SELECT [id_user] AS [id], [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [users] AS [user] WHERE [user].[companyId] = 1 ORDER BY [user].[last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: [['last_name', 'ASC']] })+') AS sub',
274+
'SELECT * FROM (SELECT [id_user] AS [id], [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [users] AS [user] WHERE [user].[companyId] = 5 ORDER BY [user].[last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: [['last_name', 'ASC']] })+') AS sub'
275275
].join(current.dialect.supports['UNION ALL'] ?' UNION ALL ' : ' UNION ')
276276
+') AS [user] LEFT OUTER JOIN [post] AS [POSTS] ON [user].[id] = [POSTS].[user_id];'
277277
});
@@ -334,8 +334,8 @@ suite(Support.getTestDialectTeaser('SQL'), () => {
334334
}, {
335335
default: 'SELECT [user].*, [POSTS].[id] AS [POSTS.id], [POSTS].[title] AS [POSTS.title], [POSTS->COMMENTS].[id] AS [POSTS.COMMENTS.id], [POSTS->COMMENTS].[title] AS [POSTS.COMMENTS.title] FROM ('+
336336
[
337-
'(SELECT [id_user] AS [id], [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [users] AS [user] WHERE [user].[companyId] = 1 ORDER BY [user].[last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')',
338-
'(SELECT [id_user] AS [id], [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [users] AS [user] WHERE [user].[companyId] = 5 ORDER BY [user].[last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+')'
337+
'SELECT * FROM (SELECT [id_user] AS [id], [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [users] AS [user] WHERE [user].[companyId] = 1 ORDER BY [user].[last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub',
338+
'SELECT * FROM (SELECT [id_user] AS [id], [email], [first_name] AS [firstName], [last_name] AS [lastName] FROM [users] AS [user] WHERE [user].[companyId] = 5 ORDER BY [user].[last_name] ASC'+sql.addLimitAndOffset({ limit: 3, order: ['last_name', 'ASC'] })+') AS sub'
339339
].join(current.dialect.supports['UNION ALL'] ?' UNION ALL ' : ' UNION ')
340340
+') AS [user] LEFT OUTER JOIN [post] AS [POSTS] ON [user].[id] = [POSTS].[user_id] LEFT OUTER JOIN [comment] AS [POSTS->COMMENTS] ON [POSTS].[id] = [POSTS->COMMENTS].[post_id];'
341341
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy