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

sqlite: support db.loadExtension #53900

Closed

Conversation

himself65
Copy link
Member

@himself65 himself65 commented Jul 17, 2024

Closes #53898

This PR will implement loadExtension API to align with other SQLite3 JS library like better-sqlite3, node-sqlite3, jsr:@db/sqlite, bun:sqlite

Example Code:

import { load } from 'sqlite-vec'
import { DatabaseSync } from 'node:sqlite'

const db = new DatabaseSync(':memory:', {
  allowExtension: true
})
load(db)  // db.loadExtension() support
const { sqlite_version, vec_version } = db.prepare(
  'select sqlite_version() as sqlite_version, vec_version() as vec_version;'
).get()
console.log(`SQLite version: ${sqlite_version}, vector version ${vec_version}`)

const items = [
  [1, [0.1, 0.1, 0.1, 0.1]],
  [2, [0.2, 0.2, 0.2, 0.2]],
  [3, [0.3, 0.3, 0.3, 0.3]],
  [4, [0.4, 0.4, 0.4, 0.4]],
  [5, [0.5, 0.5, 0.5, 0.5]]
]
const query = [0.3, 0.3, 0.3, 0.3]

db.exec('CREATE VIRTUAL TABLE vec_items USING vec0(embedding float[4])')

const insertStmt = db.prepare(
  'INSERT INTO vec_items(rowid, embedding) VALUES (?, ?)'
)

for (const [id, vector] of items) {
  const rowId = BigInt(id)
  const embedding = new Uint8Array(Float32Array.from(vector).buffer)
  insertStmt.run(rowId, embedding)
}

const rows = db.prepare(
  `
  SELECT
    rowid,
    distance
  FROM vec_items
  WHERE embedding MATCH ?
  ORDER BY distance
  LIMIT 3
`
).all(new Uint8Array(Float32Array.from(query).buffer))

console.log(rows)
> sqlite-vec /Users/himself65/Code/node/out/Debug/node --experimental-sqlite ./index.mjs
(node:72169) ExperimentalWarning: SQLite is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
SQLite version: 3.46.0, vector version v0.1.1
[
  { rowid: 3, distance: 0 },
  { rowid: 4, distance: 0.19999998807907104 },
  { rowid: 2, distance: 0.20000001788139343 }
]

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. sqlite Issues and PRs related to the SQLite subsystem. labels Jul 17, 2024
@himself65
Copy link
Member Author

Found another small issue: nodejs/core-validate-commit#122

@RedYetiDev
Copy link
Member

Found another small issue: nodejs/core-validate-commit#122

Duplicate of nodejs/core-validate-commit#121

@himself65
Copy link
Member Author

I will re start this PR

@himself65 himself65 force-pushed the himself65/20240717/load_extension branch from edb5f58 to 8e80ca7 Compare August 8, 2024 04:31
@himself65 himself65 changed the title src(sqlite): sqlite3.loadExtension sqlite: support sqlite3.loadExtension Aug 8, 2024
@himself65 himself65 force-pushed the himself65/20240717/load_extension branch from 8e80ca7 to 200e60b Compare August 8, 2024 05:16
@himself65 himself65 marked this pull request as ready for review August 8, 2024 07:53
@himself65 himself65 changed the title sqlite: support sqlite3.loadExtension sqlite: support sqlite.loadExtension Aug 8, 2024
@himself65 himself65 changed the title sqlite: support sqlite.loadExtension sqlite: support db.loadExtension Aug 8, 2024
@himself65 himself65 force-pushed the himself65/20240717/load_extension branch from 141f72c to 10faf88 Compare August 8, 2024 07:54
@himself65 himself65 requested a review from cjihrig August 8, 2024 07:54
@himself65 himself65 force-pushed the himself65/20240717/load_extension branch 2 times, most recently from 8b1dba0 to 67fe19a Compare August 8, 2024 08:34
@himself65
Copy link
Member Author

I have no idea how to write a test for load extension now.

@himself65
Copy link
Member Author

/cc @nodejs/sqlite (no such group?)

anyway I cc @nodejs/tsc since this is a breaking change

Copy link

codecov bot commented Aug 8, 2024

Codecov Report

Attention: Patch coverage is 69.44444% with 22 lines in your changes missing coverage. Please review.

