Skip to content

Compiled statements are not compiled again after a schema change in another database, in alasql.compile() and in views #2613

Closed

Description

@mathiasrw

Compiled SQL is kept in three places, and only one of them is ever compiled again after a schema change. After DROP TABLE and CREATE TABLE with other columns, the other two keep serving code compiled for the old table. The result is wrong and no error is raised.

Reproduced on develop with #2609 (which fixes the single-database case of #2603):

alasql('CREATE DATABASE a; CREATE DATABASE b; USE a');
Where the compiled code is kept Steps Result Expected
Statement cache, table in another database CREATE TABLE b.t (x INT), SELECT * FROM b.t, DROP TABLE b.t, CREATE TABLE b.t (x INT, y INT), insert (1,2), SELECT * FROM b.t [{x:1}] [{x:1, y:2}]
A statement from alasql.compile() st = alasql.compile('SELECT * FROM c'), then the same drop and create on c, then st() [{x:1}] [{x:1, y:2}]
A view, with alasql.options.cache = false CREATE VIEW v AS SELECT * FROM t, SELECT * FROM v, then the same drop and create on t, then SELECT * FROM v [{x:1}] [{x:1, y:2}]

Cause

There is no record of what a compiled statement depends on. The only check is statement.dbversion === db.dbversion in alasql.dexec, and it covers one of the three places:

  1. Statement cache: db is the database the statement runs in, not the database of each table it reads. A change in database b does not change a.dbversion.
  2. alasql.compile(): the returned function never checks a version.
  3. Views: the view's SELECT is compiled once, on first use, and kept on the table object (table.select, src/420from.js). Nothing compiles it again.

Direction

One global schema version, for example alasql.schemaVersion. Every schema change in any database increases it: CREATE / DROP / ALTER TABLE, views, indexes, ATTACH / DETACH, transaction commit and rollback. Every piece of compiled code stores the version it was compiled for and compiles again when it differs: cached statements, functions from alasql.compile(), and the compiled SELECT of a view.

A schema change then throws away all compiled code, not only the code that depends on the changed table. Schema changes are rare compared with queries, so this is the simple and safe choice. Tracking dependencies per table can come later if a benchmark shows the need.

This is a fix for a result that depends on what ran before, so it can go into 4.x.

Tests: the three cases above, each with the cache on and off. Expected results are the same as for a statement compiled fresh.

Related: #2603, #2609, #2587.

Activity

  1. added a commit that references this issue on Oct 20, 2026
    441e02a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions