diff --git a/Cargo.lock b/Cargo.lock index 20fc6eb1393..a5df32ae2ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2253,6 +2253,15 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.17", +] + [[package]] name = "codespan-reporting" version = "0.12.0" @@ -5020,6 +5029,18 @@ dependencies = [ "serde", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "ena" version = "0.14.3" @@ -11056,6 +11077,18 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + [[package]] name = "postgres-protocol" version = "0.6.12" @@ -11373,10 +11406,12 @@ dependencies = [ "greptime-proto", "lazy_static", "mito-codec", + "postcard", "prometheus 0.14.0", "prost 0.14.1", "rand 0.9.4", "regex", + "serde", "snafu 0.8.6", "store-api", "table", diff --git a/Cargo.toml b/Cargo.toml index c870b88c0b6..e591a76feda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -211,6 +211,7 @@ parquet-variant-json = "=59.2.0" paste = "1.0" percent-encoding = "2.3" pin-project = "1.0" +postcard = { version = "1.1.3", default-features = false, features = ["alloc", "use-std"] } pretty_assertions = "1.4.0" prometheus = { version = "0.14", features = ["process"] } promql-parser = { version = "0.10.0", features = ["ser"] } diff --git a/src/datatypes/Cargo.toml b/src/datatypes/Cargo.toml index 555aac1813e..4dfc2e6628a 100644 --- a/src/datatypes/Cargo.toml +++ b/src/datatypes/Cargo.toml @@ -33,7 +33,7 @@ parquet-variant-compute.workspace = true parquet-variant-json.workspace = true paste.workspace = true regex.workspace = true -serde.workspace = true +serde = { workspace = true, features = ["rc"] } serde_json.workspace = true snafu.workspace = true sqlparser.workspace = true diff --git a/src/datatypes/src/series.rs b/src/datatypes/src/series.rs index 252b664708d..81d0dd4750b 100644 --- a/src/datatypes/src/series.rs +++ b/src/datatypes/src/series.rs @@ -36,7 +36,7 @@ use crate::error::{InvalidSeriesSnafu, Result}; /// evaluated streams use current name/label identity, not storage primary keys or object address/hash. /// This ordering /// is not a query-global ordering, partition-ownership rule, or finality guarantee. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)] pub enum SeriesOrdering { /// Series chunks may interleave; positions within each series remain strictly increasing. Interleaved, @@ -47,7 +47,7 @@ pub enum SeriesOrdering { } /// A label with shared UTF-8 name and value strings. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)] pub struct Label { /// Label name. pub name: Arc, @@ -61,12 +61,30 @@ pub struct Label { /// The metric name is only the `__name__` value (see [`Self::name`]); this type is /// the whole label set a PromQL series shows. It is neither a canonical /// matching/grouping identity nor a storage identity (read key / primary key). -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct SeriesLabels { name: Option>, tags: Arc<[Label]>, } +impl serde::Serialize for SeriesLabels { + fn serialize( + &self, + serializer: S, + ) -> std::result::Result { + (&self.name, self.tags.as_ref()).serialize(serializer) + } +} +impl<'de> serde::Deserialize<'de> for SeriesLabels { + fn deserialize>( + deserializer: D, + ) -> std::result::Result { + let (name, tags): (Option>, Vec