diff --git a/Dockerfile b/Dockerfile index b0b429803e..6d25fc2a13 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,7 +50,10 @@ RUN apt-get update && apt-get install -y clang=1:19.0* libclang-dev=1:19.0* cmak COPY ./backend/windmill-duckdb-ffi-internal . +# The `duckdb` crate comes from a git dependency (a fork carrying an engine patch), +# which cargo checks out under $CARGO_HOME/git rather than the registry cache. RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/git \ --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ cargo build --release -p windmill_duckdb_ffi_internal diff --git a/backend/CLAUDE.md b/backend/CLAUDE.md index f686e94493..9067058419 100644 --- a/backend/CLAUDE.md +++ b/backend/CLAUDE.md @@ -15,6 +15,8 @@ worktrees (keyed by the crate's `Cargo.lock`), so a fresh worktree reuses it and the build is near-instant — you don't pay the full compile per worktree. Editing the FFI crate's own source falls back to an isolated per-worktree `./target`. + The engine is a **patched fork** of duckdb-rs, not the crates.io crate — read + `docs/duckdb-isolation.md` before bumping it or touching the isolation transform. - **Running data pipelines (DuckLake) from source**: see the section below — a plain build advertises the `duckdb` tag but cannot execute DuckDB scripts and has no working S3 proxy. diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index 4b8eb8fe9d..d94d87dff2 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -f8d523195e40fd1d740595dcab6ce5cdc1bdbf09 +88568d11162ffa11723e7955e613224bab4f0568 diff --git a/backend/windmill-duckdb-ffi-internal/Cargo.lock b/backend/windmill-duckdb-ffi-internal/Cargo.lock index 93a98d58de..85bf26291b 100644 --- a/backend/windmill-duckdb-ffi-internal/Cargo.lock +++ b/backend/windmill-duckdb-ffi-internal/Cargo.lock @@ -35,18 +35,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] @@ -62,15 +62,15 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "arrow" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d441fdda254b65f3e9025910eb2c2066b6295d9c8ed409522b8d2ace1ff8574c" +checksum = "6cfdd0833e32a9874d2b55089333ad310c0be208aafa277385ce2461dec90be3" dependencies = [ "arrow-arith", "arrow-array", @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "arrow-arith" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced5406f8b720cc0bc3aa9cf5758f93e8593cda5490677aa194e4b4b383f9a59" +checksum = "0a41203398f0eaa6f7ec8e62c0da742a21abf282c148fc157f6c35c90e29981a" dependencies = [ "arrow-array", "arrow-buffer", @@ -100,9 +100,9 @@ dependencies = [ [[package]] name = "arrow-array" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772bd34cacdda8baec9418d80d23d0fb4d50ef0735685bd45158b83dfeb6e62d" +checksum = "ae33dad492b7df00a217563a7b0ef2874df68a0deea1b1a3acf628152f7f7a69" dependencies = [ "ahash 0.8.12", "arrow-buffer", @@ -110,7 +110,7 @@ dependencies = [ "arrow-schema", "chrono", "half", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "num-complex", "num-integer", "num-traits", @@ -118,9 +118,9 @@ dependencies = [ [[package]] name = "arrow-buffer" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898f4cf1e9598fdb77f356fdf2134feedfd0ee8d5a4e0a5f573e7d0aec16baa4" +checksum = "b9552f96391c005e6ab449fa941420935e7e062489b12b8b1b08879b2163f5b5" dependencies = [ "bytes", "half", @@ -130,9 +130,9 @@ dependencies = [ [[package]] name = "arrow-cast" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0127816c96533d20fc938729f48c52d3e48f99717e7a0b5ade77d742510736d" +checksum = "3a8a327c9649f30d8406995f27642b68df354713cca3baaaf100f076f18d5f34" dependencies = [ "arrow-array", "arrow-buffer", @@ -141,7 +141,7 @@ dependencies = [ "arrow-schema", "arrow-select", "atoi", - "base64", + "base64 0.22.1", "chrono", "comfy-table", "half", @@ -152,9 +152,9 @@ dependencies = [ [[package]] name = "arrow-data" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d10beeab2b1c3bb0b53a00f7c944a178b622173a5c7bcabc3cb45d90238df4" +checksum = "2b24852db04738907e06c04ea61e42fe7fda962a34513022dc0d0e754fb7976b" dependencies = [ "arrow-buffer", "arrow-schema", @@ -165,9 +165,9 @@ dependencies = [ [[package]] name = "arrow-ord" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a7ba279b20b52dad300e68cfc37c17efa65e68623169076855b3a9e941ca5" +checksum = "63a083ec750f5c043f02946b4baf05fcdbb55f4560a3277055caca5cc99f3eb0" dependencies = [ "arrow-array", "arrow-buffer", @@ -178,9 +178,9 @@ dependencies = [ [[package]] name = "arrow-row" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14fe367802f16d7668163ff647830258e6e0aeea9a4d79aaedf273af3bdcd3e" +checksum = "514ba0ef0d4c5896202dae736251ce415abb43a950bed570fb7981b8716c0e4c" dependencies = [ "arrow-array", "arrow-buffer", @@ -191,18 +191,18 @@ dependencies = [ [[package]] name = "arrow-schema" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c30a1365d7a7dc50cc847e54154e6af49e4c4b0fddc9f607b687f29212082743" +checksum = "21ca356ad6425cecb6eb7b28e4f659f1ee7880fbb1a16127de7dd62901efee9e" dependencies = [ "bitflags", ] [[package]] name = "arrow-select" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78694888660a9e8ac949853db393af2a8b8fc82c19ce333132dfa2e72cc1a7fe" +checksum = "c58da39eb3d8350ad4a549e5c2bc49284dac554016c69829310350f1731b0aad" dependencies = [ "ahash 0.8.12", "arrow-array", @@ -214,9 +214,9 @@ dependencies = [ [[package]] name = "arrow-string" -version = "58.1.0" +version = "58.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e04a01f8bb73ce54437514c5fd3ee2aa3e8abe4c777ee5cc55853b1652f79e" +checksum = "b6789b388467525e3271326b6b4915666ecfdf5142aef09779445c954b67543c" dependencies = [ "arrow-array", "arrow-buffer", @@ -240,9 +240,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base64" @@ -251,16 +251,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "bitflags" -version = "2.11.0" +name = "base64" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -270,32 +276,33 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "a88b7ea17d208c4193f2c1e6de3c35fe71f98c96982d5ced308bdcc749ff6e1f" dependencies = [ "borsh-derive", + "bytes", "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +checksum = "d8f347189c62a579b8cd5f80714efa178f52e461dc2e6d701d264f5ff22e566c" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytecheck" @@ -321,9 +328,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cast" @@ -333,9 +340,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.56" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" dependencies = [ "find-msvc-tools", "jobserver", @@ -351,15 +358,15 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -370,14 +377,12 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.1.2" +version = "7.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d05af1e006a2407bedef5af410552494ce5be9090444dbbcb57258c1af3d56" +checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a" dependencies = [ - "crossterm 0.27.0", - "crossterm 0.28.1", - "strum 0.26.3", - "strum_macros 0.26.4", + "crossterm", + "unicode-segmentation", "unicode-width", ] @@ -416,19 +421,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossterm" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" -dependencies = [ - "bitflags", - "crossterm_winapi", - "libc", - "parking_lot", - "winapi", -] - [[package]] name = "crossterm" version = "0.28.1" @@ -436,8 +428,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ "bitflags", + "crossterm_winapi", "parking_lot", "rustix 0.38.44", + "winapi", ] [[package]] @@ -463,14 +457,22 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "diffy" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10aec8f7f9393bd6a4f2762be0ceb012d3cbe2478987258cc9960de148561914" +dependencies = [ + "hashbrown 0.17.1", ] [[package]] name = "duckdb" version = "1.10505.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970e05eedd3f55c435194d9104f90a9b4a79a80d6e73251bc9ff43e178130c4e" +source = "git+https://github.com/windmill-labs/duckdb-rs?rev=475383b71cde3d009ca6eaa0cd733faa52bc7393#475383b71cde3d009ca6eaa0cd733faa52bc7393" dependencies = [ "arrow", "cast", @@ -481,7 +483,7 @@ dependencies = [ "libduckdb-sys", "num-integer", "rust_decimal", - "strum 0.27.2", + "strum", ] [[package]] @@ -514,20 +516,19 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", ] [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de" [[package]] name = "flate2" @@ -546,12 +547,42 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "funty" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -571,10 +602,21 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + [[package]] name = "half" version = "2.7.1" @@ -602,14 +644,17 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash", + "foldhash 0.1.5", ] [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash 0.2.0", +] [[package]] name = "hashlink" @@ -628,9 +673,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "http" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -668,37 +713,38 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", ] [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.90" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dc6f6450b3f6d4ed5b16327f38fed626d375a886159ca555bd7822c0c3a5a6" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] @@ -761,17 +807,17 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.182" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libduckdb-sys" version = "1.10505.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb514dab5e271e849235c1cb98bd65a2ae107fbd619a6740219319c54a71d95" +source = "git+https://github.com/windmill-labs/duckdb-rs?rev=475383b71cde3d009ca6eaa0cd733faa52bc7393#475383b71cde3d009ca6eaa0cd733faa52bc7393" dependencies = [ "cc", + "diffy", "flate2", "pkg-config", "serde", @@ -788,17 +834,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" -[[package]] -name = "libredox" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" -dependencies = [ - "bitflags", - "libc", - "redox_syscall 0.7.2", -] - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -822,15 +857,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "miniz_oxide" @@ -844,9 +879,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", @@ -882,9 +917,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "parking_lot" @@ -904,7 +939,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] @@ -916,10 +951,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] -name = "pkg-config" -version = "0.3.32" +name = "pin-project-lite" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "ppv-lite86" @@ -932,18 +973,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -970,9 +1011,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -983,6 +1024,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -991,9 +1038,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "libc", "rand_chacha", @@ -1028,20 +1075,11 @@ dependencies = [ "bitflags", ] -[[package]] -name = "redox_syscall" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d94dd2f7cd932d4dc02cc8b2b50dfd38bd079a4e5d79198b99743d7fcf9a4b4" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -1051,9 +1089,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -1062,9 +1100,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rend" @@ -1120,9 +1158,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.40.0" +version = "1.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0" +checksum = "be2a24f50780bc85f09cc6ac299bdf1424302742d77221106859c9d8b102126a" dependencies = [ "arrayvec", "borsh", @@ -1132,6 +1170,7 @@ dependencies = [ "rkyv", "serde", "serde_json", + "wasm-bindgen", ] [[package]] @@ -1144,7 +1183,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1162,9 +1201,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.37" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "log", "once_cell", @@ -1177,18 +1216,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "zeroize", ] [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "ring", "rustls-pki-types", @@ -1197,9 +1236,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" @@ -1221,9 +1260,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -1231,29 +1270,29 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "indexmap", "itoa", @@ -1265,15 +1304,15 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "simdutf8" @@ -1282,16 +1321,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] -name = "smallvec" -version = "1.15.1" +name = "slab" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] -name = "strum" -version = "0.26.3" +name = "smallvec" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "strum" @@ -1299,20 +1338,7 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros 0.27.2", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.117", + "strum_macros", ] [[package]] @@ -1324,7 +1350,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -1346,9 +1372,20 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -1363,9 +1400,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" dependencies = [ "filetime", "libc", @@ -1383,9 +1420,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -1398,18 +1435,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.25.13+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" dependencies = [ "indexmap", "toml_datetime", @@ -1419,9 +1456,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow", ] @@ -1432,6 +1469,12 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + [[package]] name = "unicode-width" version = "0.2.2" @@ -1446,11 +1489,11 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" +checksum = "972d7902c8735f2695410b8aed7df6ed12a47394aa1c8d7af49f0497b731a94d" dependencies = [ - "base64", + "base64 0.23.1", "log", "percent-encoding", "rustls", @@ -1462,11 +1505,11 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" +checksum = "da5f78b09e6941e1a0f2e30e695e4b120377b54d5e0aec11b594bb57b3971613" dependencies = [ - "base64", + "base64 0.23.1", "http", "httparse", "log", @@ -1480,9 +1523,9 @@ checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" [[package]] name = "uuid" -version = "1.21.0" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" dependencies = [ "js-sys", "wasm-bindgen", @@ -1508,31 +1551,32 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.113" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60722a937f594b7fde9adb894d7c092fc1bb6612897c46368d18e7a20208eff2" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", "rustversion", + "serde", "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.113" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac8c6395094b6b91c4af293f4c79371c163f9a6f56184d2c9a85f5a95f3950" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1540,31 +1584,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.113" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3fabce6159dc20728033842636887e4877688ae94382766e00b180abac9d60" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.113" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0e091bdb824da87dc01d967388880d017a0a9bc4f3bdc0d86ee9f9336e3bb5" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" dependencies = [ "rustls-pki-types", ] @@ -1624,7 +1668,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -1635,7 +1679,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -1671,6 +1715,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -1746,18 +1799,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.14" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "wyz" @@ -1780,29 +1833,29 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zip" @@ -1820,15 +1873,15 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.6.2" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c745c48e1007337ed136dc99df34128b9faa6ed542d80a1c673cf55a6d7236c8" +checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12" [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zopfli" diff --git a/backend/windmill-duckdb-ffi-internal/Cargo.toml b/backend/windmill-duckdb-ffi-internal/Cargo.toml index ba8b74fac0..c07751465c 100644 --- a/backend/windmill-duckdb-ffi-internal/Cargo.toml +++ b/backend/windmill-duckdb-ffi-internal/Cargo.toml @@ -10,7 +10,14 @@ chrono = "0.4.41" # used to derive itself, so a `decimal`/`numeric` job argument still binds to the # identical DECIMAL. Building one by hand would mean reimplementing that # f64 → (mantissa, scale) inference. -duckdb = { version = "1.10505.0", features = ["bundled", "rust_decimal"] } +# +# Not crates.io: a fork of duckdb-rs 1.10505.0 carrying one patch to the bundled engine — +# see docs/duckdb-isolation.md for why, and for the exit path back to the crates.io crate. +# Pinned by rev, not branch, so `cargo update` cannot move the engine under us. +duckdb = { git = "https://github.com/windmill-labs/duckdb-rs", rev = "475383b71cde3d009ca6eaa0cd733faa52bc7393", features = [ + "bundled", + "rust_decimal", +] } regex = "1" rust_decimal = "1.37.2" serde = { version = "1.0", features = ["derive"] } diff --git a/backend/windmill-duckdb-ffi-internal/build_dev.sh b/backend/windmill-duckdb-ffi-internal/build_dev.sh index b445cc29f3..dab70398a8 100755 --- a/backend/windmill-duckdb-ffi-internal/build_dev.sh +++ b/backend/windmill-duckdb-ffi-internal/build_dev.sh @@ -42,4 +42,11 @@ fi CARGO_NET_GIT_FETCH_WITH_CLI=true cargo build --release -p windmill_duckdb_ffi_internal mkdir -p ../target/debug/ -cp "$CARGO_TARGET_DIR/release/"libwindmill_duckdb_ffi_internal.* ../target/debug/ +# Install through a rename rather than writing over the destination: a running worker +# has the cdylib mapped, and rewriting those pages under it kills the process with +# SIGBUS. A rename swaps the directory entry and leaves the old inode alone. +for artifact in "$CARGO_TARGET_DIR/release/"libwindmill_duckdb_ffi_internal.*; do + dest="../target/debug/$(basename "$artifact")" + cp "$artifact" "$dest.tmp" + mv -f "$dest.tmp" "$dest" +done diff --git a/backend/windmill-duckdb-ffi-internal/src/lib.rs b/backend/windmill-duckdb-ffi-internal/src/lib.rs index 7577d98b94..77b16c7d9c 100644 --- a/backend/windmill-duckdb-ffi-internal/src/lib.rs +++ b/backend/windmill-duckdb-ffi-internal/src/lib.rs @@ -1277,3 +1277,113 @@ fn string_to_duckdb_time(s: &str) -> Result { time.num_seconds_from_midnight() as i64, )) } + +// The bundled engine is not stock (docs/duckdb-isolation.md). These two guard the ways an +// engine bump can drop the patch without anything else noticing. +#[cfg(test)] +mod patched_engine_tests { + /// Too large to be answered within the `memory_limit` `spill_attempt` sets, so the engine + /// has to reach the temp directory to finish it. + const SPILLING_QUERY: &str = "CREATE TABLE t AS SELECT * FROM range(1000000)"; + + fn spill_attempt(temp_dir: &std::path::Path, lock: bool) -> Result<(), String> { + let conn = duckdb::Connection::open_in_memory().unwrap(); + conn.execute_batch(&format!( + "SET threads=2; SET memory_limit='2MB'; SET temp_directory='{}';", + temp_dir.display() + )) + .unwrap(); + if lock { + conn.execute_batch("SET lock_temp_directory=true;") + .map_err(|e| format!("lock_temp_directory rejected: {e}"))?; + } + conn.execute_batch("SET disabled_filesystems='LocalFileSystem';") + .unwrap(); + conn.execute_batch(SPILLING_QUERY) + .map_err(|e| e.to_string()) + } + + #[test] + fn locking_the_temp_directory_keeps_spilling_available() { + let temp_dir = std::env::temp_dir().join(format!( + "windmill_duckdb_spill_{}_{:?}", + std::process::id(), + std::thread::current().id() + )); + std::fs::create_dir_all(&temp_dir).unwrap(); + + // Without the lock the fence reaches the buffer manager too, which is both the + // stock engine's behaviour and the proof that this query really does spill — + // otherwise the assertion below would pass on an unpatched engine. + let unlocked = spill_attempt(&temp_dir, false).expect_err("query did not need to spill"); + assert!( + unlocked.contains("LocalFileSystem has been disabled"), + "expected the fence to stop the spill, got: {unlocked}" + ); + + let locked = spill_attempt(&temp_dir, true); + std::fs::remove_dir_all(&temp_dir).ok(); + locked.expect("a locked temp directory must stay usable behind disabled_filesystems"); + } + + /// The exemption above is only sound while the directory cannot be moved: a script that + /// repointed it would get a write primitive through the very fence it is exempt from. A + /// rebase can drop that half of the patch while leaving the spill test green, so pin it. + #[test] + fn locking_the_temp_directory_makes_it_immutable() { + let conn = duckdb::Connection::open_in_memory().unwrap(); + conn.execute_batch("SET temp_directory='/tmp/windmill_duckdb_lock_probe';") + .unwrap(); + conn.execute_batch("SET lock_temp_directory=true;") + .expect("the patched engine must accept lock_temp_directory"); + + for stmt in [ + "SET temp_directory='/tmp/windmill_duckdb_elsewhere';", + "RESET temp_directory;", + "SET lock_temp_directory=false;", + "RESET lock_temp_directory;", + ] { + let err = conn.execute_batch(stmt).expect_err(&format!( + "`{stmt}` must be refused once the directory is locked" + )); + assert!( + err.to_string().contains("locked"), + "expected a lock refusal for `{stmt}`, got: {err}" + ); + } + } + + // The engine loads the *prebuilt* extensions from extensions.duckdb.org, which are + // compiled against the struct layouts of the release it claims to be. A patch that + // moves a member those extensions reach does not fail — the extension reads the + // neighbouring field and LOAD blocks forever — so this is a timeout, not an assertion. + #[test] + fn prebuilt_extensions_still_load() { + let conn = duckdb::Connection::open_in_memory().unwrap(); + // Fetching the extension needs egress, which loading it back — the part this guards — + // does not. Skipping keeps a developer offline from seeing a failure they can't act on, + // but never in CI, where a skip and a pass would be indistinguishable. + if let Err(e) = conn.execute_batch("INSTALL httpfs;") { + assert!( + std::env::var_os("CI").is_none(), + "could not install httpfs, so the extension-load guard did not run: {e}" + ); + eprintln!("skipping: INSTALL httpfs failed ({e})"); + return; + } + let (tx, rx) = std::sync::mpsc::channel(); + std::thread::spawn(move || { + tx.send( + conn.execute_batch("LOAD httpfs;") + .map_err(|e| e.to_string()), + ) + }); + match rx.recv_timeout(std::time::Duration::from_secs(120)) { + Ok(r) => r.expect("could not load httpfs"), + Err(_) => panic!( + "LOAD httpfs did not return: the patched engine's struct layout no longer matches \ + the release the prebuilt extensions were built against" + ), + } + } +} diff --git a/backend/windmill-worker/src/duckdb_executor.rs b/backend/windmill-worker/src/duckdb_executor.rs index e91a1957c6..b037905cf8 100644 --- a/backend/windmill-worker/src/duckdb_executor.rs +++ b/backend/windmill-worker/src/duckdb_executor.rs @@ -1516,6 +1516,10 @@ pub async fn do_duckdb( probe_blocks, ) .await?; + // The probe opens its own DuckDB connection, so it needs the same + // connection policy as the main query below. + #[cfg(feature = "private")] + let probe_blocks = crate::duckdb_isolation_ee::apply_duckdb_isolation(probe_blocks)?; let alter_ddl = compute_sync_alter_ddl( probe_blocks, job_args.clone(), @@ -1844,6 +1848,8 @@ pub async fn do_duckdb( match result { Ok(result) => Ok(result), Err(e) => { + #[cfg(feature = "private")] + let e = crate::duckdb_isolation_ee::explain_error(e); // Passwords might appear in the error message — and, for the // structured data-test failure, in sampled row data read from an // attached database — so every outgoing error is sanitized here. diff --git a/docker/RHEL8/Dockerfile b/docker/RHEL8/Dockerfile index 1af03cc5f4..c17c7685c2 100644 --- a/docker/RHEL8/Dockerfile +++ b/docker/RHEL8/Dockerfile @@ -86,6 +86,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \ CARGO_NET_GIT_FETCH_WITH_CLI=true cargo build --release --features "$features" RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/git \ cd windmill-duckdb-ffi-internal && \ CARGO_NET_GIT_FETCH_WITH_CLI=true cargo build --release diff --git a/docker/RHEL9/Dockerfile b/docker/RHEL9/Dockerfile index 9ab5c78318..3f24e936ab 100644 --- a/docker/RHEL9/Dockerfile +++ b/docker/RHEL9/Dockerfile @@ -86,6 +86,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \ CARGO_NET_GIT_FETCH_WITH_CLI=true cargo build --release --features "$features" RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/git \ cd windmill-duckdb-ffi-internal && \ CARGO_NET_GIT_FETCH_WITH_CLI=true cargo build --release diff --git a/docs/duckdb-isolation.md b/docs/duckdb-isolation.md new file mode 100644 index 0000000000..fa53551582 --- /dev/null +++ b/docs/duckdb-isolation.md @@ -0,0 +1,155 @@ +# DuckDB isolation and the patched engine + +DuckDB runs **in-process** in the worker, through the FFI cdylib in +`backend/windmill-duckdb-ffi-internal`. It is therefore the one language that the +nsjail/unshare isolation cannot confine: there is no child process to jail. On a worker +that isolates jobs, `windmill-worker/src/duckdb_isolation_ee.rs` mirrors that policy at +the connection level instead, rewriting the block list handed to the engine so it starts +with three irreversible settings: + +```sql +SET lock_temp_directory=true; +SET disabled_filesystems='LocalFileSystem'; +SET allow_community_extensions=false; +``` + +`disabled_filesystems` is the fence. `lock_temp_directory` is what keeps out-of-core +execution working behind it, and it is **not a stock DuckDB setting** — see below. + +## Why the engine had to change + +DuckDB spills through the same file system a query would use to read `/etc/hostname`, so +`disabled_filesystems='LocalFileSystem'` also stops the buffer manager. Every query whose +working set outgrows `memory_limit` then fails instead of going out-of-core. No +combination of stock settings gives "spill, but no other local file access": + +- `allowed_directories` / `allowed_paths` enforce nothing while `enable_external_access` + is true — `DBConfig::CanAccessFile` returns early. +- Turning `enable_external_access` off does preserve spilling (startup adds the temp + directory to `allowed_directories`), but the postgres and mysql extensions refuse to + `ATTACH` on that flag alone, with no allowlist entry able to re-permit it. That would + take DuckLake catalogs and datatables down with it. +- A remote `temp_directory` is impossible: DuckDB cannot open an HTTP file for both + reading and writing, and the attempt aborts the process. + +The engine is also not arranged the way the layering suggests. `FileSystem::GetLocal(db)` +looks like an escape hatch — it is what secret storage and extension installation use — +but `LocalDatabaseFileSystem::GetFileSystem()` re-applies the `disabled_filesystems` +check by hand, so it is not one. (That is also why extension autoload broke behind the +fence in DuckDB 1.5.3, which `EXTENSION_ALLOWLIST` and `PRELOAD_EXTENSIONS` exist to work +around.) The buffer manager, meanwhile, reaches its temp files through +`FileSystem::GetFileSystem(db)`, an opener-wrapped virtual file system, so both the path +allowlist and the disable apply to it. + +## What the patch adds + +`lock_temp_directory` (BOOLEAN, default false, global, irreversible). Setting it: + +1. fixes `temp_directory` in place — it can no longer be modified, and the setting itself + cannot be unset or reset; +2. routes the buffer manager's temporary files through a local file system that + `disabled_filesystems` does not apply to. + +The two halves are what make it safe as a pair. The exemption is only sound because the +directory can no longer be redirected: without (1), a script could point `temp_directory` +at an arbitrary path and get a blind write primitive through the exemption. +`allowed_directories` still applies either way. + +The isolation transform therefore emits `SET lock_temp_directory=true` **before** +`disabled_filesystems`, while the local file system is still reachable, and after the FFI +has already pointed `temp_directory` at the job dir +(`configure_duckdb_resource_limits`). Everything a script authored runs after all three +settings, so a script can never move the temp directory. + +## Where the patched engine comes from + +`backend/windmill-duckdb-ffi-internal` depends on +[`windmill-labs/duckdb-rs`](https://github.com/windmill-labs/duckdb-rs), branch +`windmill/duckdb-1.5.5`, pinned by rev. That fork is duckdb-rs 1.10505.0 (DuckDB 1.5.5) +plus one commit; `duckdb.tar.gz` is left byte-identical to upstream's and the patch is +applied to the extracted sources at build time, so `git diff` against `duckdb/duckdb-rs` +shows the whole delta as text. `crates/libduckdb-sys/windmill/README.md` in the fork +carries the rebase recipe. + +### The patch may not move a struct member + +The engine loads the **prebuilt** extensions from `extensions.duckdb.org` — httpfs, azure, +postgres, ducklake, parquet, and the rest of `EXTENSION_ALLOWLIST` — which are compiled +against the struct layouts of the release the engine claims to be. A patch that shifts a +member those extensions reach breaks them, and not loudly: the extension reads the +neighbouring field and `LOAD httpfs` **blocks forever** rather than failing, so every +DuckDB job hangs until its timeout. + +The first revision of this patch declared its new `DatabaseInstance` member next to +`local_db_file_system`, which pushed `create_api_v1` — the extension C-API entry point — +8 bytes along, and every extension load hung. It is declared last for that reason, and +`lock_temp_directory` is declared at the end of `DBConfigOptions`' run of bools so it takes +a byte of padding the struct already had. + +The invariant is **no pre-existing member changes offset**, which is strictly stronger than +`sizeof` holding — the first attempt at that field went in next to `temporary_directory`, +kept `sizeof(DBConfigOptions)` at 920 by consuming interior padding, and still slid four +bools along by a byte each. A rebase must diff the full record layouts +(`clang++ -Xclang -fdump-record-layouts`, recipe in the fork's README), not the sizes. +`prebuilt_extensions_still_load` in the FFI crate is the end-to-end guard — a timeout, not +an assertion, because the failure mode is a hang — but it covers extension *entry*, not +every field an extension reads, so it does not substitute for the layout diff. + +Alternatives considered and rejected: vendoring a patched `libduckdb-sys` in this repo +would put a 6 MB binary tarball into windmill's history on every engine bump and would +need the FFI builder stage in `Dockerfile` to copy more than +`backend/windmill-duckdb-ffi-internal`; linking a prebuilt engine through +`DUCKDB_LIB_DIR` would drop the `bundled` build, so every developer and every CI job +would need a patched `libduckdb` on the box before `build_dev.sh` could work. + +## What stops the patch disappearing silently + +An unpatched engine compiles, links and passes every existing test. Three things catch it: + +- **The fork's build script** asserts a marker string is present in the patched sources + after applying the patch, and panics if the patch no longer applies. +- **`patched_engine_tests` in the FFI crate** runs a query that must spill, first + without the lock (asserting the fence stops it, which is what proves the query really + spills) and then with it (asserting it succeeds). It fails outright on a stock engine, + where the `SET` is an unrecognized parameter. CI runs it via the FFI crate's own + `cargo test` step in `backend-test.yml`. +- **The transform itself fails closed**: on a stock engine `SET lock_temp_directory=true` + errors, so every DuckDB job on an isolating worker fails immediately rather than + quietly losing the ability to spill. + +## Upstream + +The patch is written against `duckdb/duckdb` `v1.5.5` in the shape upstream takes changes. +Besides the engine sources it carries `src/common/settings.json` (the settings generator's +input, regenerated with `scripts/generate_settings.py` and formatted with clang-format +11.0.1), two sqllogictests under `test/sql/settings/`, and one line in +`test/api/test_reset.cpp` — that test requires every setting to survive a `RESET`, so an +irreversible one has to join the exclusion list `disabled_filesystems` and +`lock_configuration` are already on. It is a `git format-patch` file, so it applies with +`git am`: + +```bash +git clone https://github.com/duckdb/duckdb.git && cd duckdb && git checkout v1.5.5 +git am < .../crates/libduckdb-sys/windmill/0001-lock-temp-directory.patch +GEN=ninja make && ./build/release/test/unittest "test/sql/settings/lock_temp_directory*" +``` + +It is filed as **[duckdb/duckdb#24694](https://github.com/duckdb/duckdb/pull/24694)**, +against `main` rather than `v1.5.5`. Filing was a human decision on purpose: their +`CONTRIBUTING.md` asks contributors not to submit LLM-generated pull requests, to discuss +the change on GitHub first, and to run CI on a fork before opening one. + +**[duckdb/duckdb#24695](https://github.com/duckdb/duckdb/issues/24695)** states the +underlying problem without prescribing a fix, and is where a different design would land: +`lock_temp_directory` is one shape, and an enforceable `allowed_directories` would solve it +equally well. Watch the issue rather than the PR for whether this fork can be retired. + +The vendored copy and #24694 are the same change and must stay that way. They differ only +where the base version forces it: the `DUCKDB_SETTING_ALIAS` indices, `vfs` versus +`db.config.file_system` in `FileSystem::GetLocal`, and the sqllogictest directory +placeholder. Nothing else should diverge. Note that the build applies neither the `test/` +hunks nor `settings.json` (`NOT_IN_TARBALL` in `build_windmill_patch.rs`), so drift in +those is invisible here and only surfaces when #24694 is rebased. + +Until it lands in a released DuckDB the fork is the delivery mechanism, and the exit path +is to delete `crates/libduckdb-sys/windmill/` and go back to the crates.io crate.