Bug 1953266 - Vendor sqlite-vec extension for Firefox. r=asuth,glandium,tjr
Sqlite-vec is a SQLite extension that allows to store and retrieve vectors and various distance between them. It is a bring your own vectors kind of solution. Differential Revision: https://phabricator.services.mozilla.com/D244347
This commit is contained in:
@@ -101,6 +101,11 @@ if CONFIG["MOZ_THUNDERBIRD"] or CONFIG["MOZ_SUITE"]:
|
|||||||
if not CONFIG["MOZ_AVOID_DISK_REMNANT_ON_CLOSE"]:
|
if not CONFIG["MOZ_AVOID_DISK_REMNANT_ON_CLOSE"]:
|
||||||
DEFINES["MOZ_SQLITE_PERSIST_AUXILIARY_FILES"] = 1
|
DEFINES["MOZ_SQLITE_PERSIST_AUXILIARY_FILES"] = 1
|
||||||
|
|
||||||
|
# The vector extension is enabled only for Firefox, it could be opened up
|
||||||
|
# to other products in the future.
|
||||||
|
if CONFIG["MOZ_BUILD_APP"] == "browser":
|
||||||
|
DEFINES["MOZ_SQLITE_VEC0_EXT"] = 1
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
"/dom/base",
|
"/dom/base",
|
||||||
"/third_party/sqlite3/ext",
|
"/third_party/sqlite3/ext",
|
||||||
|
|||||||
@@ -2786,6 +2786,9 @@ Connection::LoadExtension(const nsACString& aExtensionName,
|
|||||||
static constexpr nsLiteralCString sSupportedExtensions[] = {
|
static constexpr nsLiteralCString sSupportedExtensions[] = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
"fts5"_ns,
|
"fts5"_ns,
|
||||||
|
#ifdef MOZ_SQLITE_VEC0_EXT
|
||||||
|
"vec"_ns,
|
||||||
|
#endif
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
if (std::find(std::begin(sSupportedExtensions),
|
if (std::find(std::begin(sSupportedExtensions),
|
||||||
|
|||||||
151
storage/test/unit/test_storage_ext_vec.js
Normal file
151
storage/test/unit/test_storage_ext_vec.js
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
// This file tests support for the sqlite-vec extension.
|
||||||
|
|
||||||
|
function tensorToBlob(tensor) {
|
||||||
|
return new Uint8ClampedArray(new Float32Array(tensor).buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_setup(async function () {
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_synchronous() {
|
||||||
|
info("Testing synchronous connection");
|
||||||
|
let conn = getOpenedUnsharedDatabase();
|
||||||
|
Assert.throws(
|
||||||
|
() =>
|
||||||
|
conn.executeSimpleSQL(
|
||||||
|
`CREATE VIRTUAL TABLE test USING vec0(
|
||||||
|
embedding FLOAT[4]
|
||||||
|
);`
|
||||||
|
),
|
||||||
|
/NS_ERROR_FAILURE/,
|
||||||
|
"Should not be able to use vec without loading the extension"
|
||||||
|
);
|
||||||
|
|
||||||
|
await loadExtension(conn);
|
||||||
|
|
||||||
|
conn.executeSimpleSQL(
|
||||||
|
`
|
||||||
|
CREATE VIRTUAL TABLE test USING vec0(
|
||||||
|
embedding FLOAT[4]
|
||||||
|
)
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
let stmt = conn.createStatement(
|
||||||
|
`
|
||||||
|
INSERT INTO test(rowid, embedding)
|
||||||
|
VALUES (1, :vector)
|
||||||
|
`
|
||||||
|
);
|
||||||
|
stmt.bindBlobByName("vector", tensorToBlob([0.3, 0.3, 0.3, 0.3]));
|
||||||
|
stmt.executeStep();
|
||||||
|
stmt.reset();
|
||||||
|
stmt.finalize();
|
||||||
|
|
||||||
|
stmt = conn.createStatement(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
rowid,
|
||||||
|
distance
|
||||||
|
FROM test
|
||||||
|
WHERE embedding MATCH :vector
|
||||||
|
ORDER BY distance
|
||||||
|
LIMIT 1
|
||||||
|
`
|
||||||
|
);
|
||||||
|
stmt.bindBlobByName("vector", tensorToBlob([0.3, 0.3, 0.3, 0.3]));
|
||||||
|
Assert.ok(stmt.executeStep());
|
||||||
|
Assert.equal(stmt.getInt32(0), 1);
|
||||||
|
Assert.equal(stmt.getDouble(1), 0.0);
|
||||||
|
stmt.reset();
|
||||||
|
stmt.finalize();
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_asynchronous() {
|
||||||
|
info("Testing asynchronous connection");
|
||||||
|
let conn = await openAsyncDatabase(getTestDB());
|
||||||
|
|
||||||
|
await Assert.rejects(
|
||||||
|
executeSimpleSQLAsync(
|
||||||
|
conn,
|
||||||
|
`
|
||||||
|
CREATE VIRTUAL TABLE test USING vec0(
|
||||||
|
embedding float[4]
|
||||||
|
)
|
||||||
|
`
|
||||||
|
),
|
||||||
|
err => err.message.startsWith("no such module"),
|
||||||
|
"Should not be able to use vec without loading the extension"
|
||||||
|
);
|
||||||
|
|
||||||
|
await loadExtension(conn);
|
||||||
|
|
||||||
|
await executeSimpleSQLAsync(
|
||||||
|
conn,
|
||||||
|
`
|
||||||
|
CREATE VIRTUAL TABLE test USING vec0(
|
||||||
|
embedding float[4]
|
||||||
|
)
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
await asyncClose(conn);
|
||||||
|
await IOUtils.remove(getTestDB().path, { ignoreAbsent: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_clone() {
|
||||||
|
info("Testing cloning synchronous connection loads extensions in clone");
|
||||||
|
let conn1 = getOpenedUnsharedDatabase();
|
||||||
|
await loadExtension(conn1);
|
||||||
|
|
||||||
|
let conn2 = conn1.clone(false);
|
||||||
|
conn2.executeSimpleSQL(
|
||||||
|
`
|
||||||
|
CREATE VIRTUAL TABLE test USING vec0(
|
||||||
|
embedding float[4]
|
||||||
|
)
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
conn2.close();
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_asyncClone() {
|
||||||
|
info("Testing asynchronously cloning connection loads extensions in clone");
|
||||||
|
let conn1 = getOpenedUnsharedDatabase();
|
||||||
|
await loadExtension(conn1);
|
||||||
|
|
||||||
|
let conn2 = await asyncClone(conn1, false);
|
||||||
|
await executeSimpleSQLAsync(
|
||||||
|
conn2,
|
||||||
|
`
|
||||||
|
CREATE VIRTUAL TABLE test USING vec0(
|
||||||
|
embedding float[4]
|
||||||
|
)
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
await asyncClose(conn2);
|
||||||
|
await asyncClose(conn1);
|
||||||
|
await IOUtils.remove(getTestDB().path, { ignoreAbsent: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadExtension(conn, ext = "vec") {
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
conn.loadExtension(ext, status => {
|
||||||
|
if (Components.isSuccessCode(status)) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(status);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -79,6 +79,9 @@ skip-if = ["appname != 'thunderbird' && appname != 'seamonkey'"]
|
|||||||
|
|
||||||
["test_storage_ext_fts5.js"]
|
["test_storage_ext_fts5.js"]
|
||||||
|
|
||||||
|
["test_storage_ext_vec.js"]
|
||||||
|
run-if = ["buildapp == 'browser'"]
|
||||||
|
|
||||||
["test_storage_function.js"]
|
["test_storage_function.js"]
|
||||||
|
|
||||||
["test_storage_progresshandler.js"]
|
["test_storage_progresshandler.js"]
|
||||||
|
|||||||
1
third_party/sqlite3/ext/lib.symbols
vendored
1
third_party/sqlite3/ext/lib.symbols
vendored
@@ -3,3 +3,4 @@
|
|||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
sqlite3_fts5_init
|
sqlite3_fts5_init
|
||||||
|
sqlite3_vec_init
|
||||||
|
|||||||
1
third_party/sqlite3/ext/moz.build
vendored
1
third_party/sqlite3/ext/moz.build
vendored
@@ -18,6 +18,7 @@ else:
|
|||||||
|
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
"fts5.c",
|
"fts5.c",
|
||||||
|
"sqlite-vec/sqlite-vec.c",
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG["OS_TARGET"] == "Linux" or CONFIG["OS_TARGET"] == "Android":
|
if CONFIG["OS_TARGET"] == "Linux" or CONFIG["OS_TARGET"] == "Android":
|
||||||
|
|||||||
21
third_party/sqlite3/ext/sqlite-vec/LICENSE-MIT
vendored
Normal file
21
third_party/sqlite3/ext/sqlite-vec/LICENSE-MIT
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Alex Garcia
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
1
third_party/sqlite3/ext/sqlite-vec/VERSION.txt
vendored
Normal file
1
third_party/sqlite3/ext/sqlite-vec/VERSION.txt
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0.1.7-alpha.2
|
||||||
50
third_party/sqlite3/ext/sqlite-vec/moz.yaml
vendored
Normal file
50
third_party/sqlite3/ext/sqlite-vec/moz.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
schema: 1
|
||||||
|
|
||||||
|
bugzilla:
|
||||||
|
product: Toolkit
|
||||||
|
component: Storage
|
||||||
|
|
||||||
|
origin:
|
||||||
|
name: sqlite-vec
|
||||||
|
description: >
|
||||||
|
An extremely small, "fast enough" vector search SQLite extension that runs
|
||||||
|
anywhere!
|
||||||
|
url: https://github.com/asg017/sqlite-vec
|
||||||
|
release: v0.1.7-alpha.2 (2025-01-10T14:54:13-08:00).
|
||||||
|
revision: v0.1.7-alpha.2
|
||||||
|
license: MIT
|
||||||
|
license-file: LICENSE-MIT
|
||||||
|
notes: >
|
||||||
|
Please check for eventual limitations of this extension on the Github page
|
||||||
|
official documentation.
|
||||||
|
|
||||||
|
vendoring:
|
||||||
|
url: https://github.com/asg017/sqlite-vec
|
||||||
|
source-hosting: github
|
||||||
|
tracking: tag
|
||||||
|
vendor-directory: third_party/sqlite3/ext/sqlite-vec
|
||||||
|
skip-vendoring-steps:
|
||||||
|
- update-moz-build
|
||||||
|
exclude:
|
||||||
|
- "**"
|
||||||
|
include:
|
||||||
|
- LICENSE-MIT
|
||||||
|
- VERSION
|
||||||
|
- sqlite-vec.c
|
||||||
|
keep:
|
||||||
|
- moz.yaml
|
||||||
|
- vendor.sh
|
||||||
|
|
||||||
|
update-actions:
|
||||||
|
- action: move-file
|
||||||
|
from: '{vendor_dir}/VERSION'
|
||||||
|
to: '{vendor_dir}/VERSION.txt'
|
||||||
|
# Linking multiple extensions in the same library ends up defining
|
||||||
|
# sqlite3_api multiple times, INIT3 is just an extern declaration.
|
||||||
|
- action: replace-in-file
|
||||||
|
pattern: 'SQLITE_EXTENSION_INIT1'
|
||||||
|
with: 'SQLITE_EXTENSION_INIT3'
|
||||||
|
file: '{vendor_dir}/sqlite-vec.c'
|
||||||
|
- action: run-script
|
||||||
|
script: '{yaml_dir}/vendor.sh'
|
||||||
|
cwd: '{vendor_dir}'
|
||||||
9751
third_party/sqlite3/ext/sqlite-vec/sqlite-vec.c
vendored
Normal file
9751
third_party/sqlite3/ext/sqlite-vec/sqlite-vec.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
41
third_party/sqlite3/ext/sqlite-vec/sqlite-vec.h
vendored
Normal file
41
third_party/sqlite3/ext/sqlite-vec/sqlite-vec.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef SQLITE_VEC_H
|
||||||
|
#define SQLITE_VEC_H
|
||||||
|
|
||||||
|
#ifndef SQLITE_CORE
|
||||||
|
#include "sqlite3ext.h"
|
||||||
|
#else
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SQLITE_VEC_STATIC
|
||||||
|
#define SQLITE_VEC_API
|
||||||
|
#else
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define SQLITE_VEC_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define SQLITE_VEC_API
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SQLITE_VEC_VERSION "v0.1.7-alpha.2"
|
||||||
|
// TODO rm
|
||||||
|
#define SQLITE_VEC_DATE "2025-01-10T23:18:50Z+0000"
|
||||||
|
#define SQLITE_VEC_SOURCE "bdc336d1cf2a2222b6227784bd30c6631603279b"
|
||||||
|
|
||||||
|
|
||||||
|
#define SQLITE_VEC_VERSION_MAJOR 0
|
||||||
|
#define SQLITE_VEC_VERSION_MINOR 1
|
||||||
|
#define SQLITE_VEC_VERSION_PATCH 7
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SQLITE_VEC_API int sqlite3_vec_init(sqlite3 *db, char **pzErrMsg,
|
||||||
|
const sqlite3_api_routines *pApi);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* end of the 'extern "C"' block */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ifndef SQLITE_VEC_H */
|
||||||
28
third_party/sqlite3/ext/sqlite-vec/vendor.sh
vendored
Normal file
28
third_party/sqlite3/ext/sqlite-vec/vendor.sh
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# IMPORTANT: use `./mach vendor third_party/sqlite3/ext-sqlite-vec.yaml`,
|
||||||
|
# don't invoke this script directly.
|
||||||
|
|
||||||
|
# Script to download header from sqlite-vec extension amalgamation.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Retrieve latest version value.
|
||||||
|
echo ""
|
||||||
|
echo "Get extension version."
|
||||||
|
version=`cat VERSION.txt`
|
||||||
|
echo "Github version: $version";
|
||||||
|
|
||||||
|
# Retrieve files and update sources.
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Retrieving amalgamation..."
|
||||||
|
amalgamation_url=""https://github.com/asg017/sqlite-vec/releases/download/v$version/sqlite-vec-$version-amalgamation.zip""
|
||||||
|
wget -t 3 --retry-connrefused -w 5 --random-wait $amalgamation_url -qO amalgamation.zip
|
||||||
|
echo "Unpacking source files..."
|
||||||
|
unzip -p "amalgamation.zip" "sqlite-vec.h" > "sqlite-vec.h"
|
||||||
|
rm -f "amalgamation.zip"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Update complete, please commit and check in your changes."
|
||||||
|
echo ""
|
||||||
11
third_party/sqlite3/readme.txt
vendored
Normal file
11
third_party/sqlite3/readme.txt
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
To vendor a new version of SQLite:
|
||||||
|
|
||||||
|
./mach vendor third_party/sqlite3/moz.yaml
|
||||||
|
|
||||||
|
To vendor new versions of SQLite extensions, check for moz.yaml
|
||||||
|
files in ext/ subfolders. For example, to vendor sqlite-vec:
|
||||||
|
|
||||||
|
./mach vendor third_party/sqlite3/ext/sqlite-vec/moz.yaml
|
||||||
|
|
||||||
|
Vendoring tracks GitHub tags, specific tags can be targeted
|
||||||
|
using the --revision option.
|
||||||
Reference in New Issue
Block a user