Skip to main content

nodedb_sql/engine_rules/
document_strict.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Engine rules for strict document collections.
4
5use crate::engine_rules::*;
6use crate::error::{Result, SqlError};
7use crate::types::*;
8
9pub struct StrictRules;
10
11impl EngineRules for StrictRules {
12    fn plan_insert(&self, p: InsertParams) -> Result<Vec<SqlPlan>> {
13        Ok(vec![SqlPlan::Insert {
14            collection: p.collection,
15            engine: EngineType::DocumentStrict,
16            rows: p.rows,
17            column_defaults: p.column_defaults,
18            if_absent: p.if_absent,
19        }])
20    }
21
22    fn plan_upsert(&self, p: UpsertParams) -> Result<Vec<SqlPlan>> {
23        Ok(vec![SqlPlan::Upsert {
24            collection: p.collection,
25            engine: EngineType::DocumentStrict,
26            rows: p.rows,
27            column_defaults: p.column_defaults,
28            on_conflict_updates: p.on_conflict_updates,
29        }])
30    }
31
32    fn plan_scan(&self, p: ScanParams) -> Result<SqlPlan> {
33        if p.temporal.is_temporal() && !p.bitemporal {
34            return Err(SqlError::Unsupported {
35                detail: format!(
36                    "FOR SYSTEM_TIME / FOR VALID_TIME requires a bitemporal \
37                     collection; '{}' was not created WITH bitemporal = true",
38                    p.collection
39                ),
40            });
41        }
42        if let Some(plan) =
43            crate::engine_rules::try_document_index_lookup(&p, EngineType::DocumentStrict)
44        {
45            return Ok(plan);
46        }
47        Ok(SqlPlan::Scan {
48            collection: p.collection,
49            alias: p.alias,
50            engine: EngineType::DocumentStrict,
51            filters: p.filters,
52            projection: p.projection,
53            sort_keys: p.sort_keys,
54            limit: p.limit,
55            offset: p.offset,
56            distinct: p.distinct,
57            window_functions: p.window_functions,
58            temporal: p.temporal,
59        })
60    }
61
62    fn plan_point_get(&self, p: PointGetParams) -> Result<SqlPlan> {
63        Ok(SqlPlan::PointGet {
64            collection: p.collection,
65            alias: p.alias,
66            engine: EngineType::DocumentStrict,
67            key_column: p.key_column,
68            key_value: p.key_value,
69        })
70    }
71
72    fn plan_update(&self, p: UpdateParams) -> Result<Vec<SqlPlan>> {
73        Ok(vec![SqlPlan::Update {
74            collection: p.collection,
75            engine: EngineType::DocumentStrict,
76            assignments: p.assignments,
77            filters: p.filters,
78            target_keys: p.target_keys,
79            returning: p.returning,
80        }])
81    }
82
83    fn plan_update_from(&self, p: UpdateFromParams) -> Result<Vec<SqlPlan>> {
84        Ok(vec![SqlPlan::UpdateFrom {
85            collection: p.collection,
86            engine: EngineType::DocumentStrict,
87            source: p.source,
88            target_join_col: p.target_join_col,
89            source_join_col: p.source_join_col,
90            assignments: p.assignments,
91            target_filters: p.target_filters,
92            returning: p.returning,
93        }])
94    }
95
96    fn plan_delete(&self, p: DeleteParams) -> Result<Vec<SqlPlan>> {
97        Ok(vec![SqlPlan::Delete {
98            collection: p.collection,
99            engine: EngineType::DocumentStrict,
100            filters: p.filters,
101            target_keys: p.target_keys,
102        }])
103    }
104
105    fn plan_merge(&self, p: MergeParams) -> Result<Vec<SqlPlan>> {
106        Ok(vec![SqlPlan::Merge {
107            target: p.collection,
108            engine: EngineType::DocumentStrict,
109            source: p.source,
110            target_join_col: p.target_join_col,
111            source_join_col: p.source_join_col,
112            source_alias: p.source_alias,
113            clauses: p.clauses,
114            returning: p.returning,
115        }])
116    }
117
118    fn plan_aggregate(&self, p: AggregateParams) -> Result<SqlPlan> {
119        let base_scan = SqlPlan::Scan {
120            collection: p.collection,
121            alias: p.alias,
122            engine: EngineType::DocumentStrict,
123            filters: p.filters,
124            projection: Vec::new(),
125            sort_keys: Vec::new(),
126            limit: None,
127            offset: 0,
128            distinct: false,
129            window_functions: Vec::new(),
130            temporal: p.temporal,
131        };
132        Ok(SqlPlan::Aggregate {
133            input: Box::new(base_scan),
134            group_by: p.group_by,
135            aggregates: p.aggregates,
136            having: p.having,
137            limit: p.limit,
138            grouping_sets: None,
139            sort_keys: Vec::new(),
140        })
141    }
142}