不要怂,就是干,撸起袖子干!

Commit 4d75caf4 by Sushant Committed by GitHub

fix(mssql): duplicate order in FETCH/NEXT queries (#12257)

1 parent 9a95e727
...@@ -917,8 +917,18 @@ class MSSQLQueryGenerator extends AbstractQueryGenerator { ...@@ -917,8 +917,18 @@ class MSSQLQueryGenerator extends AbstractQueryGenerator {
if (options.limit || options.offset) { if (options.limit || options.offset) {
if (!options.order || options.include && !orders.subQueryOrder.length) { if (!options.order || options.include && !orders.subQueryOrder.length) {
fragment += options.order && !isSubQuery ? ', ' : ' ORDER BY '; const tablePkFragment = `${this.quoteTable(options.tableAs || model.name)}.${this.quoteIdentifier(model.primaryKeyField)}`;
fragment += `${this.quoteTable(options.tableAs || model.name)}.${this.quoteIdentifier(model.primaryKeyField)}`; if (!options.order) {
fragment += ` ORDER BY ${tablePkFragment}`;
} else {
const orderFieldNames = _.map(options.order, order => order[0]);
const primaryKeyFieldAlreadyPresent = _.includes(orderFieldNames, model.primaryKeyField);
if (!primaryKeyFieldAlreadyPresent) {
fragment += options.order && !isSubQuery ? ', ' : ' ORDER BY ';
fragment += tablePkFragment;
}
}
} }
if (options.offset || options.limit) { if (options.offset || options.limit) {
......
...@@ -8,7 +8,7 @@ const chai = require('chai'), ...@@ -8,7 +8,7 @@ const chai = require('chai'),
dialect = Support.getTestDialect(); dialect = Support.getTestDialect();
if (dialect.match(/^mssql/)) { if (dialect.match(/^mssql/)) {
describe('[MSSQL Specific] Regressions', () => { describe(Support.getTestDialectTeaser('Regressions'), () => {
it('does not duplicate columns in ORDER BY statement, #9008', async function() { it('does not duplicate columns in ORDER BY statement, #9008', async function() {
const LoginLog = this.sequelize.define('LoginLog', { const LoginLog = this.sequelize.define('LoginLog', {
ID: { ID: {
...@@ -80,72 +80,120 @@ if (dialect.match(/^mssql/)) { ...@@ -80,72 +80,120 @@ if (dialect.match(/^mssql/)) {
expect(logs).to.have.length(2); expect(logs).to.have.length(2);
expect(logs[0].User.get('UserName')).to.equal('Shaktimaan'); expect(logs[0].User.get('UserName')).to.equal('Shaktimaan');
expect(logs[1].User.get('UserName')).to.equal('Aryamaan'); expect(logs[1].User.get('UserName')).to.equal('Aryamaan');
});
});
it('sets the varchar(max) length correctly on describeTable', async function() {
const Users = this.sequelize.define('_Users', {
username: Sequelize.STRING('MAX')
}, { freezeTableName: true });
await Users.sync({ force: true }); // #11258 and similar
const metadata = await this.sequelize.getQueryInterface().describeTable('_Users'); const otherLogs = await LoginLog.findAll({
const username = metadata.username; include: [
expect(username.type).to.include('(MAX)'); {
}); model: User,
where: {
UserName: {
[Op.like]: '%maan%'
}
}
}
],
order: [['id', 'DESC']],
offset: 0,
limit: 10
});
it('sets the char(10) length correctly on describeTable', async function() { expect(otherLogs).to.have.length(2);
const Users = this.sequelize.define('_Users', { expect(otherLogs[0].User.get('UserName')).to.equal('Aryamaan');
username: Sequelize.CHAR(10) expect(otherLogs[1].User.get('UserName')).to.equal('Shaktimaan');
}, { freezeTableName: true });
await Users.sync({ force: true }); // Separate queries can apply order freely
const metadata = await this.sequelize.getQueryInterface().describeTable('_Users'); const separateUsers = await User.findAll({
const username = metadata.username; include: [
expect(username.type).to.include('(10)'); {
}); model: LoginLog,
separate: true,
order: [
'id'
]
}
],
where: {
UserName: {
[Op.like]: '%maan%'
}
},
order: ['UserName', ['UserID', 'DESC']],
offset: 0,
limit: 10
});
it('saves value bigger than 2147483647, #11245', async function() { expect(separateUsers).to.have.length(2);
const BigIntTable = this.sequelize.define('BigIntTable', { expect(separateUsers[0].get('UserName')).to.equal('Aryamaan');
business_id: { expect(separateUsers[0].get('LoginLogs')).to.have.length(1);
type: Sequelize.BIGINT, expect(separateUsers[1].get('UserName')).to.equal('Shaktimaan');
allowNull: false expect(separateUsers[1].get('LoginLogs')).to.have.length(1);
}
}, {
freezeTableName: true
}); });
const bigIntValue = 2147483648; it('sets the varchar(max) length correctly on describeTable', async function() {
const Users = this.sequelize.define('_Users', {
await BigIntTable.sync({ force: true }); username: Sequelize.STRING('MAX')
}, { freezeTableName: true });
await BigIntTable.create({ await Users.sync({ force: true });
business_id: bigIntValue const metadata = await this.sequelize.getQueryInterface().describeTable('_Users');
const username = metadata.username;
expect(username.type).to.include('(MAX)');
}); });
const record = await BigIntTable.findOne(); it('sets the char(10) length correctly on describeTable', async function() {
expect(Number(record.business_id)).to.equals(bigIntValue); const Users = this.sequelize.define('_Users', {
}); username: Sequelize.CHAR(10)
}, { freezeTableName: true });
it('saves boolean is true, #12090', async function() { await Users.sync({ force: true });
const BooleanTable = this.sequelize.define('BooleanTable', { const metadata = await this.sequelize.getQueryInterface().describeTable('_Users');
status: { const username = metadata.username;
type: Sequelize.BOOLEAN, expect(username.type).to.include('(10)');
allowNull: false
}
}, {
freezeTableName: true
}); });
const value = true; it('saves value bigger than 2147483647, #11245', async function() {
const BigIntTable = this.sequelize.define('BigIntTable', {
business_id: {
type: Sequelize.BIGINT,
allowNull: false
}
}, {
freezeTableName: true
});
const bigIntValue = 2147483648;
await BooleanTable.sync({ force: true }); await BigIntTable.sync({ force: true });
await BooleanTable.create({ await BigIntTable.create({
status: value business_id: bigIntValue
});
const record = await BigIntTable.findOne();
expect(Number(record.business_id)).to.equals(bigIntValue);
}); });
const record = await BooleanTable.findOne(); it('saves boolean is true, #12090', async function() {
expect(record.status).to.equals(value); const BooleanTable = this.sequelize.define('BooleanTable', {
status: {
type: Sequelize.BOOLEAN,
allowNull: false
}
}, {
freezeTableName: true
});
const value = true;
await BooleanTable.sync({ force: true });
await BooleanTable.create({
status: value
});
const record = await BooleanTable.findOne();
expect(record.status).to.equals(value);
});
}); });
} }
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!