Project coverage is 88.52%. Comparing base (3c2da4b) to head (08280ba).
Report is 54 commits behind head on main.

Files with missing lines Patch % Lines
src/node_sqlite.cc 69.44% 8 Missing and 14 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #53900      +/-   ##
==========================================
+ Coverage   87.99%   88.52%   +0.53%     
==========================================
  Files         656      657       +1     
  Lines      188999   189929     +930     
  Branches    35981    36472     +491     
==========================================
+ Hits       166301   168133    +1832     
+ Misses      15865    14992     -873     
+ Partials     6833     6804      -29     
Files with missing lines Coverage Δ
src/node_errors.h 85.00% <ø> (ø)
src/node_sqlite.h 70.00% <ø> (ø)
src/node_sqlite.cc 80.25% <69.44%> (-0.93%) ⬇️

... and 108 files with indirect coverage changes

@benjamingr
Copy link
Member

cc @cjihrig

src/node_sqlite.cc Outdated Show resolved Hide resolved
@cjihrig
Copy link
Contributor

cjihrig commented Aug 8, 2024

since this is a breaking change

I took a quick look at the code. I'm not sure what makes this a breaking change though.

I do think the TSC needs to decide if they want to support loading arbitrary native code in this manner. It wouldn't be the first way that Node supports loading native code, so maybe it's fine.

I have no idea how to write a test for load extension now.

Is it possible to create a very trivial extension that can be accessed as a test fixture?

@tniessen
Copy link
Member

tniessen commented Aug 9, 2024

I do think the TSC needs to decide if they want to support loading arbitrary native code in this manner.

It definitely must be disabled when the experimental permission model is enabled, just like native add-ons etc.

@himself65
Copy link
Member Author

For the native test, I'm not sure if we should build an SQLite binding from scratch or if we should just copy some community dll/so/lib to fixtures.

@targos
Copy link
Member

targos commented Aug 9, 2024

We also need a test that tries to load an unexpected file (that is not a sqlite extension). It should throw, not crash the process.

@himself65 himself65 force-pushed the himself65/20240717/load_extension branch from c01c585 to 1bf194b Compare August 10, 2024 08:22
@jakecastelli
Copy link
Member

I'm not sure if we should build an SQLite binding from scratch or if we should just copy some community dll/so/lib to fixtures.

IMO we should build from scratch to avoid any potential attack and make update tests fixture easier if we ever need to update them.

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@himself65 himself65 added the request-ci Add this label to start a Jenkins CI on a PR. label Dec 6, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Dec 6, 2024
@nodejs-github-bot
Copy link
Collaborator

@himself65 himself65 added the request-ci Add this label to start a Jenkins CI on a PR. label Dec 6, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Dec 6, 2024
@nodejs-github-bot
Copy link
Collaborator

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@cjihrig
Copy link
Contributor

cjihrig commented Dec 6, 2024

FYI - I think test/parallel/test-permission-sqlite-load-extension.js is legitimately failing on Windows. I'm not sure if it's related to the use of common.escapePOSIXShell in that test or what.

@himself65 himself65 force-pushed the himself65/20240717/load_extension branch from 6ee1209 to 50715ef Compare December 7, 2024 04:38
@himself65 himself65 added the request-ci Add this label to start a Jenkins CI on a PR. label Dec 7, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Dec 7, 2024
@nodejs-github-bot
Copy link
Collaborator

@himself65
Copy link
Member Author

not sure how to fix it right now. setting up local env on my local windows pc

@himself65
Copy link
Member Author

ok the error is legitimately falling, testing on my windows locally, I think because wrong usage of the cp api

@himself65 himself65 force-pushed the himself65/20240717/load_extension branch from 50715ef to 08280ba Compare December 10, 2024 21:58
@himself65
Copy link
Member Author

OK, I found because \n on windows will truncate the script code, remove it

@himself65 himself65 added the request-ci Add this label to start a Jenkins CI on a PR. label Dec 10, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Dec 10, 2024
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@himself65
Copy link
Member Author

will merge this today

himself65 added a commit that referenced this pull request Dec 11, 2024
PR-URL: #53900
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
@himself65
Copy link
Member Author

Landed in 5c2f599

@himself65 himself65 closed this Dec 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. sqlite Issues and PRs related to the SQLite subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support sqlite.loadExtension