Skip to main content

nodedb_physical/physical_plan/
cluster_array.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Control-Plane cluster array operations.
4//!
5//! These variants are emitted by the SQL converter when cluster mode is
6//! active and an array operation spans multiple vShards. They are handled
7//! exclusively by the Control-Plane dispatch loop (pgwire routing handler)
8//! which calls the `ArrayCoordinator` before anything touches the SPSC
9//! bridge. They are **never sent to the Data Plane**.
10//!
11//! The converter emits local `ArrayOp` variants in single-node mode and
12//! `ClusterArrayOp` variants in cluster mode. Downstream code that sees
13//! a `PhysicalPlan::ClusterArray(_)` knows it must call the coordinator,
14//! not the SPSC bridge.
15
16use nodedb_array::types::ArrayId;
17
18/// Cluster-mode array operations executed by the coordinator on the
19/// Control Plane.
20#[derive(
21    Debug,
22    Clone,
23    PartialEq,
24    serde::Serialize,
25    serde::Deserialize,
26    zerompk::ToMessagePack,
27    zerompk::FromMessagePack,
28)]
29pub enum ClusterArrayOp {
30    /// Fan-out a slice query across all target vShards and merge rows.
31    ///
32    /// `slice_hilbert_ranges` — pre-computed `(lo, hi)` Hilbert-prefix
33    /// ranges that determine which shards to contact. An empty vec means
34    /// "scan all shards".
35    ///
36    /// `prefix_bits` — routing granularity from the array catalog entry.
37    Slice {
38        array_id: ArrayId,
39        /// zerompk-encoded `Slice` predicate.
40        slice_msgpack: Vec<u8>,
41        /// Projected attribute indices (empty = all).
42        attr_projection: Vec<u32>,
43        /// Maximum rows returned. 0 = unlimited.
44        limit: u32,
45        /// Pre-computed Hilbert-prefix ranges for shard selection.
46        slice_hilbert_ranges: Vec<(u64, u64)>,
47        /// Routing granularity from the array catalog entry.
48        prefix_bits: u8,
49        /// Bitemporal system-time cutoff. `None` = live read.
50        system_as_of: Option<i64>,
51        /// Bitemporal valid-time point. `None` = no valid-time filter.
52        valid_at_ms: Option<i64>,
53    },
54
55    /// Fan-out an aggregate across all target vShards and reduce partials.
56    Agg {
57        array_id: ArrayId,
58        /// Index of the attribute to aggregate.
59        attr_idx: u32,
60        /// zerompk-encoded `ArrayReducer`.
61        reducer_msgpack: Vec<u8>,
62        /// Dimension index to group by (-1 = no grouping).
63        group_by_dim: i32,
64        /// Pre-computed Hilbert ranges for shard selection (empty = all).
65        slice_hilbert_ranges: Vec<(u64, u64)>,
66        /// Routing granularity.
67        prefix_bits: u8,
68        /// Bitemporal system-time cutoff. `None` = live read.
69        system_as_of: Option<i64>,
70        /// Bitemporal valid-time point. `None` = no valid-time filter.
71        valid_at_ms: Option<i64>,
72    },
73
74    /// Fan-out a cell write batch, partitioned by Hilbert tile.
75    ///
76    /// `cells` — list of `(hilbert_prefix, zerompk-encoded single-cell
77    /// bytes)`. The coordinator partitions these by prefix and sends each
78    /// shard's subset via `coord_put`.
79    Put {
80        array_id: ArrayId,
81        /// zerompk-encoded `ArrayId` bytes for the wire request.
82        array_id_msgpack: Vec<u8>,
83        /// Cells as `(hilbert_prefix, cell_msgpack)` pairs.
84        cells: Vec<(u64, Vec<u8>)>,
85        /// WAL LSN allocated by the Control Plane for this batch.
86        wal_lsn: u64,
87        /// Routing granularity.
88        prefix_bits: u8,
89    },
90
91    /// Fan-out a coord delete batch, partitioned by Hilbert tile.
92    ///
93    /// `coords` — `(hilbert_prefix, zerompk-encoded single-coord bytes)`.
94    Delete {
95        array_id: ArrayId,
96        /// zerompk-encoded `ArrayId` bytes for the wire request.
97        array_id_msgpack: Vec<u8>,
98        /// Coords as `(hilbert_prefix, coord_msgpack)` pairs.
99        coords: Vec<(u64, Vec<u8>)>,
100        /// WAL LSN.
101        wal_lsn: u64,
102        /// Routing granularity.
103        prefix_bits: u8,
104    },
105}