Skip to content

Commit a4c1a42

Browse files
authored
Avoid caching dirty data to fix #2027
1 parent 0dd3a6f commit a4c1a42

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

src/17alasql.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,23 @@ alasql.exec = function (sql, params, cb, scope) {
244244
}
245245
};
246246

247+
/**
248+
* Clears any unneeded properties from a given AST statement closure used for caching
249+
* @param {Object} statement the statement to cleanup
250+
*/
251+
function cleanupCache(statement) {
252+
if (!statement) {
253+
return;
254+
}
255+
if (!alasql.options.cache) {
256+
return;
257+
}
258+
// cleanup the table data to prevent storing this information in the SQL cache
259+
if (statement && statement.query && statement.query.data) {
260+
statement.query.data = [];
261+
}
262+
}
263+
247264
/**
248265
Run SQL statement on specific database
249266
*/
@@ -259,7 +276,9 @@ alasql.dexec = function (databaseid, sql, params, cb, scope) {
259276
let statement = db.sqlCache[hh];
260277
// If database structure was not changed since last time return cache
261278
if (statement && db.dbversion === statement.dbversion) {
262-
return statement(params, cb);
279+
var res = statement(params, cb);
280+
cleanupCache(statement);
281+
return res;
263282
}
264283
}
265284

@@ -302,6 +321,7 @@ alasql.dexec = function (databaseid, sql, params, cb, scope) {
302321
db.sqlCache[hh] = statement;
303322
}
304323
var res = (alasql.res = statement(params, cb, scope));
324+
cleanupCache(statement);
305325
return res;
306326
}
307327
alasql.precompile(ast.statements[0], alasql.useid, params);

test/test2027.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const alasql = require('../dist/alasql.js');
2+
3+
if (typeof exports === 'object') {
4+
var assert = require('assert');
5+
}
6+
7+
describe('Test 2007 - SQL cache', function () {
8+
before(function () {
9+
alasql('create database test');
10+
alasql('use test');
11+
});
12+
13+
after(function () {
14+
alasql('drop database test');
15+
});
16+
17+
it('A) Execute query and assert cache for `data` afterwards', () => {
18+
alasql('CREATE TABLE osoby (id INT, meno STRING)');
19+
alasql('INSERT INTO osoby VALUES (1, "John"), (2, "Jane"), (3, "Jake")');
20+
var res = alasql('SELECT * FROM osoby');
21+
22+
assert.deepEqual(alasql.databases["test"].sqlCache["-169125189"].query.data, []);
23+
assert.equal(res.length, 3);
24+
25+
// Delete all rows
26+
alasql('DELETE FROM osoby');
27+
28+
// Assert that the cache is still empty for "data"
29+
// Without the fix, the cache would still contain the data from the previous query even though all rows were deleted
30+
assert.deepEqual(alasql.databases["test"].sqlCache["-169125189"].query.data, []);
31+
32+
// Insert more rows
33+
alasql('INSERT INTO osoby VALUES (4, "Jack"), (5, "Paul")');
34+
35+
// Execute same query from cache again, the cache is hit now
36+
var res2 = alasql('SELECT * FROM osoby');
37+
38+
// Cache should still be empty for "data"
39+
assert.deepEqual(alasql.databases["test"].sqlCache["-169125189"].query.data, []);
40+
assert.equal(res2.length, 2);
41+
});
42+
});

0 commit comments

Comments
 (0)