import { Database } from "https://deno.land/x/sqlite3@0.6.1/mod.ts";
const db = new Database(":memory:");
db.exec(`
CREATE TABLE foo (
name TEXT NOT NULL
);
`);
db.exec(`INSERT INTO foo (name) VALUES (?)`, "");
fails with:
error: Uncaught (in promise) Error: NOT NULL constraint failed: foo.name
I tried to figure out what's going on and seems like it's a problem with deno's ffi layer, where for an empty array it returns a null pointer:
~> deno --unstable
Deno 1.29.1
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
> const b = new Uint8Array();
undefined
> Deno.UnsafePointer.of(b)
0
As a suggestion, perhaps something like this could work as a workaround:
// create a non-empty buffer globally somewhere
const emptyStrBuf = new Uint8Array(1);
// then when using sqlite3_bind_text in #bind check for empty string explicitly,
// if it's empty use the buffer above, but specify zero length
if (param === "") {
unwrap(
sqlite3_bind_text(this.#handle, i + 1, emptyStrBuf, 0, 0),
);
}
(using a non-empty array properly returns some valid pointer in deno)
> const b = new Uint8Array(1);
undefined
> Deno.UnsafePointer.of(b)
94900665479152
Right now the following code:
fails with:
I tried to figure out what's going on and seems like it's a problem with deno's ffi layer, where for an empty array it returns a null pointer:
Which in turn when used with
sqlite3_bind_text
causes sqlite3 to bind null: https://github.com/sqlite/sqlite/blob/3547e4997f29afa0df561653019b795e6f8f691a/src/vdbemem.c#L1155This is the code which causes a problem: https://github.com/denodrivers/sqlite3/blob/4a01a0257b878d6229a368adcc418a5bfe8485e4/src/statement.ts#L256-L263
As a suggestion, perhaps something like this could work as a workaround:
(using a non-empty array properly returns some valid pointer in deno)