diff --git a/Cargo.lock b/Cargo.lock index 4c5a0077193..0f2a17d104f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -920,7 +920,7 @@ checksum = "37672978ae0febce7516ae0a85b53e6185159a9a28787391eb63fc44ec36037d" dependencies = [ "async-fs", "futures-lite", - "thiserror 2.0.17", + "thiserror 2.0.21", ] [[package]] @@ -1202,6 +1202,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" +[[package]] +name = "base16ct" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" + [[package]] name = "base62" version = "2.2.1" @@ -1674,7 +1680,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d8af896b707212cd0e99c112a78c9497dd32994192a463ed2f7419d29bd8c6" dependencies = [ "serde", - "thiserror 2.0.17", + "thiserror 2.0.21", "toml 0.8.23", ] @@ -2701,7 +2707,7 @@ dependencies = [ "serde_json", "serde_with", "snafu 0.8.6", - "sqlx", + "sqlx 0.9.0", "store-api", "strum 0.27.1", "table", @@ -3457,6 +3463,20 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "crypto-bigint" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" +dependencies = [ + "cpubits", + "ctutils", + "num-traits", + "rand_core 0.10.0", + "serdect", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -3477,6 +3497,16 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "crypto-primes" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3633a51a39c69ebbaa4feaa694bd83d241e4093901c84a0963b19d9bb3f0cf8f" +dependencies = [ + "crypto-bigint", + "rand_core 0.10.0", +] + [[package]] name = "crypto_secretbox" version = "0.1.1" @@ -4637,7 +4667,18 @@ dependencies = [ "const-oid 0.9.6", "der_derive", "flagset", - "pem-rfc7468", + "pem-rfc7468 0.7.0", + "zeroize", +] + +[[package]] +name = "der" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" +dependencies = [ + "const-oid 0.10.2", + "pem-rfc7468 1.0.0", "zeroize", ] @@ -4975,7 +5016,7 @@ dependencies = [ "chrono", "rust_decimal", "serde", - "thiserror 2.0.17", + "thiserror 2.0.21", "time", "winnow 0.6.26", ] @@ -5159,6 +5200,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "etcetera" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96" +dependencies = [ + "cfg-if", + "windows-sys 0.61.2", +] + [[package]] name = "ethnum" version = "1.5.3" @@ -5501,6 +5552,17 @@ dependencies = [ "spin 0.9.8", ] +[[package]] +name = "flume" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -5767,9 +5829,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -5777,15 +5839,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -5805,9 +5867,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-lite" @@ -5824,26 +5886,26 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-timer" @@ -5853,9 +5915,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -5865,7 +5927,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -6254,6 +6315,15 @@ dependencies = [ "hashbrown 0.15.4", ] +[[package]] +name = "hashlink" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "hdfs-native" version = "0.14.6" @@ -6288,7 +6358,7 @@ dependencies = [ "regex", "roxmltree", "socket2 0.6.4", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "url", "uuid", @@ -6381,6 +6451,15 @@ dependencies = [ "hmac 0.12.1", ] +[[package]] +name = "hkdf" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" +dependencies = [ + "hmac 0.13.0", +] + [[package]] name = "hmac" version = "0.12.1" @@ -6631,7 +6710,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.9", + "webpki-roots 1.0.10", ] [[package]] @@ -7405,7 +7484,7 @@ dependencies = [ "jni-sys", "log", "simd_cesu8", - "thiserror 2.0.17", + "thiserror 2.0.21", "walkdir", "windows-link 0.2.1", ] @@ -7532,7 +7611,7 @@ dependencies = [ "pest_derive", "regex", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.21", ] [[package]] @@ -8060,7 +8139,7 @@ checksum = "656b3b27f8893f7bbf9485148ff9a65f019e3f33bd5cdc87c83cab16b3fd9ec8" dependencies = [ "libc", "neli", - "thiserror 2.0.17", + "thiserror 2.0.21", "windows-sys 0.59.0", ] @@ -8296,7 +8375,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb4bdc8b0ce69932332cf76d24af69c3a155242af95c226b2ab6c2e371ed1149" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.21", "zerocopy", "zerocopy-derive", ] @@ -8528,7 +8607,7 @@ dependencies = [ "serde_json", "servers", "snafu 0.8.6", - "sqlx", + "sqlx 0.9.0", "store-api", "strum 0.27.1", "table", @@ -8880,7 +8959,7 @@ dependencies = [ "twox-hash", "url", "webpki", - "webpki-roots 1.0.9", + "webpki-roots 1.0.10", ] [[package]] @@ -8916,7 +8995,7 @@ dependencies = [ "quote", "syn 2.0.117", "termcolor", - "thiserror 2.0.17", + "thiserror 2.0.21", ] [[package]] @@ -8940,13 +9019,13 @@ dependencies = [ "rustls", "serde", "socket2 0.6.4", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tokio-rustls", "tokio-util", "twox-hash", "url", - "webpki-roots 1.0.9", + "webpki-roots 1.0.10", ] [[package]] @@ -9012,7 +9091,7 @@ dependencies = [ "serde_json", "sha1 0.10.6", "sha2 0.10.9", - "thiserror 2.0.17", + "thiserror 2.0.21", "time", "uuid", ] @@ -9041,7 +9120,7 @@ dependencies = [ "serde_json", "sha1 0.11.0", "sha2 0.11.0", - "thiserror 2.0.17", + "thiserror 2.0.21", "uuid", ] @@ -9583,7 +9662,7 @@ dependencies = [ "itertools 0.14.0", "parking_lot 0.12.4", "percent-encoding", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tracing", "url", @@ -9924,7 +10003,7 @@ dependencies = [ "asyncband", "opendal-core", "serde", - "sqlx", + "sqlx 0.8.6", ] [[package]] @@ -9997,7 +10076,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.17", + "thiserror 2.0.21", "tracing", ] @@ -10027,7 +10106,7 @@ dependencies = [ "opentelemetry_sdk", "prost 0.14.1", "reqwest 0.13.4", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tonic 0.14.2", "tonic-types", @@ -10074,7 +10153,7 @@ dependencies = [ "percent-encoding", "portable-atomic", "rand 0.9.4", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tokio-stream", ] @@ -10580,7 +10659,7 @@ checksum = "500fa4cdeacd98997c5865e3d0d1cb8fe7e9d7d75ecc775e07989a433a9a9a59" dependencies = [ "arrayvec", "bitflags 2.12.1", - "thiserror 2.0.17", + "thiserror 2.0.21", "zerocopy", "zerocopy-derive", ] @@ -10610,6 +10689,15 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pem-rfc7468" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -10629,7 +10717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" dependencies = [ "memchr", - "thiserror 2.0.17", + "thiserror 2.0.21", "ucd-trie", ] @@ -10735,7 +10823,7 @@ dependencies = [ "serde_json", "smol_str", "stringprep", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tokio-rustls", "tokio-util", @@ -10929,9 +11017,19 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der", - "pkcs8", - "spki", + "der 0.7.10", + "pkcs8 0.10.2", + "spki 0.7.3", +] + +[[package]] +name = "pkcs1" +version = "0.8.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f485dbafe293ea6ccaa7d82bc591651a796eb8a9aec3df040b057b706073dbc3" +dependencies = [ + "der 0.8.2", + "spki 0.8.1", ] [[package]] @@ -10942,11 +11040,11 @@ checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" dependencies = [ "aes 0.8.4", "cbc 0.1.2", - "der", + "der 0.7.10", "pbkdf2", "scrypt", "sha2 0.10.9", - "spki", + "spki 0.7.3", ] [[package]] @@ -10955,10 +11053,20 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", + "der 0.7.10", "pkcs5", "rand_core 0.6.4", - "spki", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" +dependencies = [ + "der 0.8.2", + "spki 0.8.1", ] [[package]] @@ -11138,7 +11246,7 @@ dependencies = [ "spin 0.10.1", "symbolic-demangle", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.21", ] [[package]] @@ -11341,7 +11449,7 @@ dependencies = [ "parking_lot 0.12.4", "procfs", "protobuf 3.7.2", - "thiserror 2.0.17", + "thiserror 2.0.21", ] [[package]] @@ -11944,7 +12052,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2 0.5.10", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tracing", "web-time", @@ -11967,7 +12075,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror 2.0.21", "tinyvec", "tracing", "web-time", @@ -12436,7 +12544,7 @@ dependencies = [ "pem", "percent-encoding", "reqsign-core", - "rsa", + "rsa 0.9.10", "serde", "serde_json", "sha1 0.11.0", @@ -12459,7 +12567,7 @@ dependencies = [ "log", "mea", "percent-encoding", - "rsa", + "rsa 0.9.10", "serde", "serde_json", "sha1 0.11.0", @@ -12490,7 +12598,7 @@ dependencies = [ "percent-encoding", "reqsign-aws-v4", "reqsign-core", - "rsa", + "rsa 0.9.10", "serde", "serde_json", "tokio", @@ -12536,7 +12644,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams 0.4.2", "web-sys", - "webpki-roots 1.0.9", + "webpki-roots 1.0.10", ] [[package]] @@ -12612,7 +12720,7 @@ dependencies = [ "reqwest 0.12.24", "reqwest-middleware", "retry-policies", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "wasmtimer", ] @@ -12731,16 +12839,34 @@ dependencies = [ "num-bigint-dig", "num-integer", "num-traits", - "pkcs1", - "pkcs8", + "pkcs1 0.7.5", + "pkcs8 0.10.2", "rand_core 0.6.4", "sha2 0.10.9", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", "subtle", "zeroize", ] +[[package]] +name = "rsa" +version = "0.10.0-rc.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33405e321e16ef941ca66e254f6904c3aafd3c7ff001fb88bf11c73eb75c2b85" +dependencies = [ + "const-oid 0.10.2", + "crypto-bigint", + "crypto-primes", + "digest 0.11.3", + "pkcs1 0.8.0-rc.5", + "pkcs8 0.11.0", + "rand_core 0.10.0", + "signature 3.0.0", + "spki 0.8.1", + "zeroize", +] + [[package]] name = "rsasl" version = "2.2.1" @@ -12757,7 +12883,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "stringprep", - "thiserror 2.0.17", + "thiserror 2.0.21", ] [[package]] @@ -12777,7 +12903,7 @@ dependencies = [ "rsasl", "rustls", "snap", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tokio-rustls", "tracing", @@ -13254,7 +13380,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "thiserror 2.0.17", + "thiserror 2.0.21", ] [[package]] @@ -13507,6 +13633,16 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "servers" version = "1.4.0-alpha.0" @@ -13781,6 +13917,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" +dependencies = [ + "digest 0.11.3", + "rand_core 0.10.0", +] + [[package]] name = "simba" version = "0.9.0" @@ -14009,7 +14155,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.10", +] + +[[package]] +name = "spki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef958a98b9d5da290cfc78946e9f3e61e1e62a18db0d92cac0b83cc161491a9" +dependencies = [ + "base64ct", + "der 0.8.2", ] [[package]] @@ -14136,11 +14292,24 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" dependencies = [ - "sqlx-core", - "sqlx-macros", - "sqlx-mysql", - "sqlx-postgres", - "sqlx-sqlite", + "sqlx-core 0.8.6", + "sqlx-macros 0.8.6", + "sqlx-mysql 0.8.6", + "sqlx-postgres 0.8.6", + "sqlx-sqlite 0.8.6", +] + +[[package]] +name = "sqlx" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "378620ccc25c62c89d8be1c819e76a88d59bdcc3304733330788948e619bfd71" +dependencies = [ + "sqlx-core 0.9.0", + "sqlx-macros 0.9.0", + "sqlx-mysql 0.9.0", + "sqlx-postgres 0.9.0", + "sqlx-sqlite 0.9.0", ] [[package]] @@ -14151,7 +14320,6 @@ checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ "base64 0.22.1", "bytes", - "chrono", "crc", "crossbeam-queue", "either", @@ -14161,24 +14329,61 @@ dependencies = [ "futures-io", "futures-util", "hashbrown 0.15.4", - "hashlink", + "hashlink 0.10.0", "indexmap 2.14.2", "log", "memchr", "once_cell", "percent-encoding", + "rustls", + "serde", + "serde_json", + "sha2 0.10.9", + "smallvec", + "thiserror 2.0.21", + "tokio", + "tokio-stream", + "tracing", + "url", + "webpki-roots 0.26.11", +] + +[[package]] +name = "sqlx-core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b44e85bf579a8eeb4ceaa77a3a523baf2bf0e9bac7e40f405d537b5d2d5ccb" +dependencies = [ + "base64 0.22.1", + "bytes", + "cfg-if", + "chrono", + "crc", + "crossbeam-queue", + "either", + "event-listener 5.4.0", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.16.1", + "hashlink 0.11.1", + "indexmap 2.14.2", + "log", + "memchr", + "percent-encoding", "rust_decimal", "rustls", "serde", "serde_json", "sha2 0.10.9", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tokio-stream", "tracing", "url", - "webpki-roots 0.26.11", + "webpki-roots 1.0.10", ] [[package]] @@ -14189,8 +14394,21 @@ checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" dependencies = [ "proc-macro2", "quote", - "sqlx-core", - "sqlx-macros-core", + "sqlx-core 0.8.6", + "sqlx-macros-core 0.8.6", + "syn 2.0.117", +] + +[[package]] +name = "sqlx-macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2b84f2bc39a5705ef27ec785a11c934a41bbd4a24941e257927cddc26b60bf" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core 0.9.0", + "sqlx-macros-core 0.9.0", "syn 2.0.117", ] @@ -14210,15 +14428,41 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.9", - "sqlx-core", - "sqlx-mysql", - "sqlx-postgres", - "sqlx-sqlite", + "sqlx-core 0.8.6", + "sqlx-mysql 0.8.6", + "sqlx-postgres 0.8.6", + "sqlx-sqlite 0.8.6", "syn 2.0.117", "tokio", "url", ] +[[package]] +name = "sqlx-macros-core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb8d96de5fdc85a5c4ec813432b523ec637e80ba98f046555f75f7908ddac7c3" +dependencies = [ + "cfg-if", + "dotenvy", + "either", + "heck 0.5.0", + "hex", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.9", + "sqlx-core 0.9.0", + "sqlx-mysql 0.9.0", + "sqlx-postgres 0.9.0", + "sqlx-sqlite 0.9.0", + "syn 2.0.117", + "thiserror 2.0.21", + "tokio", + "url", +] + [[package]] name = "sqlx-mysql" version = "0.8.6" @@ -14230,7 +14474,6 @@ dependencies = [ "bitflags 2.12.1", "byteorder", "bytes", - "chrono", "crc", "digest 0.10.7", "dotenvy", @@ -14241,7 +14484,7 @@ dependencies = [ "futures-util", "generic-array", "hex", - "hkdf", + "hkdf 0.12.4", "hmac 0.12.1", "itoa", "log", @@ -14250,19 +14493,48 @@ dependencies = [ "once_cell", "percent-encoding", "rand 0.8.5", - "rsa", - "rust_decimal", + "rsa 0.9.10", "serde", "sha1 0.10.6", "sha2 0.10.9", "smallvec", - "sqlx-core", + "sqlx-core 0.8.6", "stringprep", - "thiserror 2.0.17", + "thiserror 2.0.21", "tracing", "whoami 1.6.0", ] +[[package]] +name = "sqlx-mysql" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90b8020fe17c5f2c245bfa2505d7ef59c5604839527c740266ad2214acebea27" +dependencies = [ + "bitflags 2.12.1", + "byteorder", + "bytes", + "chrono", + "crc", + "digest 0.11.3", + "dotenvy", + "either", + "futures-core", + "futures-util", + "generic-array", + "log", + "percent-encoding", + "rand 0.10.1", + "rsa 0.10.0-rc.19", + "rust_decimal", + "serde", + "sha1 0.11.0", + "sha2 0.11.0", + "sqlx-core 0.9.0", + "thiserror 2.0.21", + "tracing", +] + [[package]] name = "sqlx-postgres" version = "0.8.6" @@ -14273,15 +14545,14 @@ dependencies = [ "base64 0.22.1", "bitflags 2.12.1", "byteorder", - "chrono", "crc", "dotenvy", - "etcetera", + "etcetera 0.8.0", "futures-channel", "futures-core", "futures-util", "hex", - "hkdf", + "hkdf 0.12.4", "hmac 0.12.1", "home", "itoa", @@ -14290,18 +14561,54 @@ dependencies = [ "memchr", "once_cell", "rand 0.8.5", - "rust_decimal", "serde", "serde_json", "sha2 0.10.9", "smallvec", - "sqlx-core", + "sqlx-core 0.8.6", "stringprep", - "thiserror 2.0.17", + "thiserror 2.0.21", "tracing", "whoami 1.6.0", ] +[[package]] +name = "sqlx-postgres" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87a2bdd6e83f6b3ea525ca9fee568030508b58355a43d0b2c1674d5f79dcd65e" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.12.1", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera 0.11.0", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf 0.13.0", + "hmac 0.13.0", + "itoa", + "log", + "md-5 0.11.0", + "memchr", + "rand 0.10.1", + "rust_decimal", + "serde", + "serde_json", + "sha2 0.11.0", + "smallvec", + "sqlx-core 0.9.0", + "stringprep", + "thiserror 2.0.21", + "tracing", + "whoami 2.1.3", +] + [[package]] name = "sqlx-sqlite" version = "0.8.6" @@ -14309,8 +14616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" dependencies = [ "atoi", - "chrono", - "flume", + "flume 0.11.1", "futures-channel", "futures-core", "futures-executor", @@ -14321,8 +14627,33 @@ dependencies = [ "percent-encoding", "serde", "serde_urlencoded", - "sqlx-core", - "thiserror 2.0.17", + "sqlx-core 0.8.6", + "thiserror 2.0.21", + "tracing", + "url", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488e99c397a62007e4229aec669a179816339afc6d2620ca6fa420dbee2e982c" +dependencies = [ + "atoi", + "chrono", + "flume 0.12.0", + "form_urlencoded", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core 0.9.0", + "thiserror 2.0.21", "tracing", "url", ] @@ -14816,7 +15147,7 @@ dependencies = [ "tantivy-stacker", "tantivy-tokenizer-api", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.21", "time", "typetag", "uuid", @@ -15046,7 +15377,7 @@ dependencies = [ "snafu 0.8.6", "sql", "sqlparser", - "sqlx", + "sqlx 0.9.0", "store-api", "strum 0.27.1", "tinytemplate", @@ -15131,7 +15462,7 @@ dependencies = [ "session", "similar-asserts", "sql", - "sqlx", + "sqlx 0.9.0", "standalone", "store-api", "substrait 1.4.0-alpha.0", @@ -15163,11 +15494,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.21", ] [[package]] @@ -15183,13 +15514,13 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] @@ -15821,7 +16152,7 @@ checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c" dependencies = [ "crossbeam-channel", "symlink", - "thiserror 2.0.17", + "thiserror 2.0.21", "time", "tracing-subscriber", ] @@ -15991,7 +16322,7 @@ dependencies = [ "serde", "serde_json", "syn 2.0.117", - "thiserror 2.0.17", + "thiserror 2.0.21", "unicode-ident", ] @@ -16035,7 +16366,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f0495d3e02c0e9b074e5631de7af419b9f4fdbfec4b1ca1b3180c8b3a926cb5" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.21", "vu128", ] @@ -16363,7 +16694,7 @@ dependencies = [ "strum_macros 0.26.4", "syslog_loose", "termcolor", - "thiserror 2.0.17", + "thiserror 2.0.21", "tokio", "tracing", "ua-parser", @@ -16656,14 +16987,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.9", + "webpki-roots 1.0.10", ] [[package]] name = "webpki-roots" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +checksum = "1c1c8e20c8a38fc7d65abfe74eb7280e4aa667e8eec8bc84996d2874810748d9" dependencies = [ "rustls-pki-types", ] @@ -17320,8 +17651,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" dependencies = [ "const-oid 0.9.6", - "der", - "spki", + "der 0.7.10", + "spki 0.7.3", "tls_codec", ] @@ -17334,13 +17665,13 @@ dependencies = [ "bcder", "bytes", "chrono", - "der", + "der 0.7.10", "hex", "pem", "ring", - "signature", - "spki", - "thiserror 2.0.17", + "signature 2.2.0", + "spki 0.7.3", + "thiserror 2.0.21", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 1674063f0c6..f275cb8aada 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -250,7 +250,7 @@ similar-asserts = "1.6.0" smallvec = { version = "1", features = ["serde"] } snafu = "0.8" sqlparser = { version = "0.62.0", default-features = false, features = ["std", "visitor", "serde"] } -sqlx = { version = "0.8", default-features = false, features = [ +sqlx = { version = "0.9", default-features = false, features = [ "any", "macros", "json", diff --git a/src/common/meta/Cargo.toml b/src/common/meta/Cargo.toml index 64303b070c8..d235f6e9ad1 100644 --- a/src/common/meta/Cargo.toml +++ b/src/common/meta/Cargo.toml @@ -81,6 +81,7 @@ serde_with.workspace = true snafu.workspace = true sqlx = { workspace = true, features = [ "mysql", + "mysql-rsa", "chrono", ], optional = true } store-api.workspace = true diff --git a/src/common/meta/src/election/rds/mysql.rs b/src/common/meta/src/election/rds/mysql.rs index bd694e4ae19..5b350d11957 100644 --- a/src/common/meta/src/election/rds/mysql.rs +++ b/src/common/meta/src/election/rds/mysql.rs @@ -22,7 +22,7 @@ use snafu::{OptionExt, ResultExt, ensure}; use sqlx::mysql::{MySqlArguments, MySqlRow}; use sqlx::pool::PoolConnection; use sqlx::query::Query; -use sqlx::{MySql, MySqlPool, MySqlTransaction, Row}; +use sqlx::{AssertSqlSafe, MySql, MySqlPool, MySqlTransaction, Row}; use tokio::sync::{Mutex, MutexGuard, broadcast}; use tokio::time::MissedTickBehavior; @@ -38,6 +38,17 @@ use crate::error::{ }; use crate::key::{CANDIDATES_ROOT, ELECTION_KEY}; +/// Builds a [`Query`] from a dynamic SQL template. +/// +/// sqlx 0.9 requires `&'static str` or [`AssertSqlSafe`] to reject unaudited +/// dynamic SQL strings. The templates here are generated by +/// [`ElectionSqlFactory`] from the configured table name (operator config, +/// not user input), and all dynamic data is passed via bind parameters, +/// so it is safe to mark them with [`AssertSqlSafe`]. +fn template_query(sql: &str) -> Query<'_, MySql, MySqlArguments> { + sqlx::query(AssertSqlSafe(sql)) +} + struct ElectionSqlFactory<'a> { table_name: &'a str, } @@ -268,11 +279,11 @@ impl ElectionMysqlClient { async fn ensure_table_exists(&mut self) -> Result<()> { let create_table_sql = self.create_table_sql(); - let query = sqlx::query(&create_table_sql); + let query = template_query(&create_table_sql); self.execute(query, &create_table_sql).await?; // Insert at least one row for `SELECT * FOR UPDATE` to work. let insert_once_sql = self.insert_once_sql(); - let query = sqlx::query(&insert_once_sql); + let query = template_query(&insert_once_sql); self.execute(query, &insert_once_sql).await?; Ok(()) } @@ -324,7 +335,7 @@ impl ElectionMysqlClient { /// if `current` is `None`. async fn check_version(&mut self, sql: &str) -> Result<()> { // Check if the MySQL version is supported. - let query = sqlx::query(sql); + let query = template_query(sql); // Safety: `maybe_init_client` ensures `current` is not `None`. let client = self.current.as_mut().unwrap(); let row = tokio::time::timeout(self.execution_timeout, query.fetch_one(&mut **client)) @@ -692,7 +703,7 @@ impl MySqlElection { executor: &mut Executor<'_>, ) -> Result> { let key = key.as_bytes(); - let query = sqlx::query(&self.sql_set.get_value_with_lease).bind(key); + let query = template_query(&self.sql_set.get_value_with_lease).bind(key); let res = executor .query(query, &self.sql_set.get_value_with_lease) .await?; @@ -728,7 +739,7 @@ impl MySqlElection { executor: &mut Executor<'_>, ) -> Result<(Vec<(String, Timestamp)>, Timestamp)> { let key_prefix = format!("{}%", key_prefix).as_bytes().to_vec(); - let query = sqlx::query(&self.sql_set.get_value_with_lease_by_prefix).bind(key_prefix); + let query = template_query(&self.sql_set.get_value_with_lease_by_prefix).bind(key_prefix); let res = executor .query(query, &self.sql_set.get_value_with_lease_by_prefix) .await?; @@ -765,7 +776,7 @@ impl MySqlElection { let prev = prev.as_bytes(); let updated = updated.as_bytes(); - let query = sqlx::query(&self.sql_set.update_value_with_lease) + let query = template_query(&self.sql_set.update_value_with_lease) .bind(updated) .bind(lease_ttl as f64) .bind(key) @@ -794,7 +805,7 @@ impl MySqlElection { ) -> Result { let key = key.as_bytes(); let lease_ttl_secs = lease_ttl_secs as f64; - let query = sqlx::query(&self.sql_set.put_value_with_lease) + let query = template_query(&self.sql_set.put_value_with_lease) .bind(key) .bind(value) .bind(lease_ttl_secs); @@ -808,7 +819,7 @@ impl MySqlElection { /// Caution: Should only delete the key if the lease is expired. async fn delete_value(&self, key: &str, executor: &mut Executor<'_>) -> Result { let key = key.as_bytes(); - let query = sqlx::query(&self.sql_set.delete_value).bind(key); + let query = template_query(&self.sql_set.delete_value).bind(key); let res = executor.execute(query, &self.sql_set.delete_value).await?; Ok(res == 1) @@ -837,7 +848,7 @@ impl MySqlElection { let mut client = self.client.lock().await; let txn = client.transaction().await?; let mut executor = Executor::Txn(txn); - let query = sqlx::query(&self.sql_set.campaign); + let query = template_query(&self.sql_set.campaign); executor.query(query, &self.sql_set.campaign).await?; // Safety: Checked if lease is not None above. self.renew_lease(executor, lease.unwrap()).await?; @@ -858,7 +869,7 @@ impl MySqlElection { let mut client = self.client.lock().await; let txn = client.transaction().await?; let mut executor = Executor::Txn(txn); - let query = sqlx::query(&self.sql_set.campaign); + let query = template_query(&self.sql_set.campaign); executor.query(query, &self.sql_set.campaign).await?; self.elected(executor, lease).await?; } @@ -869,7 +880,7 @@ impl MySqlElection { let mut client = self.client.lock().await; let txn = client.transaction().await?; let mut executor = Executor::Txn(txn); - let query = sqlx::query(&self.sql_set.campaign); + let query = template_query(&self.sql_set.campaign); executor.query(query, &self.sql_set.campaign).await?; // Safety: Checked if lease is not None above. self.renew_lease(executor, lease.unwrap()).await?; @@ -1027,7 +1038,7 @@ mod tests { async fn drop_table(client: &Mutex, table_name: &str) { let mut client = client.lock().await; let sql = format!("DROP TABLE IF EXISTS `{}`;", table_name); - client.execute(sqlx::query(&sql), &sql).await.unwrap(); + client.execute(template_query(&sql), &sql).await.unwrap(); } #[tokio::test] @@ -1052,7 +1063,7 @@ mod tests { let txn = a.transaction().await.unwrap(); let mut executor = Executor::Txn(txn); let raw_query = format!("SELECT * FROM `{}` FOR UPDATE;", table_name); - let query = sqlx::query(&raw_query); + let query = template_query(&raw_query); let _ = executor.query(query, &raw_query).await.unwrap(); } @@ -1258,7 +1269,7 @@ mod tests { let txn = client.transaction().await.unwrap(); let mut executor = Executor::Txn(txn); let raw_query = format!("SELECT * FROM `{}` FOR UPDATE;", table_name); - let query = sqlx::query(&raw_query); + let query = template_query(&raw_query); let _ = executor.query(query, &raw_query).await.unwrap(); election.elected(executor, expected_lease).await } diff --git a/src/common/meta/src/kv_backend/rds/mysql.rs b/src/common/meta/src/kv_backend/rds/mysql.rs index 6791d58f933..c933bb345f6 100644 --- a/src/common/meta/src/kv_backend/rds/mysql.rs +++ b/src/common/meta/src/kv_backend/rds/mysql.rs @@ -21,7 +21,7 @@ use regex::Regex; use snafu::{OptionExt, ResultExt}; use sqlx::mysql::MySqlRow; use sqlx::pool::Pool; -use sqlx::{MySql, MySqlPool, Row, Transaction as MySqlTransaction}; +use sqlx::{AssertSqlSafe, MySql, MySqlPool, Row, Transaction as MySqlTransaction}; use strum::AsRefStr; use crate::error::{ @@ -264,7 +264,9 @@ impl Executor for MySqlClient { } async fn query(&mut self, raw_query: &str, params: &[&Vec]) -> Result> { - let query = sqlx::query(raw_query); + // Safety: `raw_query` is generated by `MySqlTemplateSet`, and all dynamic data + // is passed via bind parameters. + let query = sqlx::query(AssertSqlSafe(raw_query)); let query = params.iter().fold(query, |query, param| query.bind(param)); let rows = query .fetch_all(&**self) @@ -274,7 +276,9 @@ impl Executor for MySqlClient { } async fn execute(&mut self, raw_query: &str, params: &[&Vec]) -> Result<()> { - let query = sqlx::query(raw_query); + // Safety: `raw_query` is generated by `MySqlTemplateSet`, and all dynamic data + // is passed via bind parameters. + let query = sqlx::query(AssertSqlSafe(raw_query)); let query = params.iter().fold(query, |query, param| query.bind(param)); query .execute(&**self) @@ -303,7 +307,9 @@ impl Executor for MySqlClient { #[async_trait::async_trait] impl Transaction<'_> for MySqlTxnClient { async fn query(&mut self, raw_query: &str, params: &[&Vec]) -> Result> { - let query = sqlx::query(raw_query); + // Safety: `raw_query` is generated by `MySqlTemplateSet`, and all dynamic data + // is passed via bind parameters. + let query = sqlx::query(AssertSqlSafe(raw_query)); let query = params.iter().fold(query, |query, param| query.bind(param)); // As said in https://docs.rs/sqlx/latest/sqlx/trait.Executor.html, we need a `&mut *transaction`. Weird. let rows = query @@ -314,7 +320,9 @@ impl Transaction<'_> for MySqlTxnClient { } async fn execute(&mut self, raw_query: &str, params: &[&Vec]) -> Result<()> { - let query = sqlx::query(raw_query); + // Safety: `raw_query` is generated by `MySqlTemplateSet`, and all dynamic data + // is passed via bind parameters. + let query = sqlx::query(AssertSqlSafe(raw_query)); let query = params.iter().fold(query, |query, param| query.bind(param)); // As said in https://docs.rs/sqlx/latest/sqlx/trait.Executor.html, we need a `&mut *transaction`. Weird. query @@ -562,12 +570,14 @@ impl MySqlStore { pool: &Pool, sql_template_set: &MySqlTemplateSet, ) -> Result> { - let row = sqlx::query(&sql_template_set.show_create_table_statement) - .fetch_optional(pool) - .await - .with_context(|_| MySqlExecutionSnafu { - sql: sql_template_set.show_create_table_statement.clone(), - })?; + let row = sqlx::query(AssertSqlSafe( + sql_template_set.show_create_table_statement.as_str(), + )) + .fetch_optional(pool) + .await + .with_context(|_| MySqlExecutionSnafu { + sql: sql_template_set.show_create_table_statement.clone(), + })?; Ok(row.map(|row| row.get(1))) } @@ -598,12 +608,14 @@ impl MySqlStore { match Self::parse_value_column_blob_type(&create_table_sql) { Some(ValueBlobType::Blob) => { - sqlx::query(&sql_template_set.alter_value_column_statement) - .execute(pool) - .await - .with_context(|_| MySqlExecutionSnafu { - sql: sql_template_set.alter_value_column_statement.clone(), - })?; + sqlx::query(AssertSqlSafe( + sql_template_set.alter_value_column_statement.as_str(), + )) + .execute(pool) + .await + .with_context(|_| MySqlExecutionSnafu { + sql: sql_template_set.alter_value_column_statement.clone(), + })?; info!("Upgraded MySQL metadata value column to MEDIUMBLOB for `{table_name}`"); } Some(ValueBlobType::MediumBlob | ValueBlobType::LongBlob) => { @@ -638,12 +650,14 @@ impl MySqlStore { // We check if greptime_metakv table exists, and we will create a new table // if it does not exist. let sql_template_set = MySqlTemplateFactory::new(table_name).build(); - sqlx::query(&sql_template_set.create_table_statement) - .execute(&pool) - .await - .with_context(|_| MySqlExecutionSnafu { - sql: sql_template_set.create_table_statement.clone(), - })?; + sqlx::query(AssertSqlSafe( + sql_template_set.create_table_statement.as_str(), + )) + .execute(&pool) + .await + .with_context(|_| MySqlExecutionSnafu { + sql: sql_template_set.create_table_statement.clone(), + })?; Self::maybe_upgrade_value_column_to_mediumblob(&pool, &sql_template_set).await?; Ok(Arc::new(MySqlStore { max_txn_ops, @@ -695,7 +709,10 @@ mod tests { async fn show_create_table(pool: &MySqlPool, table_name: &str) -> String { let sql = format!("SHOW CREATE TABLE `{table_name}`"); - let row = sqlx::query(&sql).fetch_one(pool).await.unwrap(); + let row = sqlx::query(AssertSqlSafe(sql.as_str())) + .fetch_one(pool) + .await + .unwrap(); row.get::(1) } @@ -703,18 +720,24 @@ mod tests { let sql = format!( "CREATE TABLE IF NOT EXISTS `{table_name}`(k VARBINARY(3072) PRIMARY KEY, v BLOB);" ); - sqlx::query(&sql).execute(pool).await.unwrap(); + sqlx::query(AssertSqlSafe(sql.as_str())) + .execute(pool) + .await + .unwrap(); } async fn drop_table(pool: &MySqlPool, table_name: &str) { let sql = format!("DROP TABLE IF EXISTS `{table_name}`;"); - sqlx::query(&sql).execute(pool).await.unwrap(); + sqlx::query(AssertSqlSafe(sql.as_str())) + .execute(pool) + .await + .unwrap(); } async fn build_mysql_kv_backend(table_name: &str) -> Option { let pool = mysql_pool().await?; let sql_templates = MySqlTemplateFactory::new(table_name).build(); - sqlx::query(&sql_templates.create_table_statement) + sqlx::query(AssertSqlSafe(sql_templates.create_table_statement.as_str())) .execute(&pool) .await .unwrap(); diff --git a/src/meta-srv/Cargo.toml b/src/meta-srv/Cargo.toml index 6baca0934e1..fa339d76774 100644 --- a/src/meta-srv/Cargo.toml +++ b/src/meta-srv/Cargo.toml @@ -67,6 +67,7 @@ servers.workspace = true snafu.workspace = true sqlx = { workspace = true, features = [ "mysql", + "mysql-rsa", "chrono", ], optional = true } store-api.workspace = true diff --git a/tests-fuzz/Cargo.toml b/tests-fuzz/Cargo.toml index 1189f53c42f..9e0431eedcf 100644 --- a/tests-fuzz/Cargo.toml +++ b/tests-fuzz/Cargo.toml @@ -59,6 +59,7 @@ sql = { workspace = true } sqlparser.workspace = true sqlx = { workspace = true, features = [ "mysql", + "mysql-rsa", "chrono", ] } store-api = { workspace = true } diff --git a/tests-fuzz/src/utils.rs b/tests-fuzz/src/utils.rs index 4b057d1dd65..0983d51352c 100644 --- a/tests-fuzz/src/utils.rs +++ b/tests-fuzz/src/utils.rs @@ -110,7 +110,7 @@ pub const GT_FUZZ_CLUSTER_NAME: &str = "GT_FUZZ_CLUSTER_NAME"; /// Flushes memtable to SST file. pub async fn flush_memtable(e: &Pool, table_name: &Ident) -> Result<()> { let sql = format!("admin flush_table(\"{}\")", table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(e) .await .context(error::ExecuteQuerySnafu { sql })?; @@ -122,7 +122,7 @@ pub async fn flush_memtable(e: &Pool, table_name: &Ident) -> Result<()> { /// Triggers a compaction for table pub async fn compact_table(e: &Pool, table_name: &Ident) -> Result<()> { let sql = format!("admin compact_table(\"{}\")", table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(e) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/src/utils/migration.rs b/tests-fuzz/src/utils/migration.rs index 043e2271ae9..91863171163 100644 --- a/tests-fuzz/src/utils/migration.rs +++ b/tests-fuzz/src/utils/migration.rs @@ -37,7 +37,7 @@ pub async fn migrate_region( ) -> String { let sql = format!("admin migrate_region({region_id}, {from_peer_id}, {to_peer_id}, {timeout_secs});"); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .fetch_one(e) .await .context(error::ExecuteQuerySnafu { sql }) diff --git a/tests-fuzz/src/utils/procedure.rs b/tests-fuzz/src/utils/procedure.rs index 72259272120..e89dbda183c 100644 --- a/tests-fuzz/src/utils/procedure.rs +++ b/tests-fuzz/src/utils/procedure.rs @@ -24,7 +24,7 @@ use crate::error; /// Fetches the state of a procedure. pub async fn procedure_state(e: &Pool, procedure_id: &str) -> String { let sql = format!("admin procedure_state(\"{procedure_id}\");"); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .fetch_one(e) .await .context(error::ExecuteQuerySnafu { sql }) diff --git a/tests-fuzz/src/validator/column.rs b/tests-fuzz/src/validator/column.rs index d092d892e9c..19cd2849b96 100644 --- a/tests-fuzz/src/validator/column.rs +++ b/tests-fuzz/src/validator/column.rs @@ -221,7 +221,7 @@ pub async fn valid_marker_value( let sql = format!("SELECT * FROM {table_name}"); // cache is useless and buggy anyway since alter happens all the time // TODO(discord9): invalid prepared sql after alter - let res = sqlx::query(&sql) + let res = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .persistent(false) .fetch_all(db) .await diff --git a/tests-fuzz/src/validator/row.rs b/tests-fuzz/src/validator/row.rs index 5bd83d80d6b..d3b371cb686 100644 --- a/tests-fuzz/src/validator/row.rs +++ b/tests-fuzz/src/validator/row.rs @@ -155,14 +155,16 @@ pub struct ValueCount { } pub async fn count_values(db: &MySqlPool, sql: &str) -> Result { - sqlx::query_as::<_, ValueCount>(sql) + // Safety: the SQL is built by fuzz validators from generated identifiers only. + sqlx::query_as::<_, ValueCount>(sqlx::AssertSqlSafe(sql)) .fetch_one(db) .await .context(error::ExecuteQuerySnafu { sql }) } pub async fn count_values_all(db: &MySqlPool, sql: &str) -> Result> { - sqlx::query_as::<_, ValueCount>(sql) + // Safety: the SQL is built by fuzz validators from generated identifiers only. + sqlx::query_as::<_, ValueCount>(sqlx::AssertSqlSafe(sql)) .fetch_all(db) .await .context(error::ExecuteQuerySnafu { sql }) @@ -170,7 +172,8 @@ pub async fn count_values_all(db: &MySqlPool, sql: &str) -> Result Result> { - sqlx::query(sql) + // Safety: the SQL is built by fuzz validators from generated identifiers only. + sqlx::query(sqlx::AssertSqlSafe(sql)) .fetch_all(db) .await .context(error::ExecuteQuerySnafu { sql }) diff --git a/tests-fuzz/src/validator/table.rs b/tests-fuzz/src/validator/table.rs index f271101051e..08f6e28d9b7 100644 --- a/tests-fuzz/src/validator/table.rs +++ b/tests-fuzz/src/validator/table.rs @@ -47,7 +47,8 @@ fn parse_show_create(show_create: &str) -> Result> { /// Fetches table options from the context pub async fn fetch_table_options(db: &MySqlPool, sql: &str) -> Result> { - let fetched_rows = sqlx::query(sql) + // Safety: the SQL is built by fuzz validators from generated identifiers only. + let fetched_rows = sqlx::query(sqlx::AssertSqlSafe(sql)) .fetch_all(db) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/ddl/fuzz_alter_logical_table.rs b/tests-fuzz/targets/ddl/fuzz_alter_logical_table.rs index c7542a46237..11dd7cbae4c 100644 --- a/tests-fuzz/targets/ddl/fuzz_alter_logical_table.rs +++ b/tests-fuzz/targets/ddl/fuzz_alter_logical_table.rs @@ -123,7 +123,7 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { let create_physical_table_expr = generate_create_physical_table_expr(&mut rng).unwrap(); let translator = CreateTableExprTranslator; let sql = translator.translate(&create_physical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -154,7 +154,7 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { let create_logical_table_expr = generate_create_logical_table_expr(physical_table_ctx, &mut rng).unwrap(); let sql = translator.translate(&create_logical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -178,7 +178,7 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { .unwrap(); let translator = AlterTableExprTranslator; let sql = translator.translate(&expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -213,7 +213,7 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // Clean up logical table let sql = format!("DROP TABLE {}", create_logical_table_expr.table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -224,7 +224,7 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // Clean up physical table let sql = format!("DROP TABLE {}", create_physical_table_expr.table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/ddl/fuzz_alter_table.rs b/tests-fuzz/targets/ddl/fuzz_alter_table.rs index 773e75c2b89..37002943128 100644 --- a/tests-fuzz/targets/ddl/fuzz_alter_table.rs +++ b/tests-fuzz/targets/ddl/fuzz_alter_table.rs @@ -229,14 +229,14 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { let expr = generate_create_table_expr(&mut rng).unwrap(); let translator = CreateTableExprTranslator; let sql = translator.translate(&expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; info!("Create table: {sql}, result: {result:?}"); let insert = generate_insert_table_sql(&mut rng, &expr)?; - let result = sqlx::query(&insert) + let result = sqlx::query(sqlx::AssertSqlSafe(insert.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &insert })?; @@ -248,7 +248,7 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { let expr = generate_alter_table_expr(table_ctx.clone(), &mut rng).unwrap(); let translator = AlterTableExprTranslator; let sql = translator.translate(&expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -303,7 +303,7 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // select from table to make sure the table is still ok let sql = format!("SELECT * FROM {}", table_ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .persistent(false) .execute(&ctx.greptime) .await @@ -314,7 +314,7 @@ async fn execute_alter_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // Cleans up let table_name = table_ctx.name.clone(); let sql = format!("DROP TABLE {}", table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/ddl/fuzz_create_database.rs b/tests-fuzz/targets/ddl/fuzz_create_database.rs index a6b2071cac4..60e46e1a89c 100644 --- a/tests-fuzz/targets/ddl/fuzz_create_database.rs +++ b/tests-fuzz/targets/ddl/fuzz_create_database.rs @@ -74,7 +74,7 @@ async fn execute_create_database(ctx: FuzzContext, input: FuzzInput) -> Result<( let expr = generate_expr(input)?; let translator = CreateDatabaseExprTranslator; let sql = translator.translate(&expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -82,7 +82,7 @@ async fn execute_create_database(ctx: FuzzContext, input: FuzzInput) -> Result<( // Cleans up let sql = format!("DROP DATABASE {}", expr.database_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/ddl/fuzz_create_logical_table.rs b/tests-fuzz/targets/ddl/fuzz_create_logical_table.rs index e36b5782099..1500c609f1f 100644 --- a/tests-fuzz/targets/ddl/fuzz_create_logical_table.rs +++ b/tests-fuzz/targets/ddl/fuzz_create_logical_table.rs @@ -85,7 +85,7 @@ async fn execute_create_logic_table(ctx: FuzzContext, input: FuzzInput) -> Resul .generate(&mut rng)?; let translator = CreateTableExprTranslator; let sql = translator.translate(&create_physical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -128,7 +128,7 @@ async fn execute_create_logic_table(ctx: FuzzContext, input: FuzzInput) -> Resul .unwrap() .generate(&mut rng)?; let sql = translator.translate(&create_logical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -162,7 +162,7 @@ async fn execute_create_logic_table(ctx: FuzzContext, input: FuzzInput) -> Resul // Clean up logical table let sql = format!("DROP TABLE {}", create_logical_table_expr.table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -173,7 +173,7 @@ async fn execute_create_logic_table(ctx: FuzzContext, input: FuzzInput) -> Resul // Clean up physical table let sql = format!("DROP TABLE {}", create_physical_table_expr.table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/ddl/fuzz_create_table.rs b/tests-fuzz/targets/ddl/fuzz_create_table.rs index 71171cb076d..a1597256bc5 100644 --- a/tests-fuzz/targets/ddl/fuzz_create_table.rs +++ b/tests-fuzz/targets/ddl/fuzz_create_table.rs @@ -93,7 +93,7 @@ async fn execute_create_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> let expr = generate_expr(input)?; let translator = CreateTableExprTranslator; let sql = translator.translate(&expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -110,7 +110,7 @@ async fn execute_create_table(ctx: FuzzContext, input: FuzzInput) -> Result<()> // Cleans up let sql = format!("DROP TABLE {}", expr.table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/ddl/fuzz_repartition_metric_table.rs b/tests-fuzz/targets/ddl/fuzz_repartition_metric_table.rs index 8a6bd81fa80..461bfe51daa 100644 --- a/tests-fuzz/targets/ddl/fuzz_repartition_metric_table.rs +++ b/tests-fuzz/targets/ddl/fuzz_repartition_metric_table.rs @@ -152,7 +152,7 @@ async fn create_metric_tables( let create_physical_expr = generate_create_physical_table_expr(partitions, rng)?; let translator = CreateTableExprTranslator; let create_physical_sql = translator.translate(&create_physical_expr)?; - let result = sqlx::query(&create_physical_sql) + let result = sqlx::query(sqlx::AssertSqlSafe(create_physical_sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { @@ -180,7 +180,7 @@ async fn create_metric_tables( } let create_logical_sql = translator.translate(&create_logical_expr)?; - let result = sqlx::query(&create_logical_sql) + let result = sqlx::query(sqlx::AssertSqlSafe(create_logical_sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { @@ -212,7 +212,7 @@ async fn execute_insert_with_retry(ctx: &FuzzContext, sql: &str) -> Result<()> { let mut attempt = 0; let max_attempts = 10; loop { - match sqlx::query(sql) + match sqlx::query(sqlx::AssertSqlSafe(sql)) .persistent(false) .execute(&ctx.greptime) .await @@ -408,7 +408,7 @@ async fn cleanup_tables( ) -> Result<()> { for table_ctx in logical_tables.values() { let drop_logical_sql = format!("DROP TABLE {}", table_ctx.name); - let result = sqlx::query(&drop_logical_sql) + let result = sqlx::query(sqlx::AssertSqlSafe(drop_logical_sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { @@ -418,7 +418,7 @@ async fn cleanup_tables( } let drop_physical_sql = format!("DROP TABLE {}", physical_table_ctx.name); - let result = sqlx::query(&drop_physical_sql) + let result = sqlx::query(sqlx::AssertSqlSafe(drop_physical_sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { @@ -572,7 +572,7 @@ async fn execute_repartition_metric_table(ctx: FuzzContext, input: FuzzInput) -> info!("Repartition sql: {sql}"); let started_at_ms = current_time_millis(); let now = Instant::now(); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; diff --git a/tests-fuzz/targets/ddl/fuzz_repartition_table.rs b/tests-fuzz/targets/ddl/fuzz_repartition_table.rs index 4f6a014f2e7..d1f633014b0 100644 --- a/tests-fuzz/targets/ddl/fuzz_repartition_table.rs +++ b/tests-fuzz/targets/ddl/fuzz_repartition_table.rs @@ -187,7 +187,7 @@ async fn execute_insert_with_retry(ctx: &FuzzContext, sql: &str) -> Result<()> { match ctx .greptime // unprepared query, see - .execute(sql) + .execute(sqlx::AssertSqlSafe(sql)) .await { Ok(_) => { @@ -250,7 +250,7 @@ async fn execute_repartition_table(ctx: FuzzContext, input: FuzzInput) -> Result let expr = generate_create_expr(&input, &mut rng).unwrap(); let translator = CreateTableExprTranslator; let sql = translator.translate(&expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -271,7 +271,7 @@ async fn execute_repartition_table(ctx: FuzzContext, input: FuzzInput) -> Result let translator = RepartitionExprTranslator; let sql = translator.translate(&expr)?; info!("Initial partition sql: {sql}"); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -306,7 +306,7 @@ async fn execute_repartition_table(ctx: FuzzContext, input: FuzzInput) -> Result let translator = RepartitionExprTranslator; let sql = translator.translate(&expr)?; info!("Repartition sql: {sql}"); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -378,7 +378,7 @@ async fn execute_repartition_table(ctx: FuzzContext, input: FuzzInput) -> Result // Cleans up let table_name = table_ctx.name.clone(); let sql = format!("DROP TABLE {}", table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/ddl/fuzz_repartition_table_chaos.rs b/tests-fuzz/targets/ddl/fuzz_repartition_table_chaos.rs index c1e570f6981..ed0b963908b 100644 --- a/tests-fuzz/targets/ddl/fuzz_repartition_table_chaos.rs +++ b/tests-fuzz/targets/ddl/fuzz_repartition_table_chaos.rs @@ -184,7 +184,7 @@ async fn execute_insert_with_retry(ctx: &FuzzContext, sql: &str) -> Result<()> { let mut attempt = 0; let max_attempts = 10; loop { - match ctx.greptime.execute(sql).await { + match ctx.greptime.execute(sqlx::AssertSqlSafe(sql)).await { Ok(_) => return Ok(()), Err(err) => { tokio::time::sleep(delay).await; @@ -201,7 +201,7 @@ async fn execute_insert_with_retry(ctx: &FuzzContext, sql: &str) -> Result<()> { async fn create_table(ctx: &FuzzContext, expr: &CreateTableExpr) -> Result { let translator = CreateTableExprTranslator; let sql = translator.translate(expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -333,7 +333,7 @@ fn alter_table_partitions_expr_from_table_ctx( async fn submit_repartition_procedure(ctx: &FuzzContext, expr: &RepartitionExpr) -> Result { let translator = RepartitionExprTranslator; let sql = translator.translate(expr)?; - let (procedure_id,) = sqlx::query_as::<_, (String,)>(&sql) + let (procedure_id,) = sqlx::query_as::<_, (String,)>(sqlx::AssertSqlSafe(sql.as_str())) .fetch_one(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -418,7 +418,7 @@ async fn validate_terminal_metadata( async fn drop_table(ctx: &FuzzContext, table_name: &tests_fuzz::ir::Ident) -> Result<()> { let sql = format!("DROP TABLE {}", table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; diff --git a/tests-fuzz/targets/failover/fuzz_failover_metric_regions.rs b/tests-fuzz/targets/failover/fuzz_failover_metric_regions.rs index 06623c42350..1f8cc67d775 100644 --- a/tests-fuzz/targets/failover/fuzz_failover_metric_regions.rs +++ b/tests-fuzz/targets/failover/fuzz_failover_metric_regions.rs @@ -110,7 +110,7 @@ async fn create_physical_table( let create_physical_table_expr = generate_create_physical_table_expr(rng).unwrap(); let translator = CreateTableExprTranslator; let sql = translator.translate(&create_physical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -167,7 +167,7 @@ async fn insert_values( let result = ctx .greptime // unprepared query, see - .execute(sql.as_str()) + .execute(sqlx::AssertSqlSafe(sql.as_str())) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -201,7 +201,7 @@ async fn execute_failover(ctx: FuzzContext, input: FuzzInput) -> Result<()> { continue; } let sql = translator.translate(&create_logical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -272,7 +272,7 @@ async fn execute_failover(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // Clean up for (table_ctx, _) in tables.values() { let sql = format!("DROP TABLE {}", table_ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; @@ -280,7 +280,7 @@ async fn execute_failover(ctx: FuzzContext, input: FuzzInput) -> Result<()> { } let sql = format!("DROP TABLE {}", physical_table_ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/failover/fuzz_failover_mito_regions.rs b/tests-fuzz/targets/failover/fuzz_failover_mito_regions.rs index da3b7dbcf3c..cfb2ae13420 100644 --- a/tests-fuzz/targets/failover/fuzz_failover_mito_regions.rs +++ b/tests-fuzz/targets/failover/fuzz_failover_mito_regions.rs @@ -158,7 +158,7 @@ async fn execute_create_exprs( let _permit = semaphore.acquire().await.unwrap(); let translator = CreateTableExprTranslator; let sql = translator.translate(expr).unwrap(); - sqlx::query(&sql) + sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql }) @@ -225,7 +225,7 @@ async fn execute_insert_exprs( let sql = translator.translate(&insert_expr)?; let result = greptime // unprepared query, see - .execute(sql.as_str()) + .execute(sqlx::AssertSqlSafe(sql.as_str())) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; ensure!( @@ -337,7 +337,7 @@ async fn execute_failover(ctx: FuzzContext, input: FuzzInput) -> Result<()> { for table_ctx in table_ctxs { let sql = format!("DROP TABLE {}", table_ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/fuzz_insert.rs b/tests-fuzz/targets/fuzz_insert.rs index bc690a48776..8a5192d48eb 100644 --- a/tests-fuzz/targets/fuzz_insert.rs +++ b/tests-fuzz/targets/fuzz_insert.rs @@ -130,7 +130,7 @@ async fn execute_insert(ctx: FuzzContext, input: FuzzInput) -> Result<()> { let create_expr = generate_create_expr(input, &mut rng)?; let translator = CreateTableExprTranslator; let sql = translator.translate(&create_expr)?; - let _result = sqlx::query(&sql) + let _result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -142,7 +142,7 @@ async fn execute_insert(ctx: FuzzContext, input: FuzzInput) -> Result<()> { let result = ctx .greptime // unprepared query, see - .execute(sql.as_str()) + .execute(sqlx::AssertSqlSafe(sql.as_str())) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -202,7 +202,7 @@ async fn execute_insert(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // Cleans up let sql = format!("DROP TABLE {}", create_expr.table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/fuzz_insert_logical_table.rs b/tests-fuzz/targets/fuzz_insert_logical_table.rs index 289856f771c..dcaada5edfd 100644 --- a/tests-fuzz/targets/fuzz_insert_logical_table.rs +++ b/tests-fuzz/targets/fuzz_insert_logical_table.rs @@ -141,7 +141,7 @@ async fn create_physical_table( let create_physical_table_expr = generate_create_physical_table_expr(rng).unwrap(); let translator = CreateTableExprTranslator; let sql = translator.translate(&create_physical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -211,7 +211,7 @@ async fn insert_values( let result = ctx .greptime // unprepared query, see - .execute(sql.as_str()) + .execute(sqlx::AssertSqlSafe(sql.as_str())) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -248,7 +248,7 @@ async fn execute_insert(ctx: FuzzContext, input: FuzzInput) -> Result<()> { continue; } let sql = translator.translate(&create_logical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -272,7 +272,7 @@ async fn execute_insert(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // Clean up logical table for (table_name, _) in tables { let sql = format!("DROP TABLE {}", table_name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -281,7 +281,7 @@ async fn execute_insert(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // Clean up physical table let sql = format!("DROP TABLE {}", physical_table_ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/migration/fuzz_migrate_metric_regions.rs b/tests-fuzz/targets/migration/fuzz_migrate_metric_regions.rs index d727eefa305..38bd6269966 100644 --- a/tests-fuzz/targets/migration/fuzz_migrate_metric_regions.rs +++ b/tests-fuzz/targets/migration/fuzz_migrate_metric_regions.rs @@ -109,7 +109,7 @@ async fn create_physical_table( let create_physical_table_expr = generate_create_physical_table_expr(rng).unwrap(); let translator = CreateTableExprTranslator; let sql = translator.translate(&create_physical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -166,7 +166,7 @@ async fn insert_values( let result = ctx .greptime // unprepared query, see - .execute(sql.as_str()) + .execute(sqlx::AssertSqlSafe(sql.as_str())) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -208,7 +208,7 @@ async fn create_logical_table_and_insert_values( continue; } let sql = translator.translate(&create_logical_table_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -406,7 +406,7 @@ async fn execute_migration(ctx: FuzzContext, input: FuzzInput) -> Result<()> { // Clean up for (table_ctx, _) in tables.values() { let sql = format!("DROP TABLE {}", table_ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; @@ -414,7 +414,7 @@ async fn execute_migration(ctx: FuzzContext, input: FuzzInput) -> Result<()> { } let sql = format!("DROP TABLE {}", physical_table_ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/migration/fuzz_migrate_mito_regions.rs b/tests-fuzz/targets/migration/fuzz_migrate_mito_regions.rs index 17cbfb9251d..7da074f202d 100644 --- a/tests-fuzz/targets/migration/fuzz_migrate_mito_regions.rs +++ b/tests-fuzz/targets/migration/fuzz_migrate_mito_regions.rs @@ -158,7 +158,7 @@ async fn insert_values( let result = ctx .greptime // unprepared query, see - .execute(sql.as_str()) + .execute(sqlx::AssertSqlSafe(sql.as_str())) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; ensure!( @@ -208,7 +208,11 @@ async fn validate_insert_exprs( primary_keys_column_list ); info!("Executing sql: {select_sql}"); - let fetched_rows = ctx.greptime.fetch_all(select_sql.as_str()).await.unwrap(); + let fetched_rows = ctx + .greptime + .fetch_all(sqlx::AssertSqlSafe(select_sql.as_str())) + .await + .unwrap(); let mut expected_rows = replace_default(&insert_expr.values_list, table_ctx, insert_expr); sort_by_primary_keys(&mut expected_rows, primary_keys_idx); validator::row::assert_eq::(&insert_expr.columns, &fetched_rows, &expected_rows)?; @@ -224,7 +228,11 @@ async fn validate_insert_exprs( column_list, table_ctx.name, ts_column.name, ts_value, primary_keys_column_list ); info!("Executing sql: {select_sql}"); - let fetched_rows = ctx.greptime.fetch_all(select_sql.as_str()).await.unwrap(); + let fetched_rows = ctx + .greptime + .fetch_all(sqlx::AssertSqlSafe(select_sql.as_str())) + .await + .unwrap(); let mut expected_rows = replace_default(&insert_expr.values_list, table_ctx, insert_expr); sort_by_primary_keys(&mut expected_rows, primary_keys_idx); validator::row::assert_eq::(&insert_expr.columns, &fetched_rows, &expected_rows)?; @@ -291,7 +299,7 @@ async fn execute_region_migration(ctx: FuzzContext, input: FuzzInput) -> Result< let create_expr = generate_create_expr(input, &mut rng)?; let translator = CreateTableExprTranslator; let sql = translator.translate(&create_expr)?; - let _result = sqlx::query(&sql) + let _result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -364,7 +372,7 @@ async fn execute_region_migration(ctx: FuzzContext, input: FuzzInput) -> Result< // Cleans up let sql = format!("DROP TABLE {}", table_ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-fuzz/targets/unstable/fuzz_create_table_standalone.rs b/tests-fuzz/targets/unstable/fuzz_create_table_standalone.rs index 76f978e3133..88c59f78f4c 100644 --- a/tests-fuzz/targets/unstable/fuzz_create_table_standalone.rs +++ b/tests-fuzz/targets/unstable/fuzz_create_table_standalone.rs @@ -125,7 +125,10 @@ async fn execute_unstable_create_table( let mysql_public = connect_mysql(DEFAULT_MYSQL_URL, "public").await; loop { let sql = format!("CREATE DATABASE IF NOT EXISTS {FUZZ_TESTS_DATABASE}"); - match sqlx::query(&sql).execute(&mysql_public).await { + match sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) + .execute(&mysql_public) + .await + { Ok(result) => { info!("Create database: {}, result: {result:?}", sql); break; @@ -150,7 +153,9 @@ async fn execute_unstable_create_table( let translator = CreateTableExprTranslator; let sql = translator.translate(&expr).unwrap(); - let result = sqlx::query(&sql).execute(&ctx.greptime).await; + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) + .execute(&ctx.greptime) + .await; match result { Ok(result) => { let state = *rx.borrow(); @@ -179,7 +184,10 @@ async fn execute_unstable_create_table( loop { let sql = format!("DROP DATABASE IF EXISTS {FUZZ_TESTS_DATABASE}"); - match sqlx::query(&sql).execute(&mysql_public).await { + match sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) + .execute(&mysql_public) + .await + { Ok(result) => { info!("Drop database: {}, result: {result:?}", sql); break; diff --git a/tests-fuzz/targets/wal/fuzz_remote_wal_logical_prune.rs b/tests-fuzz/targets/wal/fuzz_remote_wal_logical_prune.rs index 7545f4a4a41..a79efcce7e1 100644 --- a/tests-fuzz/targets/wal/fuzz_remote_wal_logical_prune.rs +++ b/tests-fuzz/targets/wal/fuzz_remote_wal_logical_prune.rs @@ -255,7 +255,7 @@ async fn create_tables( let create_expr = generate_create_expr(input, idx, rng)?; let translator = CreateTableExprTranslator; let sql = translator.translate(&create_expr)?; - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; @@ -288,7 +288,7 @@ async fn insert_table( let result = ctx .greptime // unprepared query, see - .execute(sql.as_str()) + .execute(sqlx::AssertSqlSafe(sql.as_str())) .await .context(error::ExecuteQuerySnafu { sql: &sql })?; ensure!( @@ -350,7 +350,11 @@ async fn validate_insert_exprs( primary_keys_column_list ); info!("Executing sql: {select_sql}"); - let fetched_rows = ctx.greptime.fetch_all(select_sql.as_str()).await.unwrap(); + let fetched_rows = ctx + .greptime + .fetch_all(sqlx::AssertSqlSafe(select_sql.as_str())) + .await + .unwrap(); let mut expected_rows = replace_default(&insert_expr.values_list, table_ctx, insert_expr); sort_by_primary_keys(&mut expected_rows, primary_keys_idx); validator::row::assert_eq::(&insert_expr.columns, &fetched_rows, &expected_rows)?; @@ -367,7 +371,11 @@ async fn validate_insert_exprs( column_list, table_ctx.name, ts_column.name, ts_value, primary_keys_column_list ); info!("Executing sql: {select_sql}"); - let fetched_rows = ctx.greptime.fetch_all(select_sql.as_str()).await.unwrap(); + let fetched_rows = ctx + .greptime + .fetch_all(sqlx::AssertSqlSafe(select_sql.as_str())) + .await + .unwrap(); let mut expected_rows = replace_default(&insert_expr.values_list, table_ctx, insert_expr); sort_by_primary_keys(&mut expected_rows, primary_keys_idx); validator::row::assert_eq::(&insert_expr.columns, &fetched_rows, &expected_rows)?; @@ -620,7 +628,7 @@ async fn execute_logical_prune_fuzz( for table in tables { let sql = format!("DROP TABLE {}", table.ctx.name); - let result = sqlx::query(&sql) + let result = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .execute(&ctx.greptime) .await .context(error::ExecuteQuerySnafu { sql })?; diff --git a/tests-integration/Cargo.toml b/tests-integration/Cargo.toml index 31a238f7bd5..4ddd9ee5a46 100644 --- a/tests-integration/Cargo.toml +++ b/tests-integration/Cargo.toml @@ -119,6 +119,7 @@ servers = { workspace = true, features = ["testing"] } similar-asserts.workspace = true sqlx = { workspace = true, features = [ "mysql", + "mysql-rsa", "postgres", "chrono", ] } diff --git a/tests-integration/tests/json2.rs b/tests-integration/tests/json2.rs index 22bcc262661..fc39a5961ff 100644 --- a/tests-integration/tests/json2.rs +++ b/tests-integration/tests/json2.rs @@ -220,7 +220,10 @@ async fn test_json2_multi_row_insert() { i, json ); - conn.execute(sql.as_str()).await.unwrap(); + // Safety: the SQL is built from test-local identifiers and payloads only. + conn.execute(sqlx::AssertSqlSafe(sql.as_str())) + .await + .unwrap(); } assert_eq!( @@ -237,9 +240,8 @@ async fn create_json2_table( table_name: &str, merge_threshold: usize, ) -> sqlx::Result<()> { - conn.execute( - format!( - r#" + let sql = format!( + r#" CREATE TABLE {table_name} ( ts TIMESTAMP TIME INDEX, host STRING PRIMARY KEY, @@ -252,10 +254,9 @@ CREATE TABLE {table_name} ( 'memtable.bulk.encode_row_threshold' = '1000000' ) "# - ) - .as_str(), - ) - .await?; + ); + // Safety: the SQL is built from test-local identifiers only. + conn.execute(sqlx::AssertSqlSafe(sql.as_str())).await?; Ok(()) } @@ -263,9 +264,8 @@ async fn create_json2_compaction_table( conn: &mut MySqlConnection, table_name: &str, ) -> sqlx::Result<()> { - conn.execute( - format!( - r#" + let sql = format!( + r#" CREATE TABLE {table_name} ( ts TIMESTAMP TIME INDEX, host STRING PRIMARY KEY, @@ -279,17 +279,15 @@ CREATE TABLE {table_name} ( 'memtable.bulk.encode_bytes_threshold' = '100000000' ) "# - ) - .as_str(), - ) - .await?; + ); + // Safety: the SQL is built from test-local identifiers only. + conn.execute(sqlx::AssertSqlSafe(sql.as_str())).await?; Ok(()) } async fn query_json2_rows(conn: &mut MySqlConnection, table_name: &str) -> sqlx::Result { - let rows = sqlx::query( - format!( - r#" + let sql = format!( + r#" SELECT host, j.payload.id::STRING AS payload_id, @@ -299,11 +297,11 @@ SELECT FROM {table_name} ORDER BY ts "# - ) - .as_str(), - ) - .fetch_all(conn) - .await?; + ); + // Safety: the SQL is built from test-local identifiers only. + let rows = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) + .fetch_all(conn) + .await?; Ok(rows .into_iter() @@ -320,9 +318,12 @@ ORDER BY ts } async fn count_table_rows(conn: &mut MySqlConnection, table_name: &str) -> sqlx::Result { - let row = sqlx::query(format!("SELECT COUNT(*) AS count FROM {table_name}").as_str()) - .fetch_one(conn) - .await?; + // Safety: the SQL is built from test-local identifiers only. + let row = sqlx::query(sqlx::AssertSqlSafe( + format!("SELECT COUNT(*) AS count FROM {table_name}").as_str(), + )) + .fetch_one(conn) + .await?; Ok(row.get("count")) } diff --git a/tests-integration/tests/sql.rs b/tests-integration/tests/sql.rs index d88fcecf1cd..4a01b0209f6 100644 --- a/tests-integration/tests/sql.rs +++ b/tests-integration/tests/sql.rs @@ -198,7 +198,8 @@ pub async fn test_mysql_auth(store_type: StorageType) { "test", "writeonly_user", |query| async move { - sqlx::query_scalar::<_, bool>(&query) + // Safety: the SQL is built from test-local identifiers only. + sqlx::query_scalar::<_, bool>(sqlx::AssertSqlSafe(query.as_str())) .fetch_one(actor_query_pool) .await .unwrap_or(false) @@ -563,7 +564,8 @@ pub async fn test_postgres_auth(store_type: StorageType) { "postgres_auth_actor", "writeonly_user", |query| async move { - sqlx::query_scalar::<_, bool>(&query) + // Safety: the SQL is built from test-local identifiers only. + sqlx::query_scalar::<_, bool>(sqlx::AssertSqlSafe(query.as_str())) .fetch_one(actor_query_pool) .await .unwrap_or(false) @@ -784,7 +786,8 @@ pub async fn test_mysql_slow_query(store_type: StorageType) { let row = tokio::time::timeout(Duration::from_secs(10), async { loop { - if let Ok(Some(row)) = sqlx::query(&query) + // Safety: the SQL is built from test-local identifiers only. + if let Ok(Some(row)) = sqlx::query(sqlx::AssertSqlSafe(query.as_str())) .bind(slow_query) .fetch_optional(&pool) .await @@ -1142,7 +1145,8 @@ pub async fn test_postgres_slow_query(store_type: StorageType) { let row = tokio::time::timeout(Duration::from_secs(10), async { loop { - if let Ok(Some(row)) = sqlx::query(&query) + // Safety: the SQL is built from test-local identifiers only. + if let Ok(Some(row)) = sqlx::query(sqlx::AssertSqlSafe(query.as_str())) .bind(slow_query) .fetch_optional(&pool) .await