mirror of
https://github.com/lancedb/lancedb.git
synced 2026-09-03 12:08:52 +00:00
e773d1e093
Bumps the rust-minor-patch group with 9 updates in the / directory: | Package | From | To | | --- | --- | --- | | [async-trait](https://github.com/dtolnay/async-trait) | `0.1.91` | `0.1.92` | | [log](https://github.com/rust-lang/log) | `0.4.33` | `0.4.34` | | [moka](https://github.com/moka-rs/moka) | `0.12.15` | `0.12.16` | | [uuid](https://github.com/uuid-rs/uuid) | `1.24.0` | `1.26.0` | | [serde_with](https://github.com/jonasbb/serde_with) | `3.21.0` | `3.22.0` | | [roaring](https://github.com/RoaringBitmap/roaring-rs) | `0.11.4` | `0.11.5` | | [napi](https://github.com/napi-rs/napi-rs) | `3.11.0` | `3.12.0` | | [napi-derive](https://github.com/napi-rs/napi-rs) | `3.6.1` | `3.6.3` | | [napi-build](https://github.com/napi-rs/napi-rs) | `2.4.0` | `2.4.1` | Updates `async-trait` from 0.1.91 to 0.1.92 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/dtolnay/async-trait/releases">async-trait's releases</a>.</em></p> <blockquote> <h2>0.1.92</h2> <ul> <li>Resolve double_must_use clippy lint in generated code (<a href="https://redirect.github.com/dtolnay/async-trait/issues/303">#303</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/dtolnay/async-trait/commit/82e7e9edd60f622294373a23c0ce9c0077ad0263"><code>82e7e9e</code></a> Release 0.1.92</li> <li><a href="https://github.com/dtolnay/async-trait/commit/9a35cb87f9366cd992bbc00d430e1b5fe1aa0cdd"><code>9a35cb8</code></a> Merge pull request <a href="https://redirect.github.com/dtolnay/async-trait/issues/303">#303</a> from dtolnay/mustuse</li> <li><a href="https://github.com/dtolnay/async-trait/commit/875ceecb100bab2cf369178633b4791336d92b75"><code>875ceec</code></a> Resolve double_must_use clippy lint</li> <li><a href="https://github.com/dtolnay/async-trait/commit/62993a57bc6a8d5bd3de23fbae48cede333cb925"><code>62993a5</code></a> Raise minimum tested compiler to rust 1.88</li> <li>See full diff in <a href="https://github.com/dtolnay/async-trait/compare/0.1.91...0.1.92">compare view</a></li> </ul> </details> <br /> Updates `log` from 0.4.33 to 0.4.34 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/rust-lang/log/releases">log's releases</a>.</em></p> <blockquote> <h2>0.4.34</h2> <h2>What's Changed</h2> <ul> <li>doc: Add context-logger utility to README by <a href="https://github.com/alekseysidorov"><code>@alekseysidorov</code></a> in <a href="https://redirect.github.com/rust-lang/log/pull/735">rust-lang/log#735</a></li> <li>Add alloc support for boxed loggers by <a href="https://github.com/malezjaa"><code>@malezjaa</code></a> in <a href="https://redirect.github.com/rust-lang/log/pull/737">rust-lang/log#737</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/alekseysidorov"><code>@alekseysidorov</code></a> made their first contribution in <a href="https://redirect.github.com/rust-lang/log/pull/735">rust-lang/log#735</a></li> <li><a href="https://github.com/malezjaa"><code>@malezjaa</code></a> made their first contribution in <a href="https://redirect.github.com/rust-lang/log/pull/737">rust-lang/log#737</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/rust-lang/log/compare/0.4.33...0.4.34">https://github.com/rust-lang/log/compare/0.4.33...0.4.34</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/rust-lang/log/blob/master/CHANGELOG.md">log's changelog</a>.</em></p> <blockquote> <h2>[0.4.34] - 2026-08-22</h2> <h2>What's Changed</h2> <ul> <li>doc: Add context-logger utility to README by <a href="https://github.com/alekseysidorov"><code>@alekseysidorov</code></a> in <a href="https://redirect.github.com/rust-lang/log/pull/735">rust-lang/log#735</a></li> <li>Add alloc support for boxed loggers by <a href="https://github.com/malezjaa"><code>@malezjaa</code></a> in <a href="https://redirect.github.com/rust-lang/log/pull/737">rust-lang/log#737</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/alekseysidorov"><code>@alekseysidorov</code></a> made their first contribution in <a href="https://redirect.github.com/rust-lang/log/pull/735">rust-lang/log#735</a></li> <li><a href="https://github.com/malezjaa"><code>@malezjaa</code></a> made their first contribution in <a href="https://redirect.github.com/rust-lang/log/pull/737">rust-lang/log#737</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/rust-lang/log/compare/0.4.33...0.4.34">https://github.com/rust-lang/log/compare/0.4.33...0.4.34</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/rust-lang/log/commit/8034743dd9d7f7583bd9a670271483d176130911"><code>8034743</code></a> Merge pull request <a href="https://redirect.github.com/rust-lang/log/issues/738">#738</a> from rust-lang/cargo/0.4.34</li> <li><a href="https://github.com/rust-lang/log/commit/7d1e24e3506d4ffa1badf6c9ea357779877adaf0"><code>7d1e24e</code></a> prepare for 0.4.34 release</li> <li><a href="https://github.com/rust-lang/log/commit/3b939b6714616dc32193c12019861c7c518c5edb"><code>3b939b6</code></a> Merge pull request <a href="https://redirect.github.com/rust-lang/log/issues/737">#737</a> from malezjaa/master</li> <li><a href="https://github.com/rust-lang/log/commit/b88266cfed8b287f8c35b2015808b09b056f61af"><code>b88266c</code></a> Add alloc support for boxed loggers</li> <li><a href="https://github.com/rust-lang/log/commit/037d7a58f6ad184abb3afc4db81d37c43a5696ec"><code>037d7a5</code></a> doc: Add context-logger utility to README</li> <li>See full diff in <a href="https://github.com/rust-lang/log/compare/0.4.33...0.4.34">compare view</a></li> </ul> </details> <br /> Updates `moka` from 0.12.15 to 0.12.16 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/moka-rs/moka/releases">moka's releases</a>.</em></p> <blockquote> <h2>v0.12.16</h2> <h2>Version 0.12.16</h2> <h3>Fixed</h3> <ul> <li>Fixed a bug where cache eviction could stall permanently when the cache was configured with the <strong>non-default</strong> LRU eviction policy (<code>EvictionPolicy::lru()</code>) by a race between insert and remove operations on the same key (<a href="https://redirect.github.com/moka-rs/moka/issues/592">#592</a><a href="https://redirect.github.com/moka-rs/moka/pull/592/">gh-pull-0592</a> by <a href="https://github.com/kim-jhyeon"><code>@kim-jhyeon</code></a>, reported in <a href="https://redirect.github.com/moka-rs/moka/issues/590">#590</a><a href="https://redirect.github.com/moka-rs/moka/issues/590/">gh-issue-0590</a>): <ul> <li>This bug was introduced in v0.12.0 and affected <code>sync::Cache</code>, <code>sync::SegmentedCache</code> and <code>future::Cache</code>.</li> <li>A race between applying a write recording for an entry and concurrently removing that entry from the internal concurrent hash table could leave an orphaned node at the front of the LRU queue. Once present, no entry was ever evicted again and the cache grew unboundedly past <code>max_capacity</code>.</li> <li>The same race also affected the default TinyLFU eviction policy, but with a milder symptom: each occurrence permanently leaked one phantom entry slot, causing <code>entry_count</code> and <code>weighted_size</code> to over-report and the usable capacity to shrink by one entry per occurrence. Fixed by the same change.</li> </ul> </li> </ul> <h3>Changed</h3> <ul> <li>Worked around a ThreadSanitizer false positive (<a href="https://redirect.github.com/moka-rs/moka/issues/602">#602</a><a href="https://redirect.github.com/moka-rs/moka/pull/602/">gh-pull-0602</a>): <ul> <li>Replaced the standalone <code>fence(Acquire)</code> in the internal <code>MiniArc</code>'s drop path with an <code>Acquire</code> load of the reference count, so that downstream projects can now run ThreadSanitizer on code using Moka without hitting this false positive.</li> <li><code>std::sync::Arc</code> has a similar workaround.</li> </ul> </li> <li>Raised the minimum version of the <code>crossbeam-epoch</code> crate from <code>v0.9.18</code> to <code>v0.9.20</code> to avoid the following advisory (<a href="https://redirect.github.com/moka-rs/moka/issues/603">#603</a><a href="https://redirect.github.com/moka-rs/moka/pull/603/">gh-pull-0603</a>): <ul> <li>[RUSTSEC-2026-0204] crossbeam-epoch: invalid pointer dereference in <code>fmt::Pointer</code> for <code>Atomic</code> and <code>Shared</code></li> <li>Moka is <em>not</em> affected by this advisory because it never formats these pointer types. However, raising the minimum version prevents downstream lockfiles from resolving to an affected <code>crossbeam-epoch</code> version via Moka.</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/moka-rs/moka/blob/main/CHANGELOG.md">moka's changelog</a>.</em></p> <blockquote> <h2>Version 0.12.16</h2> <h3>Fixed</h3> <ul> <li>Fixed a bug where cache eviction could stall permanently when the cache was configured with the <strong>non-default</strong> LRU eviction policy (<code>EvictionPolicy::lru()</code>) by a race between insert and remove operations on the same key (<a href="https://redirect.github.com/moka-rs/moka/issues/592">#592</a>[gh-pull-0592] by [<a href="https://github.com/kim-jhyeon"><code>@kim-jhyeon</code></a>][gh-kim-jhyeon], reported in <a href="https://redirect.github.com/moka-rs/moka/issues/590">#590</a>[gh-issue-0590]): <ul> <li>This bug was introduced in v0.12.0 and affected <code>sync::Cache</code>, <code>sync::SegmentedCache</code> and <code>future::Cache</code>.</li> <li>A race between applying a write recording for an entry and concurrently removing that entry from the internal concurrent hash table could leave an orphaned node at the front of the LRU queue. Once present, no entry was ever evicted again and the cache grew unboundedly past <code>max_capacity</code>.</li> <li>The same race also affected the default TinyLFU eviction policy, but with a milder symptom: each occurrence permanently leaked one phantom entry slot, causing <code>entry_count</code> and <code>weighted_size</code> to over-report and the usable capacity to shrink by one entry per occurrence. Fixed by the same change.</li> </ul> </li> </ul> <h3>Changed</h3> <ul> <li>Worked around a ThreadSanitizer false positive (<a href="https://redirect.github.com/moka-rs/moka/issues/602">#602</a>[gh-pull-0602]): <ul> <li>Replaced the standalone <code>fence(Acquire)</code> in the internal <code>MiniArc</code>'s drop path with an <code>Acquire</code> load of the reference count, so that downstream projects can now run ThreadSanitizer on code using Moka without hitting this false positive.</li> <li><code>std::sync::Arc</code> has a similar workaround.</li> </ul> </li> <li>Raised the minimum version of the <code>crossbeam-epoch</code> crate from <code>v0.9.18</code> to <code>v0.9.20</code> to avoid the following advisory (<a href="https://redirect.github.com/moka-rs/moka/issues/603">#603</a>[gh-pull-0603]): <ul> <li>[RUSTSEC-2026-0204] crossbeam-epoch: invalid pointer dereference in <code>fmt::Pointer</code> for <code>Atomic</code> and <code>Shared</code></li> <li>Moka is <em>not</em> affected by this advisory because it never formats these pointer types. However, raising the minimum version prevents downstream lockfiles from resolving to an affected <code>crossbeam-epoch</code> version via Moka.</li> </ul> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/moka-rs/moka/commit/a616ec19e8d4ed938caf8b2c88090331d778d5da"><code>a616ec1</code></a> Merge pull request <a href="https://redirect.github.com/moka-rs/moka/issues/604">#604</a> from moka-rs/chore/bump-v0.12.16</li> <li><a href="https://github.com/moka-rs/moka/commit/3b140a627e9faa4ec6a8e682224c7f81efc2b6e4"><code>3b140a6</code></a> Bump the version to v0.12.16</li> <li><a href="https://github.com/moka-rs/moka/commit/51b802dc5cfc9e0da21de04177d79028bfbe5d47"><code>51b802d</code></a> Merge pull request <a href="https://redirect.github.com/moka-rs/moka/issues/603">#603</a> from moka-rs/bump-crossbeam-epoch-floor</li> <li><a href="https://github.com/moka-rs/moka/commit/4f9071684161d59212c32a0e89762c3a5d6385a4"><code>4f90716</code></a> Raise the minimum crossbeam-epoch version to 0.9.20</li> <li><a href="https://github.com/moka-rs/moka/commit/08d0e0458bd95af7f9435ff3ffbba6d1e91647c1"><code>08d0e04</code></a> Merge pull request <a href="https://redirect.github.com/moka-rs/moka/issues/602">#602</a> from moka-rs/gh600-tsan-workaround</li> <li><a href="https://github.com/moka-rs/moka/commit/14447a7cbe441639e2aa3570e411fe493c71c9ac"><code>14447a7</code></a> Restructure the v0.12.16 TSan workaround CHANGELOG entry</li> <li><a href="https://github.com/moka-rs/moka/commit/7b14c37b009a25c9a2ec27e2669dc5f8db7ce254"><code>7b14c37</code></a> Avoid a TSan false positive by replacing the fence in MiniArc::drop</li> <li><a href="https://github.com/moka-rs/moka/commit/05b37c63098473034e7e961c1010284163ad8634"><code>05b37c6</code></a> Merge pull request <a href="https://redirect.github.com/moka-rs/moka/issues/599">#599</a> from moka-rs/gh590-deterministic-tests</li> <li><a href="https://github.com/moka-rs/moka/commit/fc318584d25c0ea01109872da37d395754647e04"><code>fc31858</code></a> Replace private doc references in gh590 test comments</li> <li><a href="https://github.com/moka-rs/moka/commit/57435922036ff4ab9f1b5bd0c3bffe6c8acd9921"><code>5743592</code></a> Improve the v0.12.16 CHANGELOG entry</li> <li>Additional commits viewable in <a href="https://github.com/moka-rs/moka/compare/v0.12.15...v0.12.16">compare view</a></li> </ul> </details> <br /> Updates `uuid` from 1.24.0 to 1.26.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/uuid-rs/uuid/releases">uuid's releases</a>.</em></p> <blockquote> <h2>v1.26.0</h2> <h2>What's Changed</h2> <ul> <li>Add ContextV7::with_additional_precision_bits by <a href="https://github.com/ChrisJr404"><code>@ChrisJr404</code></a> in <a href="https://redirect.github.com/uuid-rs/uuid/pull/904">uuid-rs/uuid#904</a></li> <li>Prepare for 1.26.0 release by <a href="https://github.com/KodrAus"><code>@KodrAus</code></a> in <a href="https://redirect.github.com/uuid-rs/uuid/pull/905">uuid-rs/uuid#905</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/uuid-rs/uuid/compare/1.25.0...v1.26.0">https://github.com/uuid-rs/uuid/compare/1.25.0...v1.26.0</a></p> <h2>1.25.0</h2> <h2>What's Changed</h2> <ul> <li>Add a serde::bytes module that encodes a Uuid as a byte string by <a href="https://github.com/ChrisJr404"><code>@ChrisJr404</code></a> in <a href="https://redirect.github.com/uuid-rs/uuid/pull/902">uuid-rs/uuid#902</a></li> <li>Prepare for 1.25.0 release by <a href="https://github.com/KodrAus"><code>@KodrAus</code></a> in <a href="https://redirect.github.com/uuid-rs/uuid/pull/903">uuid-rs/uuid#903</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/ChrisJr404"><code>@ChrisJr404</code></a> made their first contribution in <a href="https://redirect.github.com/uuid-rs/uuid/pull/902">uuid-rs/uuid#902</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/uuid-rs/uuid/compare/v1.24.1...1.25.0">https://github.com/uuid-rs/uuid/compare/v1.24.1...1.25.0</a></p> <h2>v1.24.1</h2> <h2>What's Changed</h2> <ul> <li>Fix non-ASCII character handling in parse diagnostics by <a href="https://github.com/questfever"><code>@questfever</code></a> in <a href="https://redirect.github.com/uuid-rs/uuid/pull/899">uuid-rs/uuid#899</a></li> <li>Prepare for 1.24.1 release by <a href="https://github.com/KodrAus"><code>@KodrAus</code></a> in <a href="https://redirect.github.com/uuid-rs/uuid/pull/900">uuid-rs/uuid#900</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/questfever"><code>@questfever</code></a> made their first contribution in <a href="https://redirect.github.com/uuid-rs/uuid/pull/899">uuid-rs/uuid#899</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/uuid-rs/uuid/compare/v1.24.0...v1.24.1">https://github.com/uuid-rs/uuid/compare/v1.24.0...v1.24.1</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/uuid-rs/uuid/commit/cdc96a87bddc38d0eb8f894c764e151d2299b4b3"><code>cdc96a8</code></a> Merge pull request <a href="https://redirect.github.com/uuid-rs/uuid/issues/905">#905</a> from uuid-rs/cargo/v1.26.0</li> <li><a href="https://github.com/uuid-rs/uuid/commit/34e4f49c0d50c12f1b3021baf98b8fb91f6407bb"><code>34e4f49</code></a> don't test macros under miri</li> <li><a href="https://github.com/uuid-rs/uuid/commit/d9e7242b37755d844d19fa74559a88e1c46c5206"><code>d9e7242</code></a> update nightly used for miri</li> <li><a href="https://github.com/uuid-rs/uuid/commit/ec16819865b89aa3c52456c8afd0ce9a90f0fcdb"><code>ec16819</code></a> prepare for 1.26.0 release</li> <li><a href="https://github.com/uuid-rs/uuid/commit/162cd208a4521138f1d8ce05b63342ba7ba5c4e6"><code>162cd20</code></a> Merge pull request <a href="https://redirect.github.com/uuid-rs/uuid/issues/904">#904</a> from ChrisJr404/v7-additional-precision-bits</li> <li><a href="https://github.com/uuid-rs/uuid/commit/97eceffa708f87969792af604291d3e4984dfc90"><code>97eceff</code></a> Add ContextV7::with_additional_precision_bits for microsecond clocks</li> <li><a href="https://github.com/uuid-rs/uuid/commit/302e0bf6dc5abf949c06973a37f1f3a093cc2699"><code>302e0bf</code></a> Merge pull request <a href="https://redirect.github.com/uuid-rs/uuid/issues/903">#903</a> from uuid-rs/cargo/1.25.0</li> <li><a href="https://github.com/uuid-rs/uuid/commit/b7ccde885d770d013f413a2685ebe7f38932e1d0"><code>b7ccde8</code></a> prepare for 1.25.0 release</li> <li><a href="https://github.com/uuid-rs/uuid/commit/c62dffbc038034ff045f3009f2536362e313bf34"><code>c62dffb</code></a> Merge pull request <a href="https://redirect.github.com/uuid-rs/uuid/issues/902">#902</a> from ChrisJr404/serde-bytes-module</li> <li><a href="https://github.com/uuid-rs/uuid/commit/8c198b24b1aa55948c0fa4b3433c1954be19c8c8"><code>8c198b2</code></a> Add a serde::bytes module that encodes as a byte string</li> <li>Additional commits viewable in <a href="https://github.com/uuid-rs/uuid/compare/v1.24.0...v1.26.0">compare view</a></li> </ul> </details> <br /> Updates `serde_with` from 3.21.0 to 3.22.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/jonasbb/serde_with/releases">serde_with's releases</a>.</em></p> <blockquote> <h2>serde_with v3.22.0</h2> <h3>Added</h3> <ul> <li>Add support for <code>jiff</code> v0.2 behind the new <code>jiff_0_2</code> feature flag (<a href="https://redirect.github.com/jonasbb/serde_with/issues/936">#936</a>) <code>jiff::SignedDuration</code> works with <code>DurationSeconds</code> and its variants. <code>jiff::Timestamp</code>, <code>jiff::Zoned</code>, and <code>jiff::civil::DateTime</code> work with <code>TimestampSeconds</code> and its variants. Deserializing a <code>jiff::Zoned</code> uses the system time zone, like <code>chrono::DateTime<Local></code>.</li> </ul> <h3>Fixed</h3> <ul> <li>Extend the <a href="https://github.com/jonasbb/serde_with/security/advisories/GHSA-7gcf-g7xr-8hxj">GHSA-7gcf-g7xr-8hxj</a> fix to the duplicate-key-prevention collections. The <code>rust::sets_duplicate_value_is_error</code>, <code>rust::maps_duplicate_key_is_error</code>, <code>rust::sets_last_value_wins</code>, and <code>rust::maps_first_key_wins</code> adapters created their backing sets/maps with <code>with_capacity_and_hasher</code> using the raw deserializer <code>size_hint</code>, bypassing the <code>size_hint_cautious</code> cap added in <a href="https://redirect.github.com/jonasbb/serde_with/issues/966">#966</a> (the <code>clippy.toml</code> <code>disallowed_methods</code> lint only covers <code>Vec::with_capacity</code>, not <code>with_capacity_and_hasher</code>, so these sites were not flagged). Attacker-controlled input claiming a huge length could panic with <code>Hash table capacity overflow</code> before a single element was read. All such constructions now route through <code>size_hint_cautious</code>.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/jonasbb/serde_with/commit/88f576a17c5cd45cea6a30252ef10653dde69fa8"><code>88f576a</code></a> Bump version to 3.22.0 (<a href="https://redirect.github.com/jonasbb/serde_with/issues/991">#991</a>)</li> <li><a href="https://github.com/jonasbb/serde_with/commit/931e664445c2139446b84e76b339924f136a1565"><code>931e664</code></a> Bump version to 3.22.0</li> <li><a href="https://github.com/jonasbb/serde_with/commit/e26930e0b7a6c1e6463086a2447e7cc8fc6f0a24"><code>e26930e</code></a> Bump github/codeql-action from 4.37.3 to 4.37.4 in the github-actions group (...</li> <li><a href="https://github.com/jonasbb/serde_with/commit/92cd5a0bd5c7a80fc7eae90bb99b873c40429aa3"><code>92cd5a0</code></a> Bump github/codeql-action in the github-actions group</li> <li><a href="https://github.com/jonasbb/serde_with/commit/32be66fecc5c1fe4c90ac0230c0af04d1977df53"><code>32be66f</code></a> Guard with_capacity_and_hasher against untrusted size_hint (DoS) (<a href="https://redirect.github.com/jonasbb/serde_with/issues/971">#971</a>)</li> <li><a href="https://github.com/jonasbb/serde_with/commit/33871cd4dd1ecef2c3af0ead9528c8b407c16f04"><code>33871cd</code></a> Merge branch 'master' into fix/duplicate-key-impls-capacity-overflow</li> <li><a href="https://github.com/jonasbb/serde_with/commit/bb1e06484261595c8cec7fd7f4ed33ecdfb951c0"><code>bb1e064</code></a> Change function position within impl (<a href="https://redirect.github.com/jonasbb/serde_with/issues/968">#968</a>)</li> <li><a href="https://github.com/jonasbb/serde_with/commit/202d3dd617d7b5a9db5f490fa752d6ccb48454e8"><code>202d3dd</code></a> Improve the time unit macros to remove unnecessary repetition and make the co...</li> <li><a href="https://github.com/jonasbb/serde_with/commit/b347efb536caf83c850d4808f90503835fd78755"><code>b347efb</code></a> Move the <code>use_duration_signed_ser</code>/<code>*_de</code> macros utils</li> <li><a href="https://github.com/jonasbb/serde_with/commit/65905455527c0abf51f2f906bc08724426b2b922"><code>6590545</code></a> chrono_0_4: Implement the same time unit macro cleanup as jiff_0_2</li> <li>Additional commits viewable in <a href="https://github.com/jonasbb/serde_with/compare/v3.21.0...v3.22.0">compare view</a></li> </ul> </details> <br /> Updates `roaring` from 0.11.4 to 0.11.5 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/RoaringBitmap/roaring-rs/releases">roaring's releases</a>.</em></p> <blockquote> <h2>v0.11.5</h2> <h2>What's Changed</h2> <ul> <li>Implement std Error for IntegerTooSmall by <a href="https://github.com/Kerollmops"><code>@Kerollmops</code></a> in <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/pull/362">RoaringBitmap/roaring-rs#362</a></li> <li>fix: invalid treemap iter advance by <a href="https://github.com/silver-ymz"><code>@silver-ymz</code></a> in <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/pull/360">RoaringBitmap/roaring-rs#360</a></li> <li>Fix off-by-one that corrupts a bitmap in remove_smallest/remove_biggest (<a href="https://redirect.github.com/RoaringBitmap/roaring-rs/issues/359">#359</a>) by <a href="https://github.com/youdie006"><code>@youdie006</code></a> in <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/pull/363">RoaringBitmap/roaring-rs#363</a></li> <li>Upgrade dependencies bump version by <a href="https://github.com/Kerollmops"><code>@Kerollmops</code></a> in <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/pull/364">RoaringBitmap/roaring-rs#364</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/silver-ymz"><code>@silver-ymz</code></a> made their first contribution in <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/pull/360">RoaringBitmap/roaring-rs#360</a></li> <li><a href="https://github.com/youdie006"><code>@youdie006</code></a> made their first contribution in <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/pull/363">RoaringBitmap/roaring-rs#363</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/RoaringBitmap/roaring-rs/compare/v0.11.4...v0.11.5">https://github.com/RoaringBitmap/roaring-rs/compare/v0.11.4...v0.11.5</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/0ce3fc8b55b193ce220253bfbc0c3e09bd171375"><code>0ce3fc8</code></a> Merge pull request <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/issues/364">#364</a> from RoaringBitmap/upgrade-dependencies-bump-version</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/a961a042db8d325515e6b5273a2e9369fe5c931d"><code>a961a04</code></a> Remove the once_cell dependency</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/5e8445b2d6914e8e56d85de340f9156825f4e91b"><code>5e8445b</code></a> Merge pull request <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/issues/363">#363</a> from youdie006/fix/359-interval-remove-boundary</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/bf2961d99fb4da2c540a55eb699228a7bb00a732"><code>bf2961d</code></a> Bump version to v0.11.5</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/048a8b05fcae08636354607f0c00d6e95f262107"><code>048a8b0</code></a> Fix off-by-one that corrupts a bitmap in remove_smallest/remove_biggest</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/27d84f567dd85243194d2b87683262ef43a5dd97"><code>27d84f5</code></a> Merge pull request <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/issues/360">#360</a> from silver-ymz/fix/treemap-iter-advance-across-bitmaps</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/aac2de82a7f9e44fd73d8364de840169447d580b"><code>aac2de8</code></a> Make clippy happy</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/a3d1d54be985fe22c01e882f85c3ee7055ad9c8b"><code>a3d1d54</code></a> Merge pull request <a href="https://redirect.github.com/RoaringBitmap/roaring-rs/issues/362">#362</a> from RoaringBitmap/std-error-for-integer-too-small</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/9a3c33e42c0b14bdd3f296313ee367526092aa81"><code>9a3c33e</code></a> Implement std Error for IntegerTooSmall</li> <li><a href="https://github.com/RoaringBitmap/roaring-rs/commit/f46c0ffe90b6d5d52a93106253bb6fa51a08c137"><code>f46c0ff</code></a> fix: invalid treemap iter advance</li> <li>See full diff in <a href="https://github.com/RoaringBitmap/roaring-rs/compare/v0.11.4...v0.11.5">compare view</a></li> </ul> </details> <br /> Updates `napi` from 3.11.0 to 3.12.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/napi-rs/napi-rs/releases">napi's releases</a>.</em></p> <blockquote> <h2>napi-v3.12.0</h2> <h3>Added</h3> <ul> <li><em>(cli)</em> support non-threaded WASI targets (<a href="https://redirect.github.com/napi-rs/napi-rs/pull/3353">#3353</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/napi-rs/napi-rs/commit/58bd87fa524a837a7c962ab4103e5588557ccd81"><code>58bd87f</code></a> chore: release (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3414">#3414</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/9da87236dbc4fef99f066b7a130f4d0377308d44"><code>9da8723</code></a> chore(release): publish</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/8d22196aa98a1e6e70584561f5446d117d9c802c"><code>8d22196</code></a> chore(deps): update dependency oxc-parser to ^0.142.0 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3422">#3422</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/abc30fbafc2e3967d499cef970c68b3edfefd850"><code>abc30fb</code></a> build(deps): bump postcss from 8.5.17 to 8.5.23 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3421">#3421</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/55421392cbaa24d4df69419e4c6d4958fbcb6a12"><code>5542139</code></a> build(deps): bump fast-xml-parser from 5.9.3 to 5.10.1 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3418">#3418</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/dc4ee8c89cc27ce30e239482199b3b3d786bf8b6"><code>dc4ee8c</code></a> build(deps): bump fast-uri from 3.1.3 to 3.1.4 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3419">#3419</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/050d985196174b4be830cdb813d09e2705258455"><code>050d985</code></a> feat(async-runtime): drain-linger surface + lock-free scheduler internals (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3">#3</a>...</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/e0b87086eefe0e7efeea6d269e9403c4be4ba9aa"><code>e0b8708</code></a> chore(deps): update dependency oxc-parser to ^0.141.0 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3417">#3417</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/fc8494010697d078a93a528c3180271f6f187504"><code>fc84940</code></a> chore(deps): update actions/setup-node action to v7 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3413">#3413</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/ee598db45985ef11e18c7340801c28bb2452b688"><code>ee598db</code></a> build(deps): bump protobufjs from 7.6.4 to 7.6.5 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3410">#3410</a>)</li> <li>Additional commits viewable in <a href="https://github.com/napi-rs/napi-rs/compare/napi-v3.11.0...napi-v3.12.0">compare view</a></li> </ul> </details> <br /> Updates `napi-derive` from 3.6.1 to 3.6.3 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/napi-rs/napi-rs/releases">napi-derive's releases</a>.</em></p> <blockquote> <h2>napi-derive-v3.6.3</h2> <h3>Other</h3> <ul> <li>updated the following local packages: napi-derive-backend</li> </ul> <h2>napi-derive-v3.6.2</h2> <h3>Other</h3> <ul> <li>updated the following local packages: napi-derive-backend</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/napi-rs/napi-rs/commit/956e4525fea6a676ea3680b711382f167b899af9"><code>956e452</code></a> chore: release (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3448">#3448</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/73048f5a7fdbd42cdc2f46f2d5ac60ef27417bfa"><code>73048f5</code></a> chore(release): publish</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/61fae8a1440ad8b7249f3cd7838fc2bafe00a906"><code>61fae8a</code></a> fix(napi): stop unloading addons with live native code, preserve non-Error re...</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/93e86ce167095e84f2be2ae1c66a6c0bb96fec49"><code>93e86ce</code></a> chore(release): publish</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/2c905991899b9f12a0df4072c4bff6d62ef70d26"><code>2c90599</code></a> fix(cli): support npm 12 pack output (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3449">#3449</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/360b1ec99ab0d001147d29e11c416c8338d3d1c9"><code>360b1ec</code></a> fix(wasi): avoid randomness during module registration (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3447">#3447</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/b648c4090e7518ced18c9eca6059d27af3ab511b"><code>b648c40</code></a> build(deps): bump nanoid from 3.3.16 to 3.3.18 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3446">#3446</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/ffda4efff4bc4ebb6bef1f629dd0a6f09dc8f210"><code>ffda4ef</code></a> chore(deps): update dependency js-yaml to v4.3.1 [security] (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3445">#3445</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/387b0dc7986018e44a4a0b466b030dc414170411"><code>387b0dc</code></a> feat(cli): size WASI browser worker pools from navigator.hardwareConcurrency ...</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/61e4346ce3d9a9c13e5c5dd6fb3b7d5e1b1d6e0d"><code>61e4346</code></a> build(deps): bump fast-uri from 3.1.4 to 3.1.5 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3440">#3440</a>)</li> <li>Additional commits viewable in <a href="https://github.com/napi-rs/napi-rs/compare/napi-derive-v3.6.1...napi-derive-v3.6.3">compare view</a></li> </ul> </details> <br /> Updates `napi-build` from 2.4.0 to 2.4.1 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/napi-rs/napi-rs/releases">napi-build's releases</a>.</em></p> <blockquote> <h2>napi-build-v2.4.1</h2> <h3>Fixed</h3> <ul> <li><em>(napi)</em> stop unloading addons with live native code, preserve non-Error rejections, and add the wasm teardown barrier (<a href="https://redirect.github.com/napi-rs/napi-rs/pull/3423">#3423</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/napi-rs/napi-rs/commit/956e4525fea6a676ea3680b711382f167b899af9"><code>956e452</code></a> chore: release (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3448">#3448</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/73048f5a7fdbd42cdc2f46f2d5ac60ef27417bfa"><code>73048f5</code></a> chore(release): publish</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/61fae8a1440ad8b7249f3cd7838fc2bafe00a906"><code>61fae8a</code></a> fix(napi): stop unloading addons with live native code, preserve non-Error re...</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/93e86ce167095e84f2be2ae1c66a6c0bb96fec49"><code>93e86ce</code></a> chore(release): publish</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/2c905991899b9f12a0df4072c4bff6d62ef70d26"><code>2c90599</code></a> fix(cli): support npm 12 pack output (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3449">#3449</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/360b1ec99ab0d001147d29e11c416c8338d3d1c9"><code>360b1ec</code></a> fix(wasi): avoid randomness during module registration (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3447">#3447</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/b648c4090e7518ced18c9eca6059d27af3ab511b"><code>b648c40</code></a> build(deps): bump nanoid from 3.3.16 to 3.3.18 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3446">#3446</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/ffda4efff4bc4ebb6bef1f629dd0a6f09dc8f210"><code>ffda4ef</code></a> chore(deps): update dependency js-yaml to v4.3.1 [security] (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3445">#3445</a>)</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/387b0dc7986018e44a4a0b466b030dc414170411"><code>387b0dc</code></a> feat(cli): size WASI browser worker pools from navigator.hardwareConcurrency ...</li> <li><a href="https://github.com/napi-rs/napi-rs/commit/61e4346ce3d9a9c13e5c5dd6fb3b7d5e1b1d6e0d"><code>61e4346</code></a> build(deps): bump fast-uri from 3.1.4 to 3.1.5 (<a href="https://redirect.github.com/napi-rs/napi-rs/issues/3440">#3440</a>)</li> <li>Additional commits viewable in <a href="https://github.com/napi-rs/napi-rs/compare/napi-build-v2.4.0...napi-build-v2.4.1">compare view</a></li> </ul> </details> <br /> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Will Jones <willjones127@gmail.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
710 lines
22 KiB
Rust
710 lines
22 KiB
Rust
// SPDX-License-Identifier: Apache-2.0
|
|
// SPDX-FileCopyrightText: Copyright The LanceDB Authors
|
|
|
|
use std::sync::Arc;
|
|
|
|
use crate::error::NapiErrorExt;
|
|
use crate::error::convert_error;
|
|
use crate::iterator::RecordBatchIterator;
|
|
use crate::rerankers::RerankHybridCallbackArgs;
|
|
use crate::rerankers::Reranker;
|
|
use crate::util::{parse_distance_type, schema_to_buffer};
|
|
use arrow_array::{
|
|
Array, Float16Array as ArrowFloat16Array, Float32Array as ArrowFloat32Array,
|
|
Float64Array as ArrowFloat64Array, UInt8Array as ArrowUInt8Array,
|
|
};
|
|
use arrow_buffer::ScalarBuffer;
|
|
use half::f16;
|
|
use lancedb::index::scalar::{
|
|
BooleanQuery, BoostQuery, FtsQuery, FullTextSearchQuery, MatchQuery, MultiMatchQuery, Occur,
|
|
Operator, PhraseQuery,
|
|
};
|
|
use lancedb::query::AnalyzePlanDistributedMetrics;
|
|
use lancedb::query::ExecutableQuery;
|
|
use lancedb::query::Query as LanceDbQuery;
|
|
use lancedb::query::QueryBase;
|
|
use lancedb::query::QueryExecutionOptions;
|
|
use lancedb::query::Select;
|
|
use lancedb::query::TakeQuery as LanceDbTakeQuery;
|
|
use lancedb::query::{ColumnOrdering as LanceDbColumnOrdering, VectorQuery as LanceDbVectorQuery};
|
|
use napi::bindgen_prelude::*;
|
|
use napi_derive::napi;
|
|
|
|
#[napi(object)]
|
|
pub struct ColumnOrdering {
|
|
pub ascending: bool,
|
|
pub nulls_first: bool,
|
|
pub column_name: String,
|
|
}
|
|
|
|
impl From<ColumnOrdering> for LanceDbColumnOrdering {
|
|
fn from(value: ColumnOrdering) -> Self {
|
|
match (value.ascending, value.nulls_first) {
|
|
(true, true) => Self::asc_nulls_first(value.column_name),
|
|
(true, false) => Self::asc_nulls_last(value.column_name),
|
|
(false, true) => Self::desc_nulls_first(value.column_name),
|
|
(false, false) => Self::desc_nulls_last(value.column_name),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn analyze_plan_options(
|
|
distributed_metrics: Option<String>,
|
|
) -> napi::Result<QueryExecutionOptions> {
|
|
let analyze_plan_distributed_metrics =
|
|
match distributed_metrics.as_deref().unwrap_or("aggregate") {
|
|
"aggregate" => AnalyzePlanDistributedMetrics::Aggregate,
|
|
"per_worker" => AnalyzePlanDistributedMetrics::PerWorker,
|
|
"full" => AnalyzePlanDistributedMetrics::Full,
|
|
mode => {
|
|
return Err(napi::Error::from_reason(format!(
|
|
"Invalid distributedMetrics value '{}'. Expected one of: \
|
|
'aggregate', 'per_worker', 'full'",
|
|
mode
|
|
)));
|
|
}
|
|
};
|
|
|
|
let mut options = QueryExecutionOptions::default();
|
|
options.analyze_plan_distributed_metrics = analyze_plan_distributed_metrics;
|
|
Ok(options)
|
|
}
|
|
|
|
fn bytes_to_arrow_array(data: Uint8Array, dtype: String) -> napi::Result<Arc<dyn Array>> {
|
|
let buf = arrow_buffer::Buffer::from(data.to_vec());
|
|
let num_bytes = buf.len();
|
|
match dtype.as_str() {
|
|
"float16" => {
|
|
let scalar_buf = ScalarBuffer::<f16>::new(buf, 0, num_bytes / 2);
|
|
Ok(Arc::new(ArrowFloat16Array::new(scalar_buf, None)))
|
|
}
|
|
"float32" => {
|
|
let scalar_buf = ScalarBuffer::<f32>::new(buf, 0, num_bytes / 4);
|
|
Ok(Arc::new(ArrowFloat32Array::new(scalar_buf, None)))
|
|
}
|
|
"float64" => {
|
|
let scalar_buf = ScalarBuffer::<f64>::new(buf, 0, num_bytes / 8);
|
|
Ok(Arc::new(ArrowFloat64Array::new(scalar_buf, None)))
|
|
}
|
|
"uint8" => {
|
|
let scalar_buf = ScalarBuffer::<u8>::new(buf, 0, num_bytes);
|
|
Ok(Arc::new(ArrowUInt8Array::new(scalar_buf, None)))
|
|
}
|
|
_ => Err(napi::Error::from_reason(format!(
|
|
"Unsupported vector dtype: {}. Expected one of: float16, float32, float64, uint8",
|
|
dtype
|
|
))),
|
|
}
|
|
}
|
|
|
|
#[napi]
|
|
pub struct Query {
|
|
inner: LanceDbQuery,
|
|
}
|
|
|
|
#[napi]
|
|
impl Query {
|
|
pub fn new(query: LanceDbQuery) -> Self {
|
|
Self { inner: query }
|
|
}
|
|
|
|
// We cannot call this r#where because NAPI gets confused by the r#
|
|
#[napi]
|
|
pub fn only_if(&mut self, predicate: String) {
|
|
self.inner = self.inner.clone().only_if(predicate);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn full_text_search(&mut self, query: Object) -> napi::Result<()> {
|
|
let query = parse_fts_query(query)?;
|
|
self.inner = self.inner.clone().full_text_search(query);
|
|
Ok(())
|
|
}
|
|
|
|
#[napi]
|
|
pub fn select(&mut self, columns: Vec<(String, String)>) {
|
|
self.inner = self.inner.clone().select(Select::dynamic(&columns));
|
|
}
|
|
|
|
#[napi]
|
|
pub fn select_columns(&mut self, columns: Vec<String>) {
|
|
self.inner = self.inner.clone().select(Select::columns(&columns));
|
|
}
|
|
|
|
#[napi]
|
|
pub fn limit(&mut self, limit: u32) {
|
|
self.inner = self.inner.clone().limit(limit as usize);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn offset(&mut self, offset: u32) {
|
|
self.inner = self.inner.clone().offset(offset as usize);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn nearest_to(&mut self, vector: Float32Array) -> Result<VectorQuery> {
|
|
let inner = self
|
|
.inner
|
|
.clone()
|
|
.nearest_to(vector.as_ref())
|
|
.default_error()?;
|
|
Ok(VectorQuery { inner })
|
|
}
|
|
|
|
#[napi]
|
|
pub fn nearest_to_raw(&mut self, data: Uint8Array, dtype: String) -> Result<VectorQuery> {
|
|
let array = bytes_to_arrow_array(data, dtype)?;
|
|
let inner = self.inner.clone().nearest_to(array).default_error()?;
|
|
Ok(VectorQuery { inner })
|
|
}
|
|
|
|
#[napi]
|
|
pub fn fast_search(&mut self) {
|
|
self.inner = self.inner.clone().fast_search();
|
|
}
|
|
|
|
#[napi]
|
|
pub fn with_row_id(&mut self) {
|
|
self.inner = self.inner.clone().with_row_id();
|
|
}
|
|
|
|
#[napi]
|
|
pub fn use_lsm(&mut self, enable: bool) {
|
|
self.inner = self.inner.clone().use_lsm(enable);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn order_by(&mut self, ordering: Option<Vec<ColumnOrdering>>) -> napi::Result<()> {
|
|
let ordering = ordering.map(|ordering| {
|
|
ordering
|
|
.into_iter()
|
|
.map(LanceDbColumnOrdering::from)
|
|
.collect()
|
|
});
|
|
self.inner = self.inner.clone().order_by(ordering);
|
|
Ok(())
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn output_schema(&self) -> napi::Result<Buffer> {
|
|
let schema = self.inner.output_schema().await.default_error()?;
|
|
schema_to_buffer(&schema)
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn execute(
|
|
&self,
|
|
max_batch_length: Option<u32>,
|
|
timeout_ms: Option<u32>,
|
|
) -> napi::Result<RecordBatchIterator> {
|
|
let mut execution_opts = QueryExecutionOptions::default();
|
|
if let Some(max_batch_length) = max_batch_length {
|
|
execution_opts.max_batch_length = max_batch_length;
|
|
}
|
|
if let Some(timeout_ms) = timeout_ms {
|
|
execution_opts.timeout = Some(std::time::Duration::from_millis(timeout_ms as u64))
|
|
}
|
|
let inner_stream = self
|
|
.inner
|
|
.execute_with_options(execution_opts)
|
|
.await
|
|
.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to execute query stream: {}",
|
|
convert_error(&e)
|
|
))
|
|
})?;
|
|
Ok(RecordBatchIterator::new(inner_stream))
|
|
}
|
|
|
|
#[napi]
|
|
pub async fn explain_plan(&self, verbose: bool) -> napi::Result<String> {
|
|
self.inner.explain_plan(verbose).await.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to retrieve the query plan: {}",
|
|
convert_error(&e)
|
|
))
|
|
})
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn analyze_plan(&self, distributed_metrics: Option<String>) -> napi::Result<String> {
|
|
let options = analyze_plan_options(distributed_metrics)?;
|
|
self.inner
|
|
.analyze_plan_with_options(options)
|
|
.await
|
|
.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to execute analyze plan: {}",
|
|
convert_error(&e)
|
|
))
|
|
})
|
|
}
|
|
}
|
|
|
|
#[napi]
|
|
pub struct VectorQuery {
|
|
inner: LanceDbVectorQuery,
|
|
}
|
|
|
|
#[napi]
|
|
impl VectorQuery {
|
|
#[napi]
|
|
pub fn column(&mut self, column: String) {
|
|
self.inner = self.inner.clone().column(&column);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn add_query_vector(&mut self, vector: Float32Array) -> Result<()> {
|
|
self.inner = self
|
|
.inner
|
|
.clone()
|
|
.add_query_vector(vector.as_ref())
|
|
.default_error()?;
|
|
Ok(())
|
|
}
|
|
|
|
#[napi]
|
|
pub fn add_query_vector_raw(&mut self, data: Uint8Array, dtype: String) -> Result<()> {
|
|
let array = bytes_to_arrow_array(data, dtype)?;
|
|
self.inner = self.inner.clone().add_query_vector(array).default_error()?;
|
|
Ok(())
|
|
}
|
|
|
|
#[napi]
|
|
pub fn distance_type(&mut self, distance_type: String) -> napi::Result<()> {
|
|
let distance_type = parse_distance_type(distance_type)?;
|
|
self.inner = self.inner.clone().distance_type(distance_type);
|
|
Ok(())
|
|
}
|
|
|
|
#[napi]
|
|
pub fn postfilter(&mut self) {
|
|
self.inner = self.inner.clone().postfilter();
|
|
}
|
|
|
|
#[napi]
|
|
pub fn refine_factor(&mut self, refine_factor: u32) {
|
|
self.inner = self.inner.clone().refine_factor(refine_factor);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn nprobes(&mut self, nprobe: u32) {
|
|
self.inner = self.inner.clone().nprobes(nprobe as usize);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn minimum_nprobes(&mut self, minimum_nprobe: u32) -> napi::Result<()> {
|
|
self.inner = self
|
|
.inner
|
|
.clone()
|
|
.minimum_nprobes(minimum_nprobe as usize)
|
|
.default_error()?;
|
|
Ok(())
|
|
}
|
|
|
|
#[napi]
|
|
pub fn maximum_nprobes(&mut self, maximum_nprobes: u32) -> napi::Result<()> {
|
|
let maximum_nprobes = if maximum_nprobes == 0 {
|
|
None
|
|
} else {
|
|
Some(maximum_nprobes as usize)
|
|
};
|
|
self.inner = self
|
|
.inner
|
|
.clone()
|
|
.maximum_nprobes(maximum_nprobes)
|
|
.default_error()?;
|
|
Ok(())
|
|
}
|
|
|
|
#[napi]
|
|
pub fn distance_range(&mut self, lower_bound: Option<f64>, upper_bound: Option<f64>) {
|
|
// napi doesn't support f32, so we have to convert to f32
|
|
self.inner = self
|
|
.inner
|
|
.clone()
|
|
.distance_range(lower_bound.map(|v| v as f32), upper_bound.map(|v| v as f32));
|
|
}
|
|
|
|
#[napi]
|
|
pub fn ef(&mut self, ef: u32) {
|
|
self.inner = self.inner.clone().ef(ef as usize);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn bypass_vector_index(&mut self) {
|
|
self.inner = self.inner.clone().bypass_vector_index()
|
|
}
|
|
|
|
#[napi]
|
|
pub fn only_if(&mut self, predicate: String) {
|
|
self.inner = self.inner.clone().only_if(predicate);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn full_text_search(&mut self, query: Object) -> napi::Result<()> {
|
|
let query = parse_fts_query(query)?;
|
|
self.inner = self.inner.clone().full_text_search(query);
|
|
Ok(())
|
|
}
|
|
|
|
#[napi]
|
|
pub fn select(&mut self, columns: Vec<(String, String)>) {
|
|
self.inner = self.inner.clone().select(Select::dynamic(&columns));
|
|
}
|
|
|
|
#[napi]
|
|
pub fn select_columns(&mut self, columns: Vec<String>) {
|
|
self.inner = self.inner.clone().select(Select::columns(&columns));
|
|
}
|
|
|
|
#[napi]
|
|
pub fn limit(&mut self, limit: u32) {
|
|
self.inner = self.inner.clone().limit(limit as usize);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn offset(&mut self, offset: u32) {
|
|
self.inner = self.inner.clone().offset(offset as usize);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn fast_search(&mut self) {
|
|
self.inner = self.inner.clone().fast_search();
|
|
}
|
|
|
|
#[napi]
|
|
pub fn with_row_id(&mut self) {
|
|
self.inner = self.inner.clone().with_row_id();
|
|
}
|
|
|
|
#[napi]
|
|
pub fn use_lsm(&mut self, enable: bool) {
|
|
self.inner = self.inner.clone().use_lsm(enable);
|
|
}
|
|
|
|
#[napi]
|
|
pub fn rerank(
|
|
&mut self,
|
|
rerank_hybrid: Function<RerankHybridCallbackArgs, Promise<Buffer>>,
|
|
) -> napi::Result<()> {
|
|
let reranker = Reranker::new(rerank_hybrid)?;
|
|
self.inner = self.inner.clone().rerank(Arc::new(reranker));
|
|
Ok(())
|
|
}
|
|
|
|
#[napi]
|
|
pub fn order_by(&mut self, ordering: Option<Vec<ColumnOrdering>>) -> napi::Result<()> {
|
|
let ordering = ordering.map(|ordering| {
|
|
ordering
|
|
.into_iter()
|
|
.map(LanceDbColumnOrdering::from)
|
|
.collect()
|
|
});
|
|
self.inner = self.inner.clone().order_by(ordering);
|
|
Ok(())
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn output_schema(&self) -> napi::Result<Buffer> {
|
|
let schema = self.inner.output_schema().await.default_error()?;
|
|
schema_to_buffer(&schema)
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn execute(
|
|
&self,
|
|
max_batch_length: Option<u32>,
|
|
timeout_ms: Option<u32>,
|
|
) -> napi::Result<RecordBatchIterator> {
|
|
let mut execution_opts = QueryExecutionOptions::default();
|
|
if let Some(max_batch_length) = max_batch_length {
|
|
execution_opts.max_batch_length = max_batch_length;
|
|
}
|
|
if let Some(timeout_ms) = timeout_ms {
|
|
execution_opts.timeout = Some(std::time::Duration::from_millis(timeout_ms as u64))
|
|
}
|
|
let inner_stream = self
|
|
.inner
|
|
.execute_with_options(execution_opts)
|
|
.await
|
|
.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to execute query stream: {}",
|
|
convert_error(&e)
|
|
))
|
|
})?;
|
|
Ok(RecordBatchIterator::new(inner_stream))
|
|
}
|
|
|
|
#[napi]
|
|
pub async fn explain_plan(&self, verbose: bool) -> napi::Result<String> {
|
|
self.inner.explain_plan(verbose).await.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to retrieve the query plan: {}",
|
|
convert_error(&e)
|
|
))
|
|
})
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn analyze_plan(&self, distributed_metrics: Option<String>) -> napi::Result<String> {
|
|
let options = analyze_plan_options(distributed_metrics)?;
|
|
self.inner
|
|
.analyze_plan_with_options(options)
|
|
.await
|
|
.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to execute analyze plan: {}",
|
|
convert_error(&e)
|
|
))
|
|
})
|
|
}
|
|
}
|
|
|
|
#[napi]
|
|
pub struct TakeQuery {
|
|
inner: LanceDbTakeQuery,
|
|
}
|
|
|
|
#[napi]
|
|
impl TakeQuery {
|
|
pub fn new(query: LanceDbTakeQuery) -> Self {
|
|
Self { inner: query }
|
|
}
|
|
|
|
#[napi]
|
|
pub fn select(&mut self, columns: Vec<(String, String)>) {
|
|
self.inner = self.inner.clone().select(Select::dynamic(&columns));
|
|
}
|
|
|
|
#[napi]
|
|
pub fn select_columns(&mut self, columns: Vec<String>) {
|
|
self.inner = self.inner.clone().select(Select::columns(&columns));
|
|
}
|
|
|
|
#[napi]
|
|
pub fn with_row_id(&mut self) {
|
|
self.inner = self.inner.clone().with_row_id();
|
|
}
|
|
|
|
#[napi]
|
|
pub fn use_lsm(&mut self, enable: bool) {
|
|
self.inner = self.inner.clone().use_lsm(enable);
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn output_schema(&self) -> napi::Result<Buffer> {
|
|
let schema = self.inner.output_schema().await.default_error()?;
|
|
schema_to_buffer(&schema)
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn execute(
|
|
&self,
|
|
max_batch_length: Option<u32>,
|
|
timeout_ms: Option<u32>,
|
|
) -> napi::Result<RecordBatchIterator> {
|
|
let mut execution_opts = QueryExecutionOptions::default();
|
|
if let Some(max_batch_length) = max_batch_length {
|
|
execution_opts.max_batch_length = max_batch_length;
|
|
}
|
|
if let Some(timeout_ms) = timeout_ms {
|
|
execution_opts.timeout = Some(std::time::Duration::from_millis(timeout_ms as u64))
|
|
}
|
|
let inner_stream = self
|
|
.inner
|
|
.execute_with_options(execution_opts)
|
|
.await
|
|
.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to execute query stream: {}",
|
|
convert_error(&e)
|
|
))
|
|
})?;
|
|
Ok(RecordBatchIterator::new(inner_stream))
|
|
}
|
|
|
|
#[napi]
|
|
pub async fn explain_plan(&self, verbose: bool) -> napi::Result<String> {
|
|
self.inner.explain_plan(verbose).await.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to retrieve the query plan: {}",
|
|
convert_error(&e)
|
|
))
|
|
})
|
|
}
|
|
|
|
#[napi(catch_unwind)]
|
|
pub async fn analyze_plan(&self, distributed_metrics: Option<String>) -> napi::Result<String> {
|
|
let options = analyze_plan_options(distributed_metrics)?;
|
|
self.inner
|
|
.analyze_plan_with_options(options)
|
|
.await
|
|
.map_err(|e| {
|
|
napi::Error::from_reason(format!(
|
|
"Failed to execute analyze plan: {}",
|
|
convert_error(&e)
|
|
))
|
|
})
|
|
}
|
|
}
|
|
|
|
#[napi]
|
|
#[derive(Debug, Clone)]
|
|
pub struct JsFullTextQuery {
|
|
pub(crate) inner: FtsQuery,
|
|
}
|
|
|
|
#[napi]
|
|
impl JsFullTextQuery {
|
|
#[napi(factory)]
|
|
pub fn match_query(
|
|
query: String,
|
|
column: String,
|
|
boost: f64,
|
|
fuzziness: Option<u32>,
|
|
max_expansions: u32,
|
|
operator: String,
|
|
prefix_length: u32,
|
|
) -> napi::Result<Self> {
|
|
Ok(Self {
|
|
inner: MatchQuery::new(query)
|
|
.with_column(Some(column))
|
|
.with_boost(boost as f32)
|
|
.with_fuzziness(fuzziness)
|
|
.with_max_expansions(max_expansions as usize)
|
|
.with_operator(
|
|
Operator::try_from(operator.as_str()).map_err(|e| {
|
|
napi::Error::from_reason(format!("Invalid operator: {}", e))
|
|
})?,
|
|
)
|
|
.with_prefix_length(prefix_length)
|
|
.into(),
|
|
})
|
|
}
|
|
|
|
#[napi(factory)]
|
|
pub fn phrase_query(query: String, column: String, slop: u32) -> napi::Result<Self> {
|
|
Ok(Self {
|
|
inner: PhraseQuery::new(query)
|
|
.with_column(Some(column))
|
|
.with_slop(slop)
|
|
.into(),
|
|
})
|
|
}
|
|
|
|
#[napi(factory)]
|
|
#[allow(clippy::use_self)] // NAPI doesn't allow Self here but clippy reports it
|
|
pub fn boost_query(
|
|
positive: &JsFullTextQuery,
|
|
negative: &JsFullTextQuery,
|
|
negative_boost: Option<f64>,
|
|
) -> napi::Result<Self> {
|
|
Ok(Self {
|
|
inner: BoostQuery::new(
|
|
positive.inner.clone(),
|
|
negative.inner.clone(),
|
|
negative_boost.map(|v| v as f32),
|
|
)
|
|
.into(),
|
|
})
|
|
}
|
|
|
|
#[napi(factory)]
|
|
pub fn multi_match_query(
|
|
query: String,
|
|
columns: Vec<String>,
|
|
boosts: Option<Vec<f64>>,
|
|
operator: String,
|
|
) -> napi::Result<Self> {
|
|
let q = match boosts {
|
|
Some(boosts) => MultiMatchQuery::try_new(query, columns)
|
|
.and_then(|q| q.try_with_boosts(boosts.into_iter().map(|v| v as f32).collect())),
|
|
None => MultiMatchQuery::try_new(query, columns),
|
|
}
|
|
.map_err(|e| {
|
|
napi::Error::from_reason(format!("Failed to create multi match query: {}", e))
|
|
})?;
|
|
|
|
let operator = Operator::try_from(operator.as_str()).map_err(|e| {
|
|
napi::Error::from_reason(format!("Invalid operator for multi match query: {}", e))
|
|
})?;
|
|
|
|
Ok(Self {
|
|
inner: q.with_operator(operator).into(),
|
|
})
|
|
}
|
|
|
|
#[napi(factory)]
|
|
#[allow(clippy::use_self)] // NAPI doesn't allow Self here but clippy reports it
|
|
pub fn boolean_query(queries: Vec<(String, &JsFullTextQuery)>) -> napi::Result<Self> {
|
|
let mut sub_queries = Vec::with_capacity(queries.len());
|
|
for (occur, q) in queries {
|
|
let occur = Occur::try_from(occur.as_str())
|
|
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
|
|
sub_queries.push((occur, q.inner.clone()));
|
|
}
|
|
Ok(Self {
|
|
inner: BooleanQuery::new(sub_queries).into(),
|
|
})
|
|
}
|
|
|
|
#[napi(getter)]
|
|
pub fn query_type(&self) -> String {
|
|
match self.inner {
|
|
FtsQuery::Match(_) => "match".to_string(),
|
|
FtsQuery::Phrase(_) => "phrase".to_string(),
|
|
FtsQuery::Boost(_) => "boost".to_string(),
|
|
FtsQuery::MultiMatch(_) => "multi_match".to_string(),
|
|
FtsQuery::Boolean(_) => "boolean".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn parse_fts_query(query: Object) -> napi::Result<FullTextSearchQuery> {
|
|
// `&JsFullTextQuery` recovers a native class reference through napi's borrow-tracked
|
|
// path, which is only usable from generated `#[napi]` argument conversion. This is a
|
|
// manual lookup on a nested `Object` property instead, so use `ClassInstance`, which
|
|
// unwraps the class without requiring a borrow scope.
|
|
if let Ok(Some(query)) = query.get::<ClassInstance<JsFullTextQuery>>("query") {
|
|
Ok(FullTextSearchQuery::new_query(query.inner.clone()))
|
|
} else if let Ok(Some(query_text)) = query.get::<String>("query") {
|
|
let mut query_text = query_text;
|
|
let columns = query.get::<Option<Vec<String>>>("columns")?.flatten();
|
|
|
|
let is_phrase =
|
|
query_text.len() >= 2 && query_text.starts_with('"') && query_text.ends_with('"');
|
|
let is_multi_match = columns.as_ref().map(|cols| cols.len() > 1).unwrap_or(false);
|
|
|
|
if is_phrase {
|
|
// Remove the surrounding quotes for phrase queries
|
|
query_text = query_text[1..query_text.len() - 1].to_string();
|
|
}
|
|
|
|
let query: FtsQuery = match (is_phrase, is_multi_match) {
|
|
(false, _) => MatchQuery::new(query_text).into(),
|
|
(true, false) => PhraseQuery::new(query_text).into(),
|
|
(true, true) => {
|
|
return Err(napi::Error::from_reason(
|
|
"Phrase queries cannot be used with multiple columns.",
|
|
));
|
|
}
|
|
};
|
|
let mut query = FullTextSearchQuery::new_query(query);
|
|
if let Some(cols) = columns
|
|
&& !cols.is_empty()
|
|
{
|
|
query = query.with_columns(&cols).map_err(|e| {
|
|
napi::Error::from_reason(format!("Failed to set full text search columns: {}", e))
|
|
})?;
|
|
}
|
|
Ok(query)
|
|
} else {
|
|
Err(napi::Error::from_reason(
|
|
"Invalid full text search query object".to_string(),
|
|
))
|
|
}
|
|
}
|