Skip to main content

nodedb_sql/engine_rules/
spatial.rs

1//! Engine rules for spatial columnar collections.
2
3use crate::engine_rules::*;
4use crate::error::{Result, SqlError};
5use crate::types::*;
6
7pub struct SpatialRules;
8
9impl EngineRules for SpatialRules {
10    fn plan_insert(&self, p: InsertParams) -> Result<Vec<SqlPlan>> {
11        Ok(vec![SqlPlan::Insert {
12            collection: p.collection,
13            engine: EngineType::Spatial,
14            rows: p.rows,
15            column_defaults: p.column_defaults,
16        }])
17    }
18
19    fn plan_upsert(&self, _p: UpsertParams) -> Result<Vec<SqlPlan>> {
20        Err(SqlError::Unsupported {
21            detail: "UPSERT is not supported on spatial collections".into(),
22        })
23    }
24
25    fn plan_scan(&self, p: ScanParams) -> Result<SqlPlan> {
26        // Plain scan on spatial collection — no spatial predicate involved.
27        // Spatial predicates (ST_DWithin, ST_Contains, etc.) are detected
28        // in select.rs and routed to SpatialScan directly, bypassing this.
29        Ok(SqlPlan::Scan {
30            collection: p.collection,
31            alias: p.alias,
32            engine: EngineType::Spatial,
33            filters: p.filters,
34            projection: p.projection,
35            sort_keys: p.sort_keys,
36            limit: p.limit,
37            offset: p.offset,
38            distinct: p.distinct,
39            window_functions: p.window_functions,
40        })
41    }
42
43    fn plan_point_get(&self, p: PointGetParams) -> Result<SqlPlan> {
44        Ok(SqlPlan::PointGet {
45            collection: p.collection,
46            alias: p.alias,
47            engine: EngineType::Spatial,
48            key_column: p.key_column,
49            key_value: p.key_value,
50        })
51    }
52
53    fn plan_update(&self, p: UpdateParams) -> Result<Vec<SqlPlan>> {
54        Ok(vec![SqlPlan::Update {
55            collection: p.collection,
56            engine: EngineType::Spatial,
57            assignments: p.assignments,
58            filters: p.filters,
59            target_keys: p.target_keys,
60            returning: p.returning,
61        }])
62    }
63
64    fn plan_delete(&self, p: DeleteParams) -> Result<Vec<SqlPlan>> {
65        Ok(vec![SqlPlan::Delete {
66            collection: p.collection,
67            engine: EngineType::Spatial,
68            filters: p.filters,
69            target_keys: p.target_keys,
70        }])
71    }
72
73    fn plan_aggregate(&self, p: AggregateParams) -> Result<SqlPlan> {
74        let base_scan = SqlPlan::Scan {
75            collection: p.collection,
76            alias: p.alias,
77            engine: EngineType::Spatial,
78            filters: p.filters,
79            projection: Vec::new(),
80            sort_keys: Vec::new(),
81            limit: None,
82            offset: 0,
83            distinct: false,
84            window_functions: Vec::new(),
85        };
86        Ok(SqlPlan::Aggregate {
87            input: Box::new(base_scan),
88            group_by: p.group_by,
89            aggregates: p.aggregates,
90            having: p.having,
91            limit: p.limit,
92        })
93    }
94}