Fixed offset without limit for mysql and sqlite3

This commit is contained in:
Vincent Schoettke 2014-08-28 13:43:09 +02:00
parent d0b8c717e4
commit 00a41a0bb2
4 changed files with 50 additions and 6 deletions

View File

@ -75,9 +75,16 @@ QueryCompiler_MySQL.prototype.columnInfo = function() {
};
};
QueryCompiler_MySQL.prototype.limit = function() {
if (!this.single.limit && !this.single.offset) return '';
// Workaround for offset only, see http://stackoverflow.com/questions/255517/mysql-offset-infinite-rows
return 'limit ' + ((this.single.offset && !this.single.limit) ? '18446744073709551615' : this.formatter.parameter(this.single.limit));
};
// Set the QueryBuilder & QueryCompiler on the client object,
// incase anyone wants to modify things to suit their own purposes.
client.QueryBuilder = QueryBuilder_MySQL;
client.QueryCompiler = QueryCompiler_MySQL;
};
};

View File

@ -110,6 +110,13 @@ QueryCompiler_SQLite3.prototype.columnInfo = function() {
};
};
QueryCompiler_SQLite3.prototype.limit = function() {
if (!this.single.limit && !this.single.offset) return '';
// Workaround for offset only, see http://stackoverflow.com/questions/10491492/sqllite-with-skip-offset-only-not-limit
return 'limit ' + this.formatter.parameter((this.single.offset && !this.single.limit) ? -1 : this.single.limit);
};
client.QueryBuilder = QueryBuilder_SQLite3;
client.QueryCompiler = QueryCompiler_SQLite3;

View File

@ -40,6 +40,36 @@ module.exports = function(knex) {
});
});
it('starts selecting at offset', function () {
return knex.pluck('id').orderBy('id').from('accounts').offset(2)
.testSql(function (tester) {
tester(
'mysql',
'select `id` from `accounts` order by `id` asc limit 18446744073709551615 offset ?',
[2],
[3, 4, 5, 7]
);
tester(
'postgresql',
'select "id" from "accounts" order by "id" asc offset ?',
[2],
['3', '4', '5', '7']
);
tester(
'sqlite3',
'select "id" from "accounts" order by "id" asc limit ? offset ?',
[-1, 2],
[3, 4, 5, 6]
);
tester(
'oracle',
"select * from (select row_.*, ROWNUM rownum_ from (select \"id\" from \"accounts\" order by \"id\" asc) row_ where rownum <= ?) where rownum_ > ?",
[10000000000002, 2],
[3, 4, 5, 7]
);
});
});
it('returns a single entry with first', function() {
return knex.first('id', 'first_name').orderBy('id').from('accounts')
.testSql(function(tester) {

View File

@ -729,7 +729,7 @@ module.exports = function(qb, clientName, aliasName) {
});
});
it("Oracle first", function() {
it("first", function() {
testsql(qb().first('*').from('users'), {
mysql: {
sql: 'select * from `users` limit ?',
@ -749,15 +749,15 @@ module.exports = function(qb, clientName, aliasName) {
it("offsets only", function() {
testsql(qb().select('*').from('users').offset(5), {
mysql: {
sql: 'select * from `users` offset ?', // TODO: This is wrong
sql: 'select * from `users` limit 18446744073709551615 offset ?',
bindings: [5]
},
sqlite3: {
sql: 'select * from "users" offset ?', // TODO: This is wrong
bindings: [5]
sql: 'select * from "users" limit ? offset ?',
bindings: [-1, 5]
},
postgres: {
sql: 'select * from "users" offset ?', // TODO: This is wrong
sql: 'select * from "users" offset ?',
bindings: [5]
},
oracle: {