diff --git a/src/17alasql.js b/src/17alasql.js index 0c5e359b5..ec54b2dea 100755 --- a/src/17alasql.js +++ b/src/17alasql.js @@ -244,6 +244,23 @@ alasql.exec = function (sql, params, cb, scope) { } }; +/** + * Clears any unneeded properties from a given AST statement closure used for caching + * @param {Object} statement the statement to cleanup + */ +function cleanupCache(statement) { + if (!statement) { + return; + } + if (!alasql.options.cache) { + return; + } + // cleanup the table data to prevent storing this information in the SQL cache + if (statement && statement.query && statement.query.data) { + statement.query.data = []; + } +} + /** Run SQL statement on specific database */ @@ -259,7 +276,9 @@ alasql.dexec = function (databaseid, sql, params, cb, scope) { let statement = db.sqlCache[hh]; // If database structure was not changed since last time return cache if (statement && db.dbversion === statement.dbversion) { - return statement(params, cb); + var res = statement(params, cb); + cleanupCache(statement); + return res; } } @@ -302,6 +321,7 @@ alasql.dexec = function (databaseid, sql, params, cb, scope) { db.sqlCache[hh] = statement; } var res = (alasql.res = statement(params, cb, scope)); + cleanupCache(statement); return res; } alasql.precompile(ast.statements[0], alasql.useid, params); diff --git a/test/test2027.js b/test/test2027.js new file mode 100644 index 000000000..7687c4d48 --- /dev/null +++ b/test/test2027.js @@ -0,0 +1,42 @@ +const alasql = require('../dist/alasql.js'); + +if (typeof exports === 'object') { + var assert = require('assert'); +} + +describe('Test 2007 - SQL cache', function () { + before(function () { + alasql('create database test'); + alasql('use test'); + }); + + after(function () { + alasql('drop database test'); + }); + + it('A) Execute query and assert cache for `data` afterwards', () => { + alasql('CREATE TABLE osoby (id INT, meno STRING)'); + alasql('INSERT INTO osoby VALUES (1, "John"), (2, "Jane"), (3, "Jake")'); + var res = alasql('SELECT * FROM osoby'); + + assert.deepEqual(alasql.databases["test"].sqlCache["-169125189"].query.data, []); + assert.equal(res.length, 3); + + // Delete all rows + alasql('DELETE FROM osoby'); + + // Assert that the cache is still empty for "data" + // Without the fix, the cache would still contain the data from the previous query even though all rows were deleted + assert.deepEqual(alasql.databases["test"].sqlCache["-169125189"].query.data, []); + + // Insert more rows + alasql('INSERT INTO osoby VALUES (4, "Jack"), (5, "Paul")'); + + // Execute same query from cache again, the cache is hit now + var res2 = alasql('SELECT * FROM osoby'); + + // Cache should still be empty for "data" + assert.deepEqual(alasql.databases["test"].sqlCache["-169125189"].query.data, []); + assert.equal(res2.length, 2); + }); +});