From 698f329598bcfa8a5bf0feedfdd4344a4cdc7e4d Mon Sep 17 00:00:00 2001 From: LuQQiu Date: Wed, 26 Mar 2025 11:22:40 -0700 Subject: [PATCH] feat: add explain plan remote api (#2263) Add explain plan remote api --- Cargo.lock | 265 +++++++++++++++----------- python/python/lancedb/_lancedb.pyi | 2 +- python/python/lancedb/query.py | 2 +- python/python/lancedb/remote/table.py | 3 + python/python/lancedb/table.py | 11 +- python/src/query.rs | 4 +- rust/lancedb/src/remote/table.rs | 86 +++++++-- 7 files changed, 235 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5433b2f5..b6d763a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,7 +221,7 @@ dependencies = [ "arrow-data", "arrow-schema", "chrono", - "chrono-tz 0.10.1", + "chrono-tz 0.10.3", "half", "hashbrown 0.15.2", "num", @@ -229,9 +229,9 @@ dependencies = [ [[package]] name = "arrow-buffer" -version = "54.2.1" +version = "54.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e899dade2c3b7f5642eb8366cfd898958bcca099cde6dfea543c7e8d3ad88d4" +checksum = "bc6ed265c73f134a583d02c3cab5e16afab9446d8048ede8707e31f85fad58a0" dependencies = [ "bytes", "half", @@ -277,9 +277,9 @@ dependencies = [ [[package]] name = "arrow-data" -version = "54.2.1" +version = "54.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a329fb064477c9ec5f0870d2f5130966f91055c7c5bce2b3a084f116bc28c3b" +checksum = "5f2cebf504bb6a92a134a87fff98f01b14fbb3a93ecf7aef90cd0f888c5fffa4" dependencies = [ "arrow-buffer", "arrow-schema", @@ -350,9 +350,9 @@ dependencies = [ [[package]] name = "arrow-schema" -version = "54.2.1" +version = "54.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85934a9d0261e0fa5d4e2a5295107d743b543a6e0484a835d4b8db2da15306f9" +checksum = "a5c53775bba63f319189f366d2b86e9a8889373eb198f07d8544938fc9f8ed9a" dependencies = [ "bitflags 2.9.0", ] @@ -433,7 +433,7 @@ dependencies = [ "bytes", "derive_builder", "futures", - "rand", + "rand 0.8.5", "reqwest", "reqwest-eventsource", "secrecy", @@ -1014,7 +1014,7 @@ dependencies = [ "getrandom 0.2.15", "instant", "pin-project-lite", - "rand", + "rand 0.8.5", "tokio", ] @@ -1168,9 +1168,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "675f87afced0413c9bb02843499dbbd3882a237645883f71a2b59644a6d2f753" +checksum = "b17679a8d69b6d7fd9cd9801a536cec9fa5e5970b69f9d4747f70b39b031f5e7" dependencies = [ "arrayref", "arrayvec", @@ -1269,7 +1269,7 @@ dependencies = [ "memmap2 0.9.5", "num-traits", "num_cpus", - "rand", + "rand 0.8.5", "rand_distr", "rayon", "safetensors", @@ -1304,7 +1304,7 @@ dependencies = [ "candle-nn", "fancy-regex", "num-traits", - "rand", + "rand 0.8.5", "rayon", "serde", "serde_json", @@ -1314,9 +1314,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.16" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "jobserver", "libc", @@ -1384,12 +1384,12 @@ dependencies = [ [[package]] name = "chrono-tz" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c6ac4f2c0bf0f44e9161aec9675e1050aa4a530663c4a9e37e108fa948bca9f" +checksum = "efdce149c370f133a071ca8ef6ea340b7b88748ab0810097a9e2976eaa34b4f3" dependencies = [ "chrono", - "chrono-tz-build 0.4.0", + "chrono-tz-build 0.4.1", "phf", ] @@ -1406,9 +1406,9 @@ dependencies = [ [[package]] name = "chrono-tz-build" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94fea34d77a245229e7746bd2beb786cd2a896f306ff491fb8cecb3074b10a7" +checksum = "8f10f8c9340e31fc120ff885fcdb54a0b48e474bbd77cab557f0c30a3e569402" dependencies = [ "parse-zoneinfo", "phf_codegen", @@ -1688,7 +1688,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -1699,7 +1699,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1834,7 +1834,7 @@ dependencies = [ "log", "object_store", "parking_lot", - "rand", + "rand 0.8.5", "regex", "sqlparser 0.53.0", "tempfile", @@ -1919,7 +1919,7 @@ dependencies = [ "log", "object_store", "parking_lot", - "rand", + "rand 0.8.5", "tempfile", "url", ] @@ -1979,7 +1979,7 @@ dependencies = [ "itertools 0.14.0", "log", "md-5", - "rand", + "rand 0.8.5", "regex", "sha2", "unicode-segmentation", @@ -2261,9 +2261,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" dependencies = [ "powerfmt", "serde", @@ -2414,7 +2414,7 @@ dependencies = [ "generic-array", "group", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -2597,7 +2597,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -2675,7 +2675,7 @@ name = "fsst" version = "0.25.1" source = "git+https://github.com/lancedb/lance.git?tag=v0.25.1-beta.3#33634d3b2e8f6a54e63a97721c7fcd31206e999a" dependencies = [ - "rand", + "rand 0.8.5", ] [[package]] @@ -2935,14 +2935,16 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", + "js-sys", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -2964,7 +2966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -3016,7 +3018,7 @@ dependencies = [ "cfg-if", "crunchy", "num-traits", - "rand", + "rand 0.8.5", "rand_distr", ] @@ -3085,7 +3087,7 @@ dependencies = [ "libc", "log", "num_cpus", - "rand", + "rand 0.8.5", "reqwest", "serde", "serde_json", @@ -3302,14 +3304,15 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core 0.52.0", ] @@ -3583,9 +3586,9 @@ checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8" [[package]] name = "jiff" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e" +checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" dependencies = [ "jiff-static", "log", @@ -3596,9 +3599,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" +checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" dependencies = [ "proc-macro2", "quote", @@ -3693,7 +3696,7 @@ dependencies = [ "pin-project", "prost", "prost-types", - "rand", + "rand 0.8.5", "roaring", "serde", "serde_json", @@ -3721,7 +3724,7 @@ dependencies = [ "getrandom 0.2.15", "half", "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -3750,7 +3753,7 @@ dependencies = [ "object_store", "pin-project", "prost", - "rand", + "rand 0.8.5", "roaring", "serde_json", "snafu", @@ -3819,7 +3822,7 @@ dependencies = [ "prost", "prost-build", "prost-types", - "rand", + "rand 0.8.5", "seq-macro", "snafu", "tokio", @@ -3902,7 +3905,7 @@ dependencies = [ "object_store", "prost", "prost-build", - "rand", + "rand 0.8.5", "rayon", "roaring", "serde", @@ -3946,7 +3949,7 @@ dependencies = [ "path_abs", "pin-project", "prost", - "rand", + "rand 0.8.5", "shellexpand", "snafu", "tokio", @@ -3972,7 +3975,7 @@ dependencies = [ "lazy_static", "log", "num-traits", - "rand", + "rand 0.8.5", "rayon", "tokio", "tracing", @@ -4006,7 +4009,7 @@ dependencies = [ "prost", "prost-build", "prost-types", - "rand", + "rand 0.8.5", "rangemap", "roaring", "serde", @@ -4027,7 +4030,7 @@ dependencies = [ "arrow-schema", "lance-arrow", "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -4083,7 +4086,7 @@ dependencies = [ "pin-project", "polars", "polars-arrow", - "rand", + "rand 0.8.5", "random_word", "regex", "reqwest", @@ -4329,9 +4332,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "loom" @@ -4603,9 +4606,9 @@ checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b" [[package]] name = "napi" -version = "2.16.16" +version = "2.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "839ae2ee5e62c6348669c50098b187c08115bd3cced658c9c0bf945fca0fec83" +checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" dependencies = [ "bitflags 2.9.0", "ctor", @@ -4617,9 +4620,9 @@ dependencies = [ [[package]] name = "napi-build" -version = "2.1.5" +version = "2.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40685973218af4aa4b42486652692c294c44b5a67e4b2202df721c9063f2e51c" +checksum = "e28acfa557c083f6e254a786e01ba253fc56f18ee000afcd4f79af735f73a6da" [[package]] name = "napi-derive" @@ -4884,7 +4887,7 @@ dependencies = [ "parking_lot", "percent-encoding", "quick-xml", - "rand", + "rand 0.8.5", "reqwest", "ring", "rustls-pemfile 2.2.0", @@ -5085,7 +5088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand", + "rand 0.8.5", ] [[package]] @@ -5257,7 +5260,7 @@ dependencies = [ "polars-error", "polars-row", "polars-utils", - "rand", + "rand 0.8.5", "rand_distr", "rayon", "regex", @@ -5456,7 +5459,7 @@ dependencies = [ "polars-error", "polars-lazy", "polars-plan", - "rand", + "rand 0.8.5", "serde", "serde_json", "sqlparser 0.39.0", @@ -5530,7 +5533,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.23", + "zerocopy 0.8.24", ] [[package]] @@ -5734,11 +5737,12 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", @@ -5748,17 +5752,18 @@ dependencies = [ "thiserror 2.0.12", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ "bytes", - "getrandom 0.2.15", - "rand", + "getrandom 0.3.2", + "rand 0.9.0", "ring", "rustc-hash 2.1.1", "rustls 0.23.25", @@ -5793,6 +5798,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "radium" version = "0.7.0" @@ -5806,8 +5817,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy 0.8.24", ] [[package]] @@ -5817,7 +5839,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -5829,6 +5861,15 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + [[package]] name = "rand_distr" version = "0.4.3" @@ -5836,7 +5877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -5849,7 +5890,7 @@ dependencies = [ "brotli", "once_cell", "paste", - "rand", + "rand 0.8.5", "unicase", ] @@ -6012,9 +6053,9 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "async-compression", "base64 0.22.1", @@ -6194,9 +6235,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ "bitflags 2.9.0", "errno", @@ -6600,7 +6641,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ "digest", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -6752,9 +6793,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stacker" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9156ebd5870ef293bfb43f91c7a74528d363ec0d424afe24160ed5a4343d08a" +checksum = "601f9201feb9b09c00266478bf459952b9ef9a6b94edb2f21eba14ab681a60a9" dependencies = [ "cc", "cfg-if", @@ -7096,14 +7137,14 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ "fastrand", - "getrandom 0.3.1", + "getrandom 0.3.2", "once_cell", - "rustix 1.0.2", + "rustix 1.0.3", "windows-sys 0.59.0", ] @@ -7159,9 +7200,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.39" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -7174,15 +7215,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -7240,7 +7281,7 @@ dependencies = [ "monostate", "onig", "paste", - "rand", + "rand 0.8.5", "rayon", "rayon-cond", "regex", @@ -7579,7 +7620,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.2", "serde", ] @@ -7628,9 +7669,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] @@ -7857,9 +7898,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-registry" @@ -7867,7 +7908,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-result 0.3.1", + "windows-result 0.3.2", "windows-strings 0.3.1", "windows-targets 0.53.0", ] @@ -7883,9 +7924,9 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ "windows-link", ] @@ -8198,9 +8239,9 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags 2.9.0", ] @@ -8273,11 +8314,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ - "zerocopy-derive 0.8.23", + "zerocopy-derive 0.8.24", ] [[package]] @@ -8293,9 +8334,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", @@ -8377,18 +8418,18 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "7.2.3" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.14+zstd.1.5.7" +version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ "cc", "pkg-config", diff --git a/python/python/lancedb/_lancedb.pyi b/python/python/lancedb/_lancedb.pyi index 38a5f14f..975f3d9e 100644 --- a/python/python/lancedb/_lancedb.pyi +++ b/python/python/lancedb/_lancedb.pyi @@ -94,6 +94,7 @@ class Query: def nearest_to(self, query_vec: pa.Array) -> VectorQuery: ... def nearest_to_text(self, query: dict) -> FTSQuery: ... async def execute(self, max_batch_length: Optional[int]) -> RecordBatchStream: ... + async def explain_plan(self, verbose: Optional[bool]) -> str: ... def to_query_request(self) -> PyQueryRequest: ... class FTSQuery: @@ -108,7 +109,6 @@ class FTSQuery: def add_query_vector(self, query_vec: pa.Array) -> None: ... def nearest_to(self, query_vec: pa.Array) -> HybridQuery: ... async def execute(self, max_batch_length: Optional[int]) -> RecordBatchStream: ... - async def explain_plan(self) -> str: ... def to_query_request(self) -> PyQueryRequest: ... class VectorQuery: diff --git a/python/python/lancedb/query.py b/python/python/lancedb/query.py index 9399c43b..2af6563c 100644 --- a/python/python/lancedb/query.py +++ b/python/python/lancedb/query.py @@ -657,7 +657,7 @@ class LanceQueryBuilder(ABC): ------- plan : str """ # noqa: E501 - return self._table._explain_plan(self.to_query_object()) + return self._table._explain_plan(self.to_query_object(), verbose=verbose) def vector(self, vector: Union[np.ndarray, list]) -> Self: """Set the vector to search for. diff --git a/python/python/lancedb/remote/table.py b/python/python/lancedb/remote/table.py index 2a362996..00dd9a0b 100644 --- a/python/python/lancedb/remote/table.py +++ b/python/python/lancedb/remote/table.py @@ -365,6 +365,9 @@ class RemoteTable(Table): return pa.RecordBatchReader.from_batches(async_iter.schema, iter_sync()) + def _explain_plan(self, query: Query, verbose: Optional[bool] = False) -> str: + return LOOP.run(self._table._explain_plan(query, verbose)) + def merge_insert(self, on: Union[str, Iterable[str]]) -> LanceMergeInsertBuilder: """Returns a [`LanceMergeInsertBuilder`][lancedb.merge.LanceMergeInsertBuilder] that can be used to create a "merge insert" operation. diff --git a/python/python/lancedb/table.py b/python/python/lancedb/table.py index a1ca619b..7fed0127 100644 --- a/python/python/lancedb/table.py +++ b/python/python/lancedb/table.py @@ -1007,6 +1007,9 @@ class Table(ABC): self, query: Query, batch_size: Optional[int] = None ) -> pa.RecordBatchReader: ... + @abstractmethod + def _explain_plan(self, query: Query, verbose: Optional[bool] = False) -> str: ... + @abstractmethod def _do_merge( self, @@ -2292,8 +2295,8 @@ class LanceTable(Table): return pa.RecordBatchReader.from_batches(async_iter.schema, iter_sync()) - def _explain_plan(self, query: Query) -> str: - return LOOP.run(self._table._explain_plan(query)) + def _explain_plan(self, query: Query, verbose: Optional[bool] = False) -> str: + return LOOP.run(self._table._explain_plan(query, verbose)) def _do_merge( self, @@ -3358,10 +3361,10 @@ class AsyncTable: return await async_query.to_batches(max_batch_length=batch_size) - async def _explain_plan(self, query: Query) -> str: + async def _explain_plan(self, query: Query, verbose: Optional[bool]) -> str: # This method is used by the sync table async_query = self._sync_query_to_async(query) - return await async_query.explain_plan() + return await async_query.explain_plan(verbose) async def _do_merge( self, diff --git a/python/src/query.rs b/python/src/query.rs index 7b941356..d86712a4 100644 --- a/python/src/query.rs +++ b/python/src/query.rs @@ -271,7 +271,7 @@ impl Query { }) } - fn explain_plan(self_: PyRef<'_, Self>, verbose: bool) -> PyResult> { + pub fn explain_plan(self_: PyRef<'_, Self>, verbose: bool) -> PyResult> { let inner = self_.inner.clone(); future_into_py(self_.py(), async move { inner @@ -470,7 +470,7 @@ impl VectorQuery { }) } - fn explain_plan(self_: PyRef<'_, Self>, verbose: bool) -> PyResult> { + pub fn explain_plan(self_: PyRef<'_, Self>, verbose: bool) -> PyResult> { let inner = self_.inner.clone(); future_into_py(self_.py(), async move { inner diff --git a/rust/lancedb/src/remote/table.rs b/rust/lancedb/src/remote/table.rs index 8a83e39b..e2bc0c8f 100644 --- a/rust/lancedb/src/remote/table.rs +++ b/rust/lancedb/src/remote/table.rs @@ -325,24 +325,11 @@ impl RemoteTable { ) -> Result>>> { let request = self.client.post(&format!("/v1/table/{}/query/", self.name)); - let version = self.current_version().await; - let mut body = serde_json::json!({ "version": version }); - - let requests = match query { - AnyQuery::Query(query) => { - Self::apply_query_params(&mut body, query)?; - // Empty vector can be passed if no vector search is performed. - body["vector"] = serde_json::Value::Array(Vec::new()); - vec![request.json(&body)] - } - AnyQuery::VectorQuery(query) => { - let bodies = self.apply_vector_query_params(body, query)?; - bodies - .into_iter() - .map(|body| request.try_clone().unwrap().json(&body)) - .collect() - } - }; + let query_bodies = self.prepare_query_bodies(query).await?; + let requests: Vec = query_bodies + .into_iter() + .map(|body| request.try_clone().unwrap().json(&body)) + .collect(); let futures = requests.into_iter().map(|req| async move { let (request_id, response) = self.client.send(req, true).await?; @@ -351,6 +338,22 @@ impl RemoteTable { let streams = futures::future::try_join_all(futures).await?; Ok(streams) } + + async fn prepare_query_bodies(&self, query: &AnyQuery) -> Result> { + let version = self.current_version().await; + let base_body = serde_json::json!({ "version": version }); + + match query { + AnyQuery::Query(query) => { + let mut body = base_body.clone(); + Self::apply_query_params(&mut body, query)?; + // Empty vector can be passed if no vector search is performed. + body["vector"] = serde_json::Value::Array(Vec::new()); + Ok(vec![body]) + } + AnyQuery::VectorQuery(query) => self.apply_vector_query_params(base_body, query), + } + } } #[derive(Deserialize)] @@ -559,6 +562,52 @@ impl BaseTable for RemoteTable { )?)) } } + + async fn explain_plan(&self, query: &AnyQuery, verbose: bool) -> Result { + let base_request = self + .client + .post(&format!("/v1/table/{}/explain_plan/", self.name)); + + let query_bodies = self.prepare_query_bodies(query).await?; + let requests: Vec = query_bodies + .into_iter() + .map(|query_body| { + let explain_request = serde_json::json!({ + "verbose": verbose, + "query": query_body + }); + + base_request.try_clone().unwrap().json(&explain_request) + }) + .collect::>(); + + let futures = requests.into_iter().map(|req| async move { + let (request_id, response) = self.client.send(req, true).await?; + let response = self.check_table_response(&request_id, response).await?; + let body = response.text().await.err_to_http(request_id.clone())?; + + serde_json::from_str(&body).map_err(|e| Error::Http { + source: format!("Failed to parse explain plan: {}", e).into(), + request_id, + status_code: None, + }) + }); + + let plan_texts = futures::future::try_join_all(futures).await?; + let final_plan = if plan_texts.len() > 1 { + plan_texts + .into_iter() + .enumerate() + .map(|(i, plan)| format!("--- Plan #{} ---\n{}", i + 1, plan)) + .collect::>() + .join("\n\n") + } else { + plan_texts.into_iter().next().unwrap_or_default() + }; + + Ok(final_plan) + } + async fn update(&self, update: UpdateBuilder) -> Result { self.check_mutable().await?; let request = self @@ -581,6 +630,7 @@ impl BaseTable for RemoteTable { Ok(0) // TODO: support returning number of modified rows once supported in SaaS. } + async fn delete(&self, predicate: &str) -> Result<()> { self.check_mutable().await?; let body = serde_json::json!({ "predicate": predicate });