mirror of
https://github.com/hanzoai/better-sqlite3-multiple-ciphers.git
synced 2026-09-24 16:57:19 +00:00
Fix virtual table limit offset
* Don't care limit and offset constraints of user-defined virtual tables * Add a test case for https://github.com/WiseLibs/better-sqlite3/issues/872 Co-authored-by: Ryusei Yamaguchi <[email protected]>
This commit is contained in:
co-authored by
Ryusei Yamaguchi
parent
8b0ab0d99b
commit
e99ea79d2a
@@ -1748,6 +1748,13 @@ int CustomTable::xBestIndex (sqlite3_vtab * vtab, sqlite3_index_info * output)
|
||||
auto item = output->aConstraint[i];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (item.op == SQLITE_INDEX_CONSTRAINT_LIMIT || item.op == SQLITE_INDEX_CONSTRAINT_OFFSET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.iColumn >= 0 && item.iColumn < parameter_count) {
|
||||
if (item.op != SQLITE_INDEX_CONSTRAINT_EQ) {
|
||||
sqlite3_free(vtab->zErrMsg);
|
||||
@@ -1782,9 +1789,9 @@ int CustomTable::xBestIndex (sqlite3_vtab * vtab, sqlite3_index_info * output)
|
||||
output->estimatedCost = output->estimatedRows = 1000000000 / (argument_count + 1);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#line 387 "./src/util/custom-table.lzz"
|
||||
#line 394 "./src/util/custom-table.lzz"
|
||||
void CustomTable::PropagateJSError ()
|
||||
#line 387 "./src/util/custom-table.lzz"
|
||||
#line 394 "./src/util/custom-table.lzz"
|
||||
{
|
||||
assert(db->GetState()->was_js_error == false);
|
||||
db->GetState()->was_js_error = true;
|
||||
|
||||
@@ -666,17 +666,17 @@ private:
|
||||
static int xRowid (sqlite3_vtab_cursor * cursor, sqlite_int64 * output);
|
||||
#line 343 "./src/util/custom-table.lzz"
|
||||
static int xBestIndex (sqlite3_vtab * vtab, sqlite3_index_info * output);
|
||||
#line 387 "./src/util/custom-table.lzz"
|
||||
void PropagateJSError ();
|
||||
#line 392 "./src/util/custom-table.lzz"
|
||||
Addon * const addon;
|
||||
#line 393 "./src/util/custom-table.lzz"
|
||||
v8::Isolate * const isolate;
|
||||
#line 394 "./src/util/custom-table.lzz"
|
||||
void PropagateJSError ();
|
||||
#line 399 "./src/util/custom-table.lzz"
|
||||
Addon * const addon;
|
||||
#line 400 "./src/util/custom-table.lzz"
|
||||
v8::Isolate * const isolate;
|
||||
#line 401 "./src/util/custom-table.lzz"
|
||||
Database * const db;
|
||||
#line 395 "./src/util/custom-table.lzz"
|
||||
#line 402 "./src/util/custom-table.lzz"
|
||||
std::string const name;
|
||||
#line 396 "./src/util/custom-table.lzz"
|
||||
#line 403 "./src/util/custom-table.lzz"
|
||||
CopyablePersistent <v8::Function> const factory;
|
||||
};
|
||||
#line 65 "./src/util/data.lzz"
|
||||
|
||||
@@ -348,6 +348,13 @@ private:
|
||||
for (int i = 0, len = output->nConstraint; i < len; ++i) {
|
||||
auto item = output->aConstraint[i];
|
||||
|
||||
// The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
|
||||
// operators have no left-hand operand, and so for those operators the
|
||||
// corresponding item.iColumn is meaningless.
|
||||
// We don't care those constraints.
|
||||
if (item.op == SQLITE_INDEX_CONSTRAINT_LIMIT || item.op == SQLITE_INDEX_CONSTRAINT_OFFSET) {
|
||||
continue;
|
||||
}
|
||||
// We only care about constraints on parameters, not regular columns.
|
||||
if (item.iColumn >= 0 && item.iColumn < parameter_count) {
|
||||
if (item.op != SQLITE_INDEX_CONSTRAINT_EQ) {
|
||||
|
||||
@@ -668,4 +668,28 @@ describe('Database#table()', function () {
|
||||
throw new TypeError('Expected the statement to throw an exception');
|
||||
});
|
||||
});
|
||||
it('should correctly handle limit and offset clause', function () {
|
||||
let lastValue;
|
||||
this.db.table('vtab', {
|
||||
columns: ['x'],
|
||||
*rows() {
|
||||
lastValue = 1;
|
||||
yield { x: lastValue };
|
||||
lastValue = 2;
|
||||
yield { x: lastValue };
|
||||
lastValue = 3;
|
||||
yield { x: lastValue };
|
||||
lastValue = null;
|
||||
},
|
||||
});
|
||||
expect(this.db.prepare('SELECT * FROM vtab LIMIT 1').all())
|
||||
.to.deep.equal([{ x: 1 }]);
|
||||
expect(lastValue).to.equal(1);
|
||||
expect(this.db.prepare('SELECT * FROM vtab LIMIT 1 OFFSET 2').all())
|
||||
.to.deep.equal([{ x: 3 }]);
|
||||
expect(lastValue).to.equal(3);
|
||||
expect(this.db.prepare('SELECT * FROM vtab LIMIT 100 OFFSET 1').all())
|
||||
.to.deep.equal([{ x: 2 }, { x: 3 }]);
|
||||
expect(lastValue).to.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user