From 2c5217ff9f62335ae2c2606fa5b0f2f606564a05 Mon Sep 17 00:00:00 2001 From: Denis Smirnov <sd@picodata.io> Date: Thu, 13 Jun 2024 20:37:56 +0700 Subject: [PATCH] feat: move to rust API for local SQL --- Cargo.lock | 616 ++++++++++-------- sbroad-benches/Cargo.toml | 15 +- sbroad-cartridge/Cargo.toml | 6 +- sbroad-cartridge/src/cartridge/storage.rs | 21 +- sbroad-cartridge/src/storage.lua | 1 - sbroad-core/Cargo.toml | 16 +- sbroad-core/src/backend/sql/ir.rs | 8 + sbroad-core/src/core-router.lua | 26 +- sbroad-core/src/core-storage.lua | 69 -- sbroad-core/src/executor/engine.rs | 8 +- sbroad-core/src/executor/engine/helpers.rs | 485 +++++++------- .../src/executor/engine/helpers/storage.rs | 217 ++++-- .../executor/engine/helpers/storage/meta.rs | 42 -- sbroad-core/src/executor/lru.rs | 10 +- sbroad-core/src/executor/result.rs | 25 +- sbroad-core/src/executor/vtable.rs | 2 +- sbroad-core/src/ir.rs | 26 + 17 files changed, 890 insertions(+), 703 deletions(-) delete mode 100644 sbroad-core/src/core-storage.lua delete mode 100644 sbroad-core/src/executor/engine/helpers/storage/meta.rs diff --git a/Cargo.lock b/Cargo.lock index 4efe5f6a5..63193dd16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -15,18 +15,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "arrayref" @@ -42,13 +42,13 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "base64" @@ -97,16 +97,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "blake3" -version = "1.4.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b71f35bd3fa1a4c86b85d32c8b9069ea7fe14f7a53cfabb65f62d4265b888" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" dependencies = [ "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", - "digest 0.10.7", ] [[package]] @@ -129,15 +128,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cast" @@ -147,9 +146,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -170,15 +169,15 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -221,47 +220,47 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crossbeam-queue" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", + "crossbeam-utils", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crypto-common" version = "0.1.6" @@ -274,9 +273,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.2.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" dependencies = [ "csv-core", "itoa", @@ -286,23 +285,13 @@ dependencies = [ [[package]] name = "csv-core" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" dependencies = [ "memchr", ] -[[package]] -name = "ctor" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" -dependencies = [ - "quote 1.0.35", - "syn 1.0.109", -] - [[package]] name = "darling" version = "0.14.4" @@ -321,8 +310,8 @@ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.85", + "quote 1.0.36", "strsim", "syn 1.0.109", ] @@ -334,26 +323,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core", - "quote 1.0.35", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "dec" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdeb628adfc427c3f926528cf76daf4418453e103151739d48f79b8182cb41f" +checksum = "a8aed775093963adbd1821f88d7934c839330b05f41c9877bdbc7b385e498b9c" dependencies = [ "decnumber-sys", "libc", + "paste", "static_assertions", ] [[package]] name = "decnumber-sys" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a99b958f19724bc0a2202086d135c2e7ed098e95cdae778546e965648fa47b" +checksum = "23b4bc33814bd5bcd46dd13f9471a29ab1a22c4701ae0c4a182e45e8336d1a5b" dependencies = [ "cc", "libc", @@ -382,7 +372,6 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", - "subtle", ] [[package]] @@ -410,9 +399,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "fnv" @@ -422,9 +411,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -437,9 +426,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -447,15 +436,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -464,38 +453,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -521,9 +510,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -532,9 +521,9 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "hash32" @@ -562,9 +551,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "ident_case" @@ -599,15 +588,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -620,9 +609,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "linked-hash-map" @@ -632,50 +621,51 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linkme" -version = "0.2.10" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd4ad156b9934dc21cad96fd17278a7cb6f30a5657a9d976cd7b71d6d49c02c" +checksum = "ccb76662d78edc9f9bf56360d6919bdacc8b7761227727e5082f128eeb90bbf5" dependencies = [ "linkme-impl", ] [[package]] name = "linkme-impl" -version = "0.2.10" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fd9dc7072de7168cbdaba9125e8f742cd3a965aa12bde994b4611a174488d8" +checksum = "f8dccda732e04fa3baf2e17cf835bfe2601c7c2edafd64417c627dabae3a8cda" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 1.0.109", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "log" -version = "0.4.19" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] -name = "memchr" -version = "2.5.0" +name = "md-5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] [[package]] -name = "memoffset" -version = "0.9.0" +name = "memchr" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -686,15 +676,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" @@ -704,9 +694,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "opentelemetry" @@ -759,42 +749,34 @@ dependencies = [ "num-traits", ] -[[package]] -name = "output_vt100" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" -dependencies = [ - "winapi", -] - [[package]] name = "paste" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.0" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.0" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef623c9bbfa0eedf5a0efba11a5ee83209c326653ca31ff019bec3a95bfff2b" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -802,22 +784,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.0" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "pest_meta" -version = "2.7.0" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01f71cb40bd8bb94232df14b946909e14660e33fc05db3e50ae2a82d7ea0ca0" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", @@ -826,29 +808,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -858,9 +840,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ "num-traits", "plotters-backend", @@ -871,15 +853,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ "plotters-backend", ] @@ -892,13 +874,11 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pretty_assertions" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" dependencies = [ - "ctor", "diff", - "output_vt100", "yansi", ] @@ -909,8 +889,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", "version_check", ] @@ -921,8 +901,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.85", + "quote 1.0.36", "version_check", ] @@ -937,9 +917,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -955,11 +935,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ - "proc-macro2 1.0.79", + "proc-macro2 1.0.85", ] [[package]] @@ -994,9 +974,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -1004,14 +984,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -1022,9 +1000,9 @@ checksum = "369e86b80fa7dc8c561dd9613a5bf25c59d2d3073cd66c47fd9e39802f0ecb58" [[package]] name = "regex" -version = "1.9.0" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89089e897c013b3deb627116ae56a6955a72b8bed395c9526af31c9fe528b484" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -1034,9 +1012,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.0" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa250384981ea14565685dea16a9ccc4d1c541a13f82b9c168572264d1df8c56" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -1045,9 +1023,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rmp" @@ -1073,9 +1051,9 @@ dependencies = [ [[package]] name = "rmp-serde" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25786b0d276110195fa3d6f3f31299900cf71dfbd6c28450f3f58a0e7f7a347e" +checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" dependencies = [ "byteorder", "rmp", @@ -1096,9 +1074,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1142,7 +1120,7 @@ dependencies = [ "serde_yaml", "smol_str", "tarantool", - "uuid 1.4.0", + "uuid 1.8.0", "yaml-rust", ] @@ -1163,44 +1141,39 @@ dependencies = [ "pretty_assertions", "rand", "rmp", - "rmp-serde 1.1.0", + "rmp-serde 1.1.2", + "rmpv", "sbroad-proc", "serde", "serde_yaml", "smol_str", "tarantool", "time", - "uuid 1.4.0", + "uuid 1.8.0", ] [[package]] name = "sbroad-proc" version = "0.1.0" dependencies = [ - "quote 1.0.35", + "quote 1.0.36", "syn 1.0.109", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "serde" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.11" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a16be4fe5320ade08736447e3198294a5ea9a6d44dde6f35f0a5e06859c427a" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] @@ -1217,20 +1190,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -1264,9 +1237,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -1275,18 +1248,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smol_str" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" dependencies = [ "serde", ] @@ -1303,12 +1276,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - [[package]] name = "syn" version = "0.15.44" @@ -1326,40 +1293,42 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.85", + "quote 1.0.36", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.55" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.85", + "quote 1.0.36", "unicode-ident", ] [[package]] name = "tarantool" version = "5.0.0" -source = "git+https://git.picodata.io/picodata/picodata/tarantool-module.git#dbebcc0aace0264b7ba9569e9a8a672b972c95ea" +source = "git+https://git.picodata.io/picodata/picodata/tarantool-module.git#d758e775797267a9d12e0e2afef73244a9aeaf5e" dependencies = [ "async-trait", "base64", "bitflags", + "crossbeam-queue", "dec", "dlopen", "futures", "libc", "linkme", "log", + "md-5", "once_cell", "refpool", "rmp", - "rmp-serde 1.1.0", + "rmp-serde 1.1.2", "rmpv", "serde", "serde_bytes", @@ -1375,13 +1344,13 @@ dependencies = [ [[package]] name = "tarantool-proc" -version = "3.0.0" -source = "git+https://git.picodata.io/picodata/picodata/tarantool-module.git#dbebcc0aace0264b7ba9569e9a8a672b972c95ea" +version = "3.1.0" +source = "git+https://git.picodata.io/picodata/picodata/tarantool-module.git#d758e775797267a9d12e0e2afef73244a9aeaf5e" dependencies = [ "darling", "proc-macro-error", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -1396,22 +1365,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.41" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c16a64ba9387ef3fdae4f9c1a7f07a0997fce91985c0336f1ddc1822b3b37802" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.41" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14928354b01c4d6a4f0e549069adef399a284e7995c7ccca94e8a07a5346c59" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -1476,7 +1445,7 @@ dependencies = [ [[package]] name = "tlua" version = "3.1.0" -source = "git+https://git.picodata.io/picodata/picodata/tarantool-module.git#dbebcc0aace0264b7ba9569e9a8a672b972c95ea" +source = "git+https://git.picodata.io/picodata/picodata/tarantool-module.git#d758e775797267a9d12e0e2afef73244a9aeaf5e" dependencies = [ "libc", "serde", @@ -1487,36 +1456,36 @@ dependencies = [ [[package]] name = "tlua-derive" version = "0.2.0" -source = "git+https://git.picodata.io/picodata/picodata/tarantool-module.git#dbebcc0aace0264b7ba9569e9a8a672b972c95ea" +source = "git+https://git.picodata.io/picodata/picodata/tarantool-module.git#d758e775797267a9d12e0e2afef73244a9aeaf5e" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -1532,9 +1501,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.4.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "getrandom", "rand", @@ -1543,13 +1512,13 @@ dependencies = [ [[package]] name = "uuid-macro-internal" -version = "1.4.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8614dda80b9075fbca36bc31b58d1447715b1236af98dee21db521c47a0cc2c0" +checksum = "9881bea7cbe687e36c9ab3b778c36cd0487402e270304e8b1296d5085303c1a2" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -1566,9 +1535,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -1582,9 +1551,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1592,53 +1561,53 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ - "quote 1.0.35", + "quote 1.0.36", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.55", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -1662,11 +1631,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys", ] [[package]] @@ -1675,6 +1644,79 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/sbroad-benches/Cargo.toml b/sbroad-benches/Cargo.toml index 110def286..75479edf0 100644 --- a/sbroad-benches/Cargo.toml +++ b/sbroad-benches/Cargo.toml @@ -11,14 +11,23 @@ edition = "2021" [dependencies] sbroad-core = { path = "../sbroad-core", version = "0.1", features = ["mock"] } -tarantool = { git = "https://git.picodata.io/picodata/picodata/tarantool-module.git" } pest = "2.0" pest_derive = "2.0" -bincode = "1.3.3" +bincode = "1.3" + +[dependencies.tarantool] +git = "https://git.picodata.io/picodata/picodata/tarantool-module.git" +version = ">=4.0" +features = ["picodata"] [dev-dependencies] criterion = "0.3" -rand = "0.8.5" +rand = "0.8" + +[dev-dependencies.tarantool] +git = "https://git.picodata.io/picodata/picodata/tarantool-module.git" +version = ">=4.0" +features = ["picodata", "standalone_decimal"] [[bench]] name = "parse" diff --git a/sbroad-cartridge/Cargo.toml b/sbroad-cartridge/Cargo.toml index efeb12c65..5f39a1ffb 100644 --- a/sbroad-cartridge/Cargo.toml +++ b/sbroad-cartridge/Cargo.toml @@ -14,7 +14,6 @@ base64ct = { version = "1.5", features = ["alloc"] } bincode = "1.3" blake3 = "1.3" sbroad-core = { path = "../sbroad-core", version = "0.1" } -tarantool = { git = "https://git.picodata.io/picodata/picodata/tarantool-module.git" } sbroad-proc = { path = "../sbroad-proc", version = "0.1" } serde = { version = "1.0", features = ["derive", "rc"] } serde_yaml = "0.8" @@ -28,6 +27,11 @@ yaml-rust = "0.4" anyhow = "1" smol_str = "0.2.1" +[dependencies.tarantool] +git = "https://git.picodata.io/picodata/picodata/tarantool-module.git" +version = ">=4.0" +features = ["picodata"] + [dev-dependencies] pretty_assertions = "1.3" diff --git a/sbroad-cartridge/src/cartridge/storage.rs b/sbroad-cartridge/src/cartridge/storage.rs index da2b159f2..90d5a45f8 100644 --- a/sbroad-cartridge/src/cartridge/storage.rs +++ b/sbroad-cartridge/src/cartridge/storage.rs @@ -2,9 +2,9 @@ use crate::cartridge::bucket_count; use crate::cartridge::config::StorageConfiguration; use sbroad::errors::{Entity, SbroadError}; use sbroad::executor::bucket::Buckets; -use sbroad::executor::engine::helpers::storage::runtime::unprepare; -use sbroad::executor::engine::helpers::storage::PreparedStmt; +use sbroad::executor::engine::helpers::storage::unprepare; use sbroad::executor::engine::helpers::vshard::get_random_bucket; +use sbroad::executor::engine::helpers::{read_or_prepare, EncodedQueryInfo}; use sbroad::executor::engine::{helpers, StorageCache}; use sbroad::executor::engine::{QueryCache, Vshard}; use sbroad::executor::hash::bucket_id_by_tuple; @@ -20,6 +20,7 @@ use std::any::Any; use std::fmt::Display; use tarantool::fiber::Mutex; +use tarantool::sql::Statement; use tarantool::tlua::LuaFunction; use super::ConfigurationProvider; @@ -31,23 +32,20 @@ pub struct StorageRuntime { cache: Mutex<CartridgeCache>, } -pub struct CartridgeCache(LRUCache<SmolStr, (PreparedStmt, Vec<NodeId>)>); +pub struct CartridgeCache(LRUCache<SmolStr, (Statement, Vec<NodeId>)>); impl StorageCache for CartridgeCache { fn put( &mut self, plan_id: SmolStr, - stmt: PreparedStmt, + stmt: Statement, _: &SchemaInfo, table_ids: Vec<NodeId>, ) -> Result<(), SbroadError> { self.0.put(plan_id, (stmt, table_ids)) } - fn get( - &mut self, - plan_id: &SmolStr, - ) -> Result<Option<(&PreparedStmt, &[NodeId])>, SbroadError> { + fn get(&mut self, plan_id: &SmolStr) -> Result<Option<(&Statement, &[NodeId])>, SbroadError> { let Some((stmt, table_ids)) = self.0.get(plan_id)? else { return Ok(None); }; @@ -206,7 +204,7 @@ impl StorageRuntime { /// # Errors /// - Failed to initialize the LRU cache. pub fn new() -> Result<Self, SbroadError> { - let cache: LRUCache<SmolStr, (PreparedStmt, Vec<NodeId>)> = + let cache: LRUCache<SmolStr, (Statement, Vec<NodeId>)> = LRUCache::new(DEFAULT_CAPACITY, Some(Box::new(unprepare)))?; let result = StorageRuntime { metadata: Mutex::new(StorageConfiguration::new()), @@ -229,7 +227,10 @@ impl StorageRuntime { ) -> Result<Box<dyn Any>, SbroadError> { match required.query_type { QueryType::DML => helpers::execute_dml(self, required, raw_optional), - QueryType::DQL => helpers::execute_dql_with_raw_optional(self, required, raw_optional), + QueryType::DQL => { + let mut info = EncodedQueryInfo::new(std::mem::take(raw_optional), required); + read_or_prepare(self, &mut info) + } } } } diff --git a/sbroad-cartridge/src/storage.lua b/sbroad-cartridge/src/storage.lua index 0f4629180..3a432adf5 100644 --- a/sbroad-cartridge/src/storage.lua +++ b/sbroad-cartridge/src/storage.lua @@ -1,5 +1,4 @@ require('strict').on() -require('sbroad.core-storage') local cartridge = require('cartridge') local rust = require("sbroad.rust") diff --git a/sbroad-core/Cargo.toml b/sbroad-core/Cargo.toml index 130169505..1e7847507 100644 --- a/sbroad-core/Cargo.toml +++ b/sbroad-core/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -lazy_static = "1.4.0" +lazy_static = "1.4" ahash = "0.7" base64ct = { version = "1.5", features = ["alloc"] } bincode = "1.3" @@ -23,17 +23,27 @@ pest_derive = "2.0" rand = "0.8" rmp = "0.8" rmp-serde = "1.0" +rmpv = "1.0" sbroad-proc = { path = "../sbroad-proc", version = "0.1" } serde = { version = "1.0", features = ["derive", "rc"] } serde_yaml = "0.8" -tarantool = { git = "https://git.picodata.io/picodata/picodata/tarantool-module.git" } uuid = { version = "1.1", features = ["v4", "fast-rng", "macro-diagnostics"] } -smol_str = { version = "0.2.1", features = ["serde"] } +smol_str = { version = "0.2", features = ["serde"] } time = { version = ">=0.3.0, <0.3.18", features = ["formatting"] } +[dependencies.tarantool] +git = "https://git.picodata.io/picodata/picodata/tarantool-module.git" +version = ">=4.0" +features = ["picodata"] + [dev-dependencies] pretty_assertions = "1.3" +[dev-dependencies.tarantool] +git = "https://git.picodata.io/picodata/picodata/tarantool-module.git" +version = ">=4.0" +features = ["picodata", "standalone_decimal"] + [lib] name = "sbroad" crate-type = ["cdylib", "rlib"] diff --git a/sbroad-core/src/backend/sql/ir.rs b/sbroad-core/src/backend/sql/ir.rs index 35ade444b..bf5c7082b 100644 --- a/sbroad-core/src/backend/sql/ir.rs +++ b/sbroad-core/src/backend/sql/ir.rs @@ -28,6 +28,14 @@ pub struct PatternWithParams { // Name of the tracer to use pub tracer: Option<String>, } + +impl PatternWithParams { + #[must_use] + pub fn into_parts(self) -> (String, Vec<Value>) { + (self.pattern, self.params) + } +} + impl PartialEq for PatternWithParams { fn eq(&self, other: &Self) -> bool { self.pattern == other.pattern && self.params == other.params diff --git a/sbroad-core/src/core-router.lua b/sbroad-core/src/core-router.lua index 9687f4a56..a821f0ba1 100644 --- a/sbroad-core/src/core-router.lua +++ b/sbroad-core/src/core-router.lua @@ -164,6 +164,11 @@ local function multi_storage_dql(uuid_to_args, func, vtable_max_rows, opts) local data = res[1] if result == nil then result = data + if vtable_max_rows ~= 0 and vtable_max_rows < #result.rows then + err = helper.vtable_limit_exceeded(vtable_max_rows, #result.rows) + err_uuid = uuid + goto fail + end else local new_vt_rows = #data.rows + #result.rows if vtable_max_rows ~= 0 and vtable_max_rows < new_vt_rows then @@ -243,14 +248,21 @@ _G.dql_on_some = function(uuid_to_args, is_readonly, waiting_timeout, vtable_max error(err) end future:wait_result(waiting_timeout) - -- vtable_max_rows limit was checked on - -- storage. No need to check it here. local res, err = future:result() if err ~= nil then error(err) end - -- TODO: explain where this `[1][1]` comes from + + -- proc_sql_execute returns [{rows_count = ..}] tuple. + -- But this rust function is wrapped with proc macros that + -- add an additional layer of array (see ReturnMsgpack). result = helper.unwrap_execute_result(res[1][1]) + + -- Check the number of rows in the virtual table. + if vtable_max_rows ~= 0 and vtable_max_rows < #result.rows then + err = helper.vtable_limit_exceeded(vtable_max_rows, #result.rows) + error(err) + end else local err, err_uuid local opts = { timeout = waiting_timeout } @@ -328,7 +340,9 @@ _G.dml_on_some = function(tbl_rs_ir, is_readonly, waiting_timeout) error(err) end - -- TODO: explain where this `[1][1]` comes from + -- proc_sql_execute returns [{rows_count = ..}] tuple. + -- But this rust function is wrapped with proc macros that + -- add an additional layer of array (see ReturnMsgpack). local next_result = helper.unwrap_execute_result(res[1][1]) if result == nil then result = next_result @@ -379,7 +393,9 @@ _G.dml_on_all = function(required, optional, is_readonly, waiting_timeout) error(err) end - -- TODO: explain where this `[1][1]` comes from + -- proc_sql_execute returns [{rows_count = ..}] tuple. + -- But this rust function is wrapped with proc macros that + -- add an additional layer of array (see ReturnMsgpack). local next_result = helper.unwrap_execute_result(res[1][1]) if result == nil then result = next_result diff --git a/sbroad-core/src/core-storage.lua b/sbroad-core/src/core-storage.lua deleted file mode 100644 index 3b6e4fae6..000000000 --- a/sbroad-core/src/core-storage.lua +++ /dev/null @@ -1,69 +0,0 @@ -local helper = require('sbroad.helper') - -_G.prepare = function(pattern) - local prep, err = box.prepare(pattern) - if err ~= nil then - error(string.format("Failed to prepare statement: %s. Error: %s", pattern, err), 1) - end - return prep.stmt_id -end - -_G.unprepare = function(stmt_id) - box.unprepare(stmt_id) -end - -_G.read = function(stmt_id, stmt, params, max_rows, options) - local res, err = box.execute(stmt_id, params, options) - if err ~= nil then - -- We don't have SQL query for retrying, - -- so simply return an error - if stmt == nil or stmt == '' then - error(err) - end - -- The statement can be evicted from the cache, - -- while we were yielding in Lua. So we execute - -- it without the cache. - res, err = box.execute(stmt, params, options) - if err ~= nil then - error(err) - end - end - - if max_rows ~= 0 and #res.rows > max_rows then - error(helper.vtable_limit_exceeded(max_rows, #res.rows)) - end - - local result = {} - result.metadata = res.metadata - result.rows = {} - for _, row in ipairs(res.rows) do - local tuple = {} - for _, field in ipairs(row) do - table.insert(tuple, field) - end - table.insert(result.rows, tuple) - end - - return box.tuple.new{result} -end - -_G.write = function(stmt_id, stmt, params, options) - local res, err = box.execute(stmt_id, params, options) - if err ~= nil then - -- We don't have SQL query for retrying, - -- so simply return an error - if stmt == nil or stmt == '' then - error(err) - end - -- The statement can be evicted from the cache, - -- while we were yielding in Lua. So we execute - -- it without the cache. - res, err = box.execute(stmt, params, options) - if err ~= nil then - error(err) - end - end - - return box.tuple.new{res} -end - diff --git a/sbroad-core/src/executor/engine.rs b/sbroad-core/src/executor/engine.rs index 71a11570e..1d1ef4c64 100644 --- a/sbroad-core/src/executor/engine.rs +++ b/sbroad-core/src/executor/engine.rs @@ -15,7 +15,6 @@ use std::sync::OnceLock; use crate::errors::SbroadError; use crate::executor::bucket::Buckets; -use crate::executor::engine::helpers::storage::PreparedStmt; use crate::executor::ir::ExecutionPlan; use crate::executor::protocol::SchemaInfo; use crate::executor::vtable::VirtualTable; @@ -28,6 +27,8 @@ use crate::ir::NodeId; use super::ir::{ConnectionType, QueryType}; use super::protocol::Binary; +use tarantool::sql::Statement; + pub mod helpers; #[cfg(feature = "mock")] pub mod mock; @@ -94,7 +95,7 @@ pub trait StorageCache { fn put( &mut self, plan_id: SmolStr, - stmt: PreparedStmt, + stmt: Statement, schema_info: &SchemaInfo, table_ids: Vec<NodeId>, ) -> Result<(), SbroadError>; @@ -105,8 +106,7 @@ pub trait StorageCache { /// # Errors /// - failed to get schema version for some table #[allow(clippy::ptr_arg)] - fn get(&mut self, plan_id: &SmolStr) - -> Result<Option<(&PreparedStmt, &[NodeId])>, SbroadError>; + fn get(&mut self, plan_id: &SmolStr) -> Result<Option<(&Statement, &[NodeId])>, SbroadError>; /// Clears the cache. /// diff --git a/sbroad-core/src/executor/engine/helpers.rs b/sbroad-core/src/executor/engine/helpers.rs index 3bbaf5f7a..bbbb011ae 100644 --- a/sbroad-core/src/executor/engine/helpers.rs +++ b/sbroad-core/src/executor/engine/helpers.rs @@ -18,13 +18,14 @@ use tarantool::{ use tarantool::{space::Space, tuple::TupleBuffer}; use crate::backend::sql::space::{TableGuard, ADMIN_ID}; -use crate::executor::engine::helpers::storage::runtime::{prepare, read_prepared, read_unprepared}; +use crate::executor::engine::helpers::storage::{execute_prepared, execute_unprepared, prepare}; use crate::executor::engine::{QueryCache, StorageCache}; use crate::executor::protocol::{EncodedTables, SchemaInfo}; use crate::ir::operator::ConflictStrategy; use crate::ir::value::{EncodedValue, LuaValue, MsgPackValue}; -use crate::ir::{ExecuteOptions, NodeId}; +use crate::ir::NodeId; use crate::otm::child_span; +use crate::utils::ByteCounter; use crate::{ backend::sql::{ ir::PatternWithParams, @@ -287,6 +288,20 @@ fn compile_optional( Ok((pwp, guard)) } +/// Decode dispatched optional data (execution plan, etc.) from msgpack +/// and compile it into a pattern with parameters and temporary space map. +/// +/// # Errors +/// - Failed to decode or compile optional data. +pub fn compile_encoded_optional( + raw_optional: &mut Vec<u8>, + template: &str, +) -> Result<(PatternWithParams, Vec<TableGuard>), SbroadError> { + let data = std::mem::take(raw_optional); + let mut optional = OptionalData::try_from(EncodedOptionalData::from(data))?; + compile_optional(&mut optional, template) +} + /// Command to build a tuple suitable to be passed into Tarantool API functions. /// For more information see `TupleBuilderPattern` docs. #[derive(Debug)] @@ -627,7 +642,7 @@ pub fn empty_query_result(plan: &ExecutionPlan) -> Result<Option<Box<dyn Any>>, match query_type { QueryType::DML => { let result = ConsumerResult::default(); - let tuple = Tuple::new(&(result,)) + let tuple = Tuple::new(&[result]) .map_err(|e| SbroadError::Invalid(Entity::Tuple, Some(format_smolstr!("{e:?}"))))?; Ok(Some(Box::new(tuple) as Box<dyn Any>)) } @@ -665,7 +680,7 @@ pub fn empty_query_result(plan: &ExecutionPlan) -> Result<Option<Box<dyn Any>>, ..Default::default() }; - let tuple = Tuple::new(&(result,)) + let tuple = Tuple::new(&[result]) .map_err(|e| SbroadError::Invalid(Entity::Tuple, Some(format_smolstr!("{e:?}"))))?; Ok(Some(Box::new(tuple) as Box<dyn Any>)) } @@ -679,7 +694,7 @@ pub fn empty_query_result(plan: &ExecutionPlan) -> Result<Option<Box<dyn Any>>, pub fn explain_format(explain: &str) -> Result<Box<dyn Any>, SbroadError> { let e = explain.lines().collect::<Vec<&str>>(); - match Tuple::new(&vec![e]) { + match Tuple::new(&[e]) { Ok(t) => Ok(Box::new(t)), Err(e) => Err(SbroadError::FailedTo( Action::Create, @@ -1122,8 +1137,117 @@ fn truncate_tables(table_ids: &[NodeId], plan_id: &SmolStr) { .expect("failed to switch to admin user"); } +pub trait PlanInfo { + /// Extracts the query and the temporary tables from the plan. + /// Temporary tables truncate their data in destructor and act + /// as a guard. + /// + /// # Errors + /// - Failed to extract query and table guard. + fn extract_query_and_table_guard( + &mut self, + ) -> Result<(PatternWithParams, Vec<TableGuard>), SbroadError>; + fn id(&self) -> &SmolStr; + fn params(&self) -> &Vec<Value>; + fn schema_info(&self) -> &SchemaInfo; + fn extract_data(&mut self) -> EncodedTables; + fn vdbe_max_steps(&self) -> u64; + fn vtable_max_rows(&self) -> u64; +} + +pub struct QueryInfo<'data> { + optional: &'data mut OptionalData, + required: &'data mut RequiredData, +} + +impl<'data> QueryInfo<'data> { + pub fn new(optional: &'data mut OptionalData, required: &'data mut RequiredData) -> Self { + Self { optional, required } + } +} + +impl PlanInfo for QueryInfo<'_> { + fn extract_query_and_table_guard( + &mut self, + ) -> Result<(PatternWithParams, Vec<TableGuard>), SbroadError> { + compile_optional(self.optional, &self.required.plan_id) + } + + fn id(&self) -> &SmolStr { + &self.required.plan_id + } + + fn params(&self) -> &Vec<Value> { + &self.required.parameters + } + + fn schema_info(&self) -> &SchemaInfo { + &self.required.schema_info + } + + fn extract_data(&mut self) -> EncodedTables { + std::mem::take(&mut self.required.tables) + } + + fn vdbe_max_steps(&self) -> u64 { + self.required.options.execute_options.vdbe_max_steps() + } + + fn vtable_max_rows(&self) -> u64 { + self.required.options.execute_options.vtable_max_rows() + } +} + +pub struct EncodedQueryInfo<'data> { + raw_optional: Vec<u8>, + required: &'data mut RequiredData, +} + +impl<'data> EncodedQueryInfo<'data> { + pub fn new(raw_optional: Vec<u8>, required: &'data mut RequiredData) -> Self { + Self { + raw_optional, + required, + } + } +} + +impl PlanInfo for EncodedQueryInfo<'_> { + fn extract_query_and_table_guard( + &mut self, + ) -> Result<(PatternWithParams, Vec<TableGuard>), SbroadError> { + let data = std::mem::take(&mut self.raw_optional); + let mut optional = OptionalData::try_from(EncodedOptionalData::from(data))?; + compile_optional(&mut optional, &self.required.plan_id) + } + + fn id(&self) -> &SmolStr { + &self.required.plan_id + } + + fn params(&self) -> &Vec<Value> { + &self.required.parameters + } + + fn schema_info(&self) -> &SchemaInfo { + &self.required.schema_info + } + + fn extract_data(&mut self) -> EncodedTables { + std::mem::take(&mut self.required.tables) + } + + fn vdbe_max_steps(&self) -> u64 { + self.required.options.execute_options.vdbe_max_steps() + } + + fn vtable_max_rows(&self) -> u64 { + self.required.options.execute_options.vtable_max_rows() + } +} + /// If the statement with given `plan_id` is found in the cache, -/// execute it and return result. Otherwise, returns `None`. +/// execute it and return result. Otherwise, returns error. /// /// This function works only for read statements, and it is a /// responsibility of a caller to ensure it. @@ -1135,15 +1259,14 @@ fn truncate_tables(table_ids: &[NodeId], plan_id: &SmolStr) { /// # Panics /// - Temporary table could not be truncated. /// - Temporary table could not be inserted. -#[otm_child_span("tarantool.cache.hit.read.prepared")] -pub fn read_from_cache<R: QueryCache, M: MutexLike<R::Cache>, 'mutex>( - locked_cache: &mut M::Guard<'mutex>, +pub fn read_from_cache<R: QueryCache, M: MutexLike<R::Cache>>( + locked_cache: &mut M::Guard<'_>, params: &[Value], tables: &mut EncodedTables, plan_id: &SmolStr, - vtable_max_rows: u64, - opts: ExecuteOptions, -) -> Result<Option<Box<dyn Any>>, SbroadError> + vdbe_max_steps: u64, + max_rows: u64, +) -> Result<Box<dyn Any>, SbroadError> where R::Cache: StorageCache, { @@ -1158,39 +1281,77 @@ where break 'dql Err(e); } } - let stmt_id = stmt.id().expect("failed to get statement id"); - read_prepared(stmt_id, "", params, vtable_max_rows, opts).map(Some) + execute_prepared(stmt, params, vdbe_max_steps, max_rows) }; truncate_tables(table_ids, plan_id); return result; }; - debug!( - Option::from("execute plan"), - &format!("Failed to find a plan (id {plan_id}) in the cache."), - ); - Ok(None) + Err(SbroadError::FailedTo( + Action::Find, + Some(Entity::Statement), + format_smolstr!("{plan_id} is absent in the storage cache"), + )) +} + +#[otm_child_span("tarantool.cache.hit.read.prepared")] +fn cache_hit<R: QueryCache, M: MutexLike<R::Cache>>( + locked_cache: &mut M::Guard<'_>, + params: &[Value], + tables: &mut EncodedTables, + plan_id: &SmolStr, + vdbe_max_steps: u64, + max_rows: u64, +) -> Result<Box<dyn Any>, SbroadError> +where + R::Cache: StorageCache, +{ + read_from_cache::<R, M>( + locked_cache, + params, + tables, + plan_id, + vdbe_max_steps, + max_rows, + ) +} + +#[otm_child_span("tarantool.cache.miss.read.prepared")] +fn cache_miss<R: QueryCache, M: MutexLike<R::Cache>>( + locked_cache: &mut M::Guard<'_>, + params: &[Value], + tables: &mut EncodedTables, + plan_id: &SmolStr, + vdbe_max_steps: u64, + max_rows: u64, +) -> Result<Box<dyn Any>, SbroadError> +where + R::Cache: StorageCache, +{ + read_from_cache::<R, M>( + locked_cache, + params, + tables, + plan_id, + vdbe_max_steps, + max_rows, + ) } /// Execute a read statement bypassing tarantool cache. -/// Must be used only while the cache is locked. /// /// # Errors /// - Failed to populate temporary tables. /// - Failed to execute the statement. /// - Temporary table could not be truncated. -#[otm_child_span("tarantool.cache.miss.read.prepared")] -fn read_bypassing_cache<R: QueryCache, M: MutexLike<R::Cache>>( +fn read_bypassing_cache( pattern: &str, params: &[Value], plan_id: &SmolStr, tables: &mut EncodedTables, - vtable_max_rows: u64, - opts: ExecuteOptions, -) -> Result<Box<dyn Any>, SbroadError> -where - R::Cache: StorageCache, -{ + vdbe_max_steps: u64, + max_rows: u64, +) -> Result<Box<dyn Any>, SbroadError> { // Transaction rollbacks are very expensive in Tarantool, so we're going to // avoid transactions for DQL queries. We can achieve atomicity by truncating // temporary tables. Isolation is guaranteed by keeping a lock on the cache. @@ -1201,146 +1362,82 @@ where break 'dql Err(e); } } - read_unprepared(pattern, params, vtable_max_rows, opts) + execute_unprepared(pattern, params, vdbe_max_steps, max_rows) }; // No need to truncate temporary tables as they would be truncated in the parent function. result } -/// Tries to prepare read statement and then execute it. -/// In case `prepare` fails, the statement will be executed anyway. -/// -/// It is responsibility of the caller, to ensure that it is a -/// read statement - not write. +/// Execute a DQL statement or prepare it, put it into the cache and execute. /// /// # Errors -/// - Failed to prepare the statement -/// - Failed to borrow runtime's cache -/// - Tarantool execution error -#[allow(unused_variables)] -pub fn prepare_and_read<R: Vshard + QueryCache, M: MutexLike<R::Cache>>( - locked_cache: &mut M::Guard<'_>, - pattern_with_params: &PatternWithParams, - plan_id: &SmolStr, - vtable_max_rows: u64, - opts: ExecuteOptions, - schema_info: &SchemaInfo, - tables_with_data: &mut EncodedTables, -) -> Result<Box<dyn Any>, SbroadError> -where - R::Cache: StorageCache, -{ - match prepare(&pattern_with_params.pattern) { - Ok(stmt) => { - let stmt_id = stmt.id()?; - debug!( - Option::from("execute plan"), - &format!( - "Created prepared statement {} for the pattern {}", - stmt_id, - stmt.pattern()? - ), - ); - let mut stmt_tables: Vec<SmolStr> = Vec::with_capacity(tables_with_data.len()); - for node_id in tables_with_data.keys() { - stmt_tables.push(table_name(plan_id.as_str(), *node_id)); - } - let table_ids = tables_with_data.keys().copied().collect::<Vec<NodeId>>(); - locked_cache.put(plan_id.clone(), stmt, schema_info, table_ids)?; - // The statement was found in the cache, so we can execute it. - let Some(res) = read_from_cache::<R, M>( - locked_cache, - &pattern_with_params.params, - tables_with_data, - plan_id, - vtable_max_rows, - opts.clone(), - )? - else { - unreachable!( - "The statement {stmt_id} was just prepared and put into the cache. SQL: {}", - &pattern_with_params.pattern - ); - }; - Ok(res) - } - // Possibly the statement is correct, but doesn't fit into - // Tarantool's prepared statements cache (`sql_cache_size`). - // So we try to execute it bypassing the cache. - Err(e) => { - // We need to lock the cache though we are not going to use it. If we don't - // lock it, the prepared statement made from our pattern can be inserted into - // the cache by some other fiber because we have removed some big statements - // with LRU and tarantool cache has enough space to store this statement. - // And it can cause races in the temporary tables. - read_bypassing_cache::<R, R::Mutex>( - &pattern_with_params.pattern, - &pattern_with_params.params, - plan_id, - tables_with_data, - vtable_max_rows, - opts, - ) - } - } -} - -/// Execute read statement that can be cached. -/// -/// If statement is in the runtime's cache it is executed, -/// otherwise the optional data (plan) is compiled into -/// the string. Then we try to prepare the statement and -/// put it into the cache. if prepare fails, the statement -/// is executed anyway. -/// -/// # Note -/// It is responsibility of the caller to check that -/// statement can be cached or that it is a read statement. -/// -/// # Errors -/// - Failed to borrow runtime's cache -/// - Tarantool execution error for given statement -/// - Failed to compile the optional data -/// - Failed to prepare the statement -#[allow(unused_variables)] -pub fn execute_dql<R: Vshard + QueryCache>( +/// - something wrong with the statement in the cache. +pub fn read_or_prepare<R: QueryCache>( runtime: &R, - required: &mut RequiredData, - optional: &mut OptionalData, + info: &mut impl PlanInfo, ) -> Result<Box<dyn Any>, SbroadError> where R::Cache: StorageCache, { - let opts = std::mem::take(&mut required.options.execute_options); - let mut tables = std::mem::take(&mut required.tables); - let try_cache = !tables - .keys() - .any(|node_id| Space::find(&table_name(required.plan_id.as_str(), *node_id)).is_none()); + let mut tmp_tables = info.extract_data(); + let plan_id = info.id(); + let vdbe_max_steps = info.vdbe_max_steps(); + let max_rows = info.vtable_max_rows(); + let parameters = info.params(); + + // Look for the statement in the cache. let mut locked_cache = runtime.cache().lock(); - if try_cache { - if let Some(res) = read_from_cache::<R, R::Mutex>( + let is_cached = locked_cache.get(plan_id)?.is_some(); + if is_cached { + // The statement was found in the cache, so we can execute it. + let res = cache_hit::<R, R::Mutex>( &mut locked_cache, - &required.parameters, - &mut tables, - &required.plan_id, - required.options.vtable_max_rows, - opts.clone(), - )? { - return Ok(res); - } + parameters, + &mut tmp_tables, + plan_id, + vdbe_max_steps, + max_rows, + )?; + return Ok(res); + } + // The statement was not found in the cache, so we need to prepare it. + let (pattern_with_params, mut guards) = info.extract_query_and_table_guard()?; + let plan_id = info.id(); + let (pattern, params) = pattern_with_params.into_parts(); + if let Ok(stmt) = prepare(pattern.clone()) { + let table_ids: Vec<NodeId> = tmp_tables.keys().copied().collect(); + locked_cache.put(plan_id.clone(), stmt, info.schema_info(), table_ids)?; + // It is safe to skip truncating temporary tables here as there are no early + // returns after this point that could leave the tables populated with data. + guards.iter_mut().for_each(TableGuard::skip_truncate); + let res = cache_miss::<R, R::Mutex>( + &mut locked_cache, + ¶ms, + &mut tmp_tables, + plan_id, + vdbe_max_steps, + max_rows, + )?; + return Ok(res); } - let (pattern_with_params, mut guards) = compile_optional(optional, &required.plan_id)?; - // There were no errors during the compilation, so we can skip truncating - // temporary tables in the table guards (prepare_and_read will do it). - guards.iter_mut().for_each(TableGuard::skip_truncate); - prepare_and_read::<R, R::Mutex>( - &mut locked_cache, - &pattern_with_params, - &required.plan_id, - required.options.vtable_max_rows, - opts, - &required.schema_info, - &mut tables, + + // Possibly the statement is correct, but doesn't fit into + // Tarantool's prepared statements cache (`sql_cache_size`). + // So we try to execute it bypassing the cache. + + // We need the cache to be locked though we are not going to use it. If we don't lock it, + // the prepared statement made from our pattern can be inserted into the cache by some + // other fiber because we have removed some big statements with LRU and tarantool cache + // has enough space to store this statement. And it can cause races in the temporary + // tables. + + read_bypassing_cache( + &pattern, + ¶ms, + plan_id, + &mut tmp_tables, + vdbe_max_steps, + max_rows, ) } @@ -1390,7 +1487,8 @@ where let plan = optional.exec_plan.get_ir_plan(); let column_names = plan.get_relational_aliases(subplan_top_id)?; optional.exec_plan.get_mut_ir_plan().restore_constants()?; - let result = execute_dql(runtime, required, optional)?; + let mut info = QueryInfo::new(optional, required); + let result = read_or_prepare(runtime, &mut info)?; let tuple = result.downcast::<Tuple>().map_err(|e| { SbroadError::FailedTo( Action::Deserialize, @@ -1893,65 +1991,11 @@ where } let result = execute_dml_on_storage(runtime, raw_optional, required)?; - let tuple = Tuple::new(&(result,)) + let tuple = Tuple::new(&[result]) .map_err(|e| SbroadError::Invalid(Entity::Tuple, Some(format_smolstr!("{e:?}"))))?; Ok(Box::new(tuple) as Box<dyn Any>) } -/// The same as `execute_dql` but accepts raw optional data. -/// See docs for `execute_dql` -/// -/// # Errors -/// - Failed to borrow runtime's cache -/// - Tarantool execution error for given statement -/// - Failed to compile the optional data -/// - Failed to prepare the statement -#[allow(unused_variables)] -pub fn execute_dql_with_raw_optional<R: Vshard + QueryCache>( - runtime: &R, - required: &mut RequiredData, - raw_optional: &mut Vec<u8>, -) -> Result<Box<dyn Any>, SbroadError> -where - R::Cache: StorageCache, -{ - let opts = std::mem::take(&mut required.options.execute_options); - let mut tables = std::mem::take(&mut required.tables); - let try_cache = !tables - .keys() - .any(|node_id| Space::find(&table_name(&required.plan_id, *node_id)).is_none()); - let mut locked_cache = runtime.cache().lock(); - if try_cache { - if let Some(res) = read_from_cache::<R, R::Mutex>( - &mut locked_cache, - &required.parameters, - &mut tables, - &required.plan_id, - required.options.vtable_max_rows, - opts.clone(), - )? { - return Ok(res); - } - } - let (pattern_with_params, mut guards) = { - let data = std::mem::take(raw_optional); - let mut optional = OptionalData::try_from(EncodedOptionalData::from(data))?; - compile_optional(&mut optional, &required.plan_id)? - }; - // There were no errors during the compilation, so we can skip truncating - // temporary tables in the table guards (prepare_and_read will do it). - guards.iter_mut().for_each(TableGuard::skip_truncate); - prepare_and_read::<R, R::Mutex>( - &mut locked_cache, - &pattern_with_params, - &required.plan_id, - required.options.vtable_max_rows, - opts, - &required.schema_info, - &mut tables, - ) -} - /// A common function for all engines to calculate the sharding key value from a `map` /// of { `column_name` -> value }. Used as a helper function of `extract_sharding_keys_from_map` /// that is called from `calculate_bucket_id`. `map` must contain a value for each sharding @@ -2108,29 +2152,8 @@ fn parse_rows(tuple: &Tuple) -> Result<&[u8], SbroadError> { } fn encode_result_tuple(metadata: &[MetadataColumn], rows: &[u8]) -> Result<Tuple, SbroadError> { - #[derive(Debug, Default)] - struct MpByteCounter(usize); - - impl MpByteCounter { - #[must_use] - pub fn bytes(&self) -> usize { - self.0 - } - } - - impl std::io::Write for MpByteCounter { - fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { - self.0 += buf.len(); - Ok(buf.len()) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } - } - fn count_mp_bytes(v: impl Serialize) -> usize { - let mut byte_counter: MpByteCounter = MpByteCounter::default(); + let mut byte_counter: ByteCounter = ByteCounter::default(); let mut ser = rmp_serde::Serializer::new(&mut byte_counter); v.serialize(&mut ser).expect("counting failed"); byte_counter.bytes() diff --git a/sbroad-core/src/executor/engine/helpers/storage.rs b/sbroad-core/src/executor/engine/helpers/storage.rs index 931c9be38..f4f0aa9db 100644 --- a/sbroad-core/src/executor/engine/helpers/storage.rs +++ b/sbroad-core/src/executor/engine/helpers/storage.rs @@ -1,55 +1,194 @@ -use smol_str::{SmolStr, ToSmolStr}; +use rmp::encode::write_array_len; +use sbroad_proc::otm_child_span; +use smol_str::{format_smolstr, SmolStr}; +use std::any::Any; +use std::collections::HashMap; +use std::io::Read; +use tarantool::session::with_su; +use tarantool::space::Space; +use tarantool::sql::{ + prepare as tnt_prepare, prepare_and_execute_raw, unprepare as tnt_unprepare, Statement, +}; +use tarantool::tuple::{Tuple, TupleBuffer}; -use crate::errors::{Entity, SbroadError}; +use crate::backend::sql::space::ADMIN_ID; +use crate::error; +use crate::errors::SbroadError; +use crate::executor::lru::DEFAULT_CAPACITY; +use crate::ir::value::{EncodedValue, Value}; +use crate::ir::NodeId; +use crate::otm::child_span; +use crate::utils::ByteCounter; -pub mod meta; -pub mod runtime; +use super::table_name; -pub struct Statement { - id: u32, - pattern: SmolStr, +const IPROTO_DATA: u8 = 0x30; +const IPROTO_META: u8 = 0x32; + +/// Storage runtime configuration. +#[allow(clippy::module_name_repetitions)] +pub struct StorageMetadata { + /// Prepared statements cache capacity (on the storage). + pub storage_capacity: usize, + /// Prepared statements cache size in bytes (on the storage). + /// If a new statement is bigger doesn't fit into the cache, + /// it would not be cached but executed directly. + pub storage_size_bytes: usize, } -#[derive(Default)] -pub struct PreparedStmt(Option<Statement>); +impl Default for StorageMetadata { + fn default() -> Self { + Self::new() + } +} -impl PreparedStmt { - /// Extract prepared statement from the cache. - /// - /// # Errors - /// - Returns None instead of a regular statement (sentinel node in the cache). - pub fn statement(&self) -> Result<&Statement, SbroadError> { - self.0.as_ref().ok_or_else(|| { - SbroadError::Invalid( - Entity::Statement, - Some("Statement is not prepared".to_smolstr()), - ) - }) +impl StorageMetadata { + #[must_use] + pub fn new() -> Self { + StorageMetadata { + storage_capacity: DEFAULT_CAPACITY, + storage_size_bytes: 1024 * DEFAULT_CAPACITY, + } } - /// Get the id of the prepared statement. - /// - /// # Errors - /// - Returns sentinel node from the cache (internal error). - pub fn id(&self) -> Result<u32, SbroadError> { - Ok(self.statement()?.id) + #[must_use] + pub fn is_empty(&self) -> bool { + self.storage_capacity == 0 && self.storage_size_bytes == 0 } +} + +#[otm_child_span("tarantool.statement.prepare")] +pub fn prepare(pattern: String) -> Result<Statement, SbroadError> { + let stmt = tnt_prepare(pattern).map_err(|e| { + error!(Option::from("prepare"), &format!("{e:?}")); + SbroadError::from(e) + })?; + Ok(stmt) +} - /// Get the pattern of the prepared statement. - /// - /// # Errors - /// - Returns sentinel node from the cache (internal error). - pub fn pattern(&self) -> Result<&str, SbroadError> { - Ok(&self.statement()?.pattern) +#[otm_child_span("tarantool.statement.unprepare")] +pub fn unprepare( + plan_id: &SmolStr, + entry: &mut (Statement, Vec<NodeId>), +) -> Result<(), SbroadError> { + let (stmt, table_ids) = std::mem::take(entry); + + // Remove the statement from the instance cache. + tnt_unprepare(stmt); + + // Remove temporary tables from the instance. + for node_id in table_ids { + let table = table_name(plan_id, node_id); + Space::find(table.as_str()).map(|space| with_su(ADMIN_ID, || space.drop())); } + + Ok(()) } -impl std::fmt::Debug for PreparedStmt { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(ref stmt) = self.0 { - write!(f, "PreparedStmt {:?}", stmt.pattern) - } else { - write!(f, "PreparedStmt None") +type EncodedMetadata = rmpv::Value; +type EncodedData = rmpv::Value; + +fn parse_dql(stream: &mut (impl Read + Sized)) -> (EncodedMetadata, EncodedData) { + let map_len = rmp::decode::read_map_len(stream).expect("failed to read DQL result"); + assert_eq!(map_len, 2, "invalid format for DQL result"); + let mut meta = None; + let mut data = None; + for _ in 0..map_len { + let key = rmp::decode::read_pfix(stream).expect("failed to read IPROTO key"); + match key { + IPROTO_META => { + meta = Some(rmpv::decode::read_value(stream).expect("failed to read DQL metadata")); + } + IPROTO_DATA => { + data = Some(rmpv::decode::read_value(stream).expect("failed to read DQL data")); + } + _ => { + unreachable!("unexpected IPROTO key: {}", key); + } } } + ( + meta.expect("missing DQL metadata"), + data.expect("missing DQL data"), + ) +} + +fn repack_meta(meta: EncodedMetadata) -> (rmpv::Value, rmpv::Value) { + let mut maps = rmpv::ext::from_value::<Vec<HashMap<u32, rmpv::Value>>>(meta) + .expect("failed to decode DQL metadata"); + let mut repacked = Vec::with_capacity(2); + for mut map in maps.drain(..) { + let col_name = map.remove(&0).expect("missing name in DQL metadata"); + let col_type = map.remove(&1).expect("missing type in DQL metadata"); + let inner = vec![("name".into(), col_name), ("type".into(), col_type)]; + repacked.push(rmpv::Value::Map(inner)); + } + ("metadata".into(), rmpv::Value::Array(repacked)) +} + +fn repack_data( + data: EncodedData, + max_rows: u64, +) -> Result<(rmpv::Value, rmpv::Value), SbroadError> { + let rows = rmpv::ext::from_value::<Vec<rmpv::Value>>(data).expect("failed to decode DQL data"); + if rows.len() as u64 > max_rows { + return Err(SbroadError::UnexpectedNumberOfValues(format_smolstr!( + "expected at most {} rows, got {}", + max_rows, + rows.len() + ))); + } + Ok(("rows".into(), rmpv::Value::Array(rows))) +} + +fn dql_result_to_tuple( + stream: &mut (impl Read + Sized), + max_rows: u64, +) -> Result<Tuple, SbroadError> { + let (meta, data) = parse_dql(stream); + let new_meta = repack_meta(meta); + let new_data = repack_data(data, max_rows)?; + let repacked = rmpv::Value::Map(vec![new_meta, new_data]); + // To pre-allocate the buffer, we need to know the size of the encoded value. + let mut byte_counter = ByteCounter::default(); + rmpv::encode::write_value(&mut byte_counter, &repacked).expect("failed to write result"); + let mut buf = Vec::with_capacity(byte_counter.bytes()); + write_array_len(&mut buf, 1).expect("failed to write array length"); + rmpv::encode::write_value(&mut buf, &repacked).expect("failed to write result"); + let tup_buf = TupleBuffer::try_from_vec(buf).expect("failed to convert to tuple buffer"); + Ok(Tuple::from(&tup_buf)) +} + +fn encoded_params(params: &[Value]) -> Vec<EncodedValue> { + params.iter().map(EncodedValue::from).collect() +} + +#[otm_child_span("tarantool.statement.prepared.execute")] +pub fn execute_prepared( + stmt: &Statement, + params: &[Value], + vdbe_max_steps: u64, + max_rows: u64, +) -> Result<Box<dyn Any>, SbroadError> { + let encoded_params = encoded_params(params); + let mut stream = with_su(ADMIN_ID, || { + stmt.execute_raw(&encoded_params, vdbe_max_steps) + })??; + let tuple = dql_result_to_tuple(&mut stream, max_rows)?; + Ok(Box::new(tuple) as Box<dyn Any>) +} + +#[otm_child_span("tarantool.statement.unprepared.execute")] +pub fn execute_unprepared( + query: &str, + params: &[Value], + vdbe_max_steps: u64, + max_rows: u64, +) -> Result<Box<dyn Any>, SbroadError> { + let encoded_params = encoded_params(params); + let mut stream = with_su(ADMIN_ID, || { + prepare_and_execute_raw(query, &encoded_params, vdbe_max_steps) + })??; + let tuple = dql_result_to_tuple(&mut stream, max_rows)?; + Ok(Box::new(tuple) as Box<dyn Any>) } diff --git a/sbroad-core/src/executor/engine/helpers/storage/meta.rs b/sbroad-core/src/executor/engine/helpers/storage/meta.rs deleted file mode 100644 index 6e01195a0..000000000 --- a/sbroad-core/src/executor/engine/helpers/storage/meta.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::executor::lru::DEFAULT_CAPACITY; - -pub const DEFAULT_JAEGER_AGENT_HOST: &str = "localhost"; -pub const DEFAULT_JAEGER_AGENT_PORT: u16 = 6831; - -/// Storage runtime configuration. -#[allow(clippy::module_name_repetitions)] -pub struct StorageMetadata { - /// Prepared statements cache capacity (on the storage). - pub storage_capacity: usize, - /// Prepared statements cache size in bytes (on the storage). - /// If a new statement is bigger doesn't fit into the cache, - /// it would not be cached but executed directly. - pub storage_size_bytes: usize, - /// Jaeger agent host - pub jaeger_agent_host: &'static str, - /// Jaeger agent port - pub jaeger_agent_port: u16, -} - -impl Default for StorageMetadata { - fn default() -> Self { - Self::new() - } -} - -impl StorageMetadata { - #[must_use] - pub fn new() -> Self { - StorageMetadata { - storage_capacity: DEFAULT_CAPACITY, - storage_size_bytes: 1024 * DEFAULT_CAPACITY, - jaeger_agent_host: DEFAULT_JAEGER_AGENT_HOST, - jaeger_agent_port: DEFAULT_JAEGER_AGENT_PORT, - } - } - - #[must_use] - pub fn is_empty(&self) -> bool { - self.storage_capacity == 0 && self.storage_size_bytes == 0 - } -} diff --git a/sbroad-core/src/executor/lru.rs b/sbroad-core/src/executor/lru.rs index b0861d81b..749670b5a 100644 --- a/sbroad-core/src/executor/lru.rs +++ b/sbroad-core/src/executor/lru.rs @@ -42,7 +42,7 @@ pub trait Cache<Key, Value> { struct LRUNode<Key, Value> where Key: Clone, - Value: Default + Debug, + Value: Default, { /// The value of the node. value: Value, @@ -55,7 +55,7 @@ where impl<Key, Value> LRUNode<Key, Value> where Key: Clone, - Value: Default + Debug, + Value: Default, { fn new(value: Value) -> Self { LRUNode { @@ -81,7 +81,7 @@ where pub struct LRUCache<Key, Value> where Key: Clone, - Value: Default + Debug, + Value: Default, { /// The capacity of the cache. capacity: usize, @@ -95,7 +95,7 @@ where impl<Key, Value> LRUCache<Key, Value> where - Value: Default + Debug, + Value: Default, Key: Clone + Eq + std::hash::Hash + std::fmt::Debug, { fn get_node_or_none(&self, key: &Option<Key>) -> Option<&LRUNode<Key, Value>> { @@ -234,7 +234,7 @@ where impl<Key, Value> Cache<Key, Value> for LRUCache<Key, Value> where - Value: Default + Debug, + Value: Default, Key: Clone + Eq + std::hash::Hash + std::fmt::Debug, { fn new(capacity: usize, evict_fn: Option<EvictFn<Key, Value>>) -> Result<Self, SbroadError> { diff --git a/sbroad-core/src/executor/result.rs b/sbroad-core/src/executor/result.rs index 711924234..b7b49eca8 100644 --- a/sbroad-core/src/executor/result.rs +++ b/sbroad-core/src/executor/result.rs @@ -10,9 +10,11 @@ //! * `row_count` (u64): the number of tuples inserted (that may be equal to 0) use core::fmt::Debug; +use serde::de::Error as DeError; use serde::ser::{Serialize, SerializeMap, Serializer}; -use serde::Deserialize; +use serde::{Deserialize, Deserializer}; use smol_str::{SmolStr, ToSmolStr}; +use std::collections::HashMap; use tarantool::tlua::{self, LuaRead}; use tarantool::tuple::Encode; @@ -27,7 +29,7 @@ use crate::ir::{Node, Plan}; pub type ExecutorTuple = Vec<LuaValue>; -#[derive(LuaRead, Debug, Deserialize, PartialEq, Eq, Clone)] +#[derive(LuaRead, Debug, PartialEq, Eq, Clone)] pub struct MetadataColumn { name: String, r#type: String, @@ -52,6 +54,25 @@ impl Serialize for MetadataColumn { } } +impl<'de> Deserialize<'de> for MetadataColumn { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + let map = HashMap::<String, String>::deserialize(deserializer)?; + let col_name = map + .get("name") + .ok_or_else(|| DeError::custom("missing name in DQL metadata"))?; + let col_type = map + .get("type") + .ok_or_else(|| DeError::custom("missing type in DQL metadata"))?; + Ok(MetadataColumn::new( + col_name.to_string(), + col_type.to_string(), + )) + } +} + impl TryInto<Column> for &MetadataColumn { type Error = SbroadError; diff --git a/sbroad-core/src/executor/vtable.rs b/sbroad-core/src/executor/vtable.rs index 2577f7184..4ba1916fd 100644 --- a/sbroad-core/src/executor/vtable.rs +++ b/sbroad-core/src/executor/vtable.rs @@ -559,7 +559,7 @@ impl VirtualTable { rows.push(row); } - let res = vec![ProducerResult { metadata, rows }]; + let res = [ProducerResult { metadata, rows }]; #[cfg(feature = "mock")] { Ok(Box::new(res)) diff --git a/sbroad-core/src/ir.rs b/sbroad-core/src/ir.rs index ad2cbc2e1..563f0fcca 100644 --- a/sbroad-core/src/ir.rs +++ b/sbroad-core/src/ir.rs @@ -306,6 +306,32 @@ impl ExecuteOptions { pub fn insert(&mut self, kind: OptionKind, value: Value) -> Option<Value> { self.0.insert(kind, value) } + + #[must_use] + pub fn vdbe_max_steps(&self) -> u64 { + self.0 + .get(&OptionKind::SqlVdbeMaxSteps) + .map_or(DEFAULT_VDBE_MAX_STEPS, |v| { + if let Value::Unsigned(steps) = v { + *steps + } else { + DEFAULT_VDBE_MAX_STEPS + } + }) + } + + #[must_use] + pub fn vtable_max_rows(&self) -> u64 { + self.0 + .get(&OptionKind::VTableMaxRows) + .map_or(DEFAULT_VTABLE_MAX_ROWS, |v| { + if let Value::Unsigned(rows) = v { + *rows + } else { + DEFAULT_VTABLE_MAX_ROWS + } + }) + } } impl<L> tlua::PushInto<L> for ExecuteOptions -- GitLab