WiseLibs / better-sqlite3

The fastest and simplest library for SQLite3 in Node.js.
MIT License
5.44k stars 394 forks source link

`no such table: main.object Object` when preparing a DELETE statement #1146

Closed MadCatX closed 7 months ago

MadCatX commented 7 months ago

This is a bizarre one.

My application suddenly stopped working, throwing an SqliteError. Further inspection told me that the exception with no such table: main.object Object message get thrown when my code tries to prepare a DELETE statement.

The simplest code that can produce the error is this:

export function del(dbh: SqliteDbh, table: SqlTable<string, string>) {
    const qs = `DELETE FROM ${table.name}`;
    const stmt = dbh.conn.prepare(qs);
    stmt.run([]);
}

I did check that the name property of the table object is sensible and that the actual query looks like, say, DELETE FROM users

The last place I can get with node debugger before the SqliteError gets thrown in the prepare function from wrappers.js

exports.prepare = function prepare(sql) {
    return this[cppdb].prepare(sql, this, false);
};

AFAICT, everything looks perfectly reasonable when the internal prepare function gets called.

I am using similar code to execute SELECTs and INSERTs with no issues. I did rebuild better_sqlite3.node manually to make sure I was not seeing any odd incompatibility issues.

Any ideas?

Prinzhorn commented 7 months ago

There's a Discussions tab for these type of questions now.

Any ideas?

Provide a minimal repro that we can run.

I did check that the name property of the table object is sensible and that the actual query looks like, say, DELETE FROM users

I don't quite believe that, it looks like you are interpolating an object somewhere, producing DELETE FROM [object Object];

sqlite> DELETE FROM [object Object];
Parse error: no such table: object Object
MadCatX commented 7 months ago

I can't seem to repro this with a trivial case so providing an actual MWE will be tricky.

I did check that the name property of the table object is sensible and that the actual query looks like, say, DELETE FROM users

I don't quite believe that, it looks like you are interpolating an object somewhere, producing DELETE FROM [object Object];

sqlite> DELETE FROM [object Object];
Parse error: no such table: object Object

That is not the error message I'm getting. main.object Object is not the same thing as object Object. Furthermore, I get the same error even if I hardcode the name of the table into the statement.

In fact, if I execute DELETE FROM non_existent_table I get a correct error message. If I replace non_existent_table with a table that actually exists, I get main.object Object in the error string.

As far as I can tell, the source of the error is somewhere in the sqlite3Parser() function when sqlite3 reaches the null terminator of the query string. AFAICT, something odd happens in sqlite3GenerateRowDelete() function so it might actually be a sqlite3 issue.

MadCatX commented 7 months ago

Never mind, I traced the problem to an awkward foreign key issue in my code for which SQLite does not provide very good error message. Closing.