nodedb_physical/physical_plan/spatial.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! Spatial engine operations dispatched to the Data Plane.
4
5use nodedb_types::{QualifiedCollection, Surrogate, SurrogateBitmap, geometry::Geometry};
6
7/// Spatial predicate type for R-tree index scan.
8#[derive(
9 Debug,
10 Clone,
11 Copy,
12 PartialEq,
13 Eq,
14 serde::Serialize,
15 serde::Deserialize,
16 zerompk::ToMessagePack,
17 zerompk::FromMessagePack,
18)]
19#[msgpack(c_enum)]
20pub enum SpatialPredicate {
21 /// ST_DWithin: geometry within distance (meters).
22 DWithin,
23 /// ST_Contains: query geometry contains document geometry.
24 Contains,
25 /// ST_Intersects: query geometry intersects document geometry.
26 Intersects,
27 /// ST_Within: document geometry is within query geometry.
28 Within,
29}
30
31/// Spatial engine physical operations.
32#[derive(
33 Debug,
34 Clone,
35 PartialEq,
36 serde::Serialize,
37 serde::Deserialize,
38 zerompk::ToMessagePack,
39 zerompk::FromMessagePack,
40)]
41pub enum SpatialOp {
42 /// Insert a geometry into the R-tree index for a document.
43 ///
44 /// Used by the sync inbound path to replicate spatial data from Lite to Origin.
45 /// The R-tree and sparse document store are keyed by the hex-encoded
46 /// `surrogate` (matching direct `INSERT INTO` semantics), so the
47 /// cross-engine prefilter bitmap intersect works without translation.
48 Insert {
49 collection: QualifiedCollection,
50 field: String,
51 /// Stable global surrogate for the row, assigned on the Control Plane.
52 surrogate: Surrogate,
53 /// Typed geometry, deserialised on the Control Plane from wire bytes.
54 geometry: Geometry,
55 /// Sync provenance: identifies the originating peer and sequence for idempotency.
56 #[serde(default)]
57 provenance: Option<nodedb_types::sync::wire::SyncProvenance>,
58 },
59 /// Remove a document's geometry from the R-tree index.
60 ///
61 /// Used by the sync inbound path. Keyed by the same hex-encoded surrogate
62 /// used at insert time.
63 Delete {
64 collection: QualifiedCollection,
65 field: String,
66 /// Stable global surrogate for the row. `None` when the key's home
67 /// binds none: the delete removes nothing and still commits its sync
68 /// provenance.
69 surrogate: Option<Surrogate>,
70 /// Sync provenance: identifies the originating peer and sequence for idempotency.
71 #[serde(default)]
72 provenance: Option<nodedb_types::sync::wire::SyncProvenance>,
73 },
74 /// R-tree index scan with spatial predicate and exact refinement.
75 Scan {
76 collection: QualifiedCollection,
77 field: String,
78 predicate: SpatialPredicate,
79 /// Typed query geometry, parsed and validated on the Control Plane.
80 query_geometry: Geometry,
81 /// Distance threshold in meters (for ST_DWithin). 0 for non-distance predicates.
82 distance_meters: f64,
83 /// Additional attribute filters applied after spatial candidates.
84 attribute_filters: Vec<u8>,
85 limit: usize,
86 projection: Vec<String>,
87 /// RLS post-candidate filters.
88 rls_filters: Vec<u8>,
89 /// Optional surrogate prefilter injected by a cross-engine sub-plan.
90 /// When present, only candidates whose surrogate is in this bitmap
91 /// are returned. `None` = no prefilter; all R-tree candidates pass.
92 prefilter: Option<SurrogateBitmap>,
93 },
94}