Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FOREIGN KEY referencing column in vec0 virtual table results in malformed database #144

Open
dymk opened this issue Nov 24, 2024 · 2 comments

Comments

@dymk
Copy link

dymk commented Nov 24, 2024

The following SQL, when ran against sqlite-vec 1.6.0, will result in a malformed database -

CREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0 (
    id INTEGER PRIMARY KEY,
    embedding float [4]
);

CREATE TABLE IF NOT EXISTS
    widgets (
        widget_id INTEGER NOT NULL,
        embedding_id INTEGER NOT NULL,
        FOREIGN KEY (embedding_id) REFERENCES embeddings (id)
    );

INSERT INTO embeddings (embedding) VALUES ('[1, 2, 3, 4]');
INSERT INTO widgets (widget_id, embedding_id) VALUES (1, (SELECT last_insert_rowid()));

The final INSERT will result in a database malformed error:

Error: SqliteFailure(Error { code: DatabaseCorrupt, extended_code: 11 }, Some("database disk image is malformed"))

If the foreign key constraint is removed (FOREIGN KEY (embedding_id) REFERENCES embeddings (id)), then there is no malformed disk image error.

@asg017
Copy link
Owner

asg017 commented Nov 27, 2024

@dymk thanks for reporting! Can you share the version of SQLite you're on?

I'm trying to reproduce on my machine on SQLite 3.41, but seems to work as expected:

.load vec0
.mode qbox

select sqlite_version(), vec_version();

CREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0 (
    id INTEGER PRIMARY KEY,
    embedding float [4]
);

CREATE TABLE IF NOT EXISTS
    widgets (
        widget_id INTEGER NOT NULL,
        embedding_id INTEGER NOT NULL,
        FOREIGN KEY (embedding_id) REFERENCES embeddings (id)
    );

INSERT INTO embeddings (embedding) VALUES ('[1, 2, 3, 4]');
INSERT INTO widgets (widget_id, embedding_id) VALUES (1, (SELECT last_insert_rowid()));

select * from widgets;
select * from embeddings;

Output:

┌──────────────────┬───────────────┐
│ sqlite_version() │ vec_version() │
├──────────────────┼───────────────┤
│ '3.41.0'         │ 'v0.1.6'      │
└──────────────────┴───────────────┘
┌───────────┬──────────────┐
│ widget_id │ embedding_id │
├───────────┼──────────────┤
│ 1         │ 1            │
└───────────┴──────────────┘
┌────┬─────────────────────────────────────┐
│ id │              embedding              │
├────┼─────────────────────────────────────┤
│ 1  │ x'0000803f000000400000404000008040' │
└────┴─────────────────────────────────────┘

@doronnac
Copy link

doronnac commented Dec 14, 2024

Hi, I've encountered this bug as well. Happens after around 20 insertions. I'll try to create a reproduction soon.

EDIT: Read some docs, this seems to not be possible in SQLite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants