nodedb_sql/engine_rules/
timeseries.rs1use crate::engine_rules::*;
10use crate::error::{Result, SqlError};
11use crate::types::*;
12
13pub struct TimeseriesRules;
14
15impl EngineRules for TimeseriesRules {
16 fn plan_insert(&self, p: InsertParams) -> Result<Vec<SqlPlan>> {
17 Ok(vec![SqlPlan::TimeseriesIngest {
19 collection: p.collection,
20 rows: p.rows,
21 }])
22 }
23
24 fn plan_upsert(&self, _p: UpsertParams) -> Result<Vec<SqlPlan>> {
25 Err(SqlError::Unsupported {
26 detail: "UPSERT is not supported on timeseries collections (append-only)".into(),
27 })
28 }
29
30 fn plan_scan(&self, p: ScanParams) -> Result<SqlPlan> {
31 if p.temporal.is_temporal() && !p.bitemporal {
32 return Err(SqlError::Unsupported {
33 detail: format!(
34 "FOR SYSTEM_TIME / FOR VALID_TIME requires a bitemporal \
35 timeseries collection; '{}' was not created WITH bitemporal = true",
36 p.collection
37 ),
38 });
39 }
40 let time_range = default_time_range();
42 Ok(SqlPlan::TimeseriesScan {
43 collection: p.collection,
44 time_range,
45 bucket_interval_ms: 0,
46 group_by: Vec::new(),
47 aggregates: Vec::new(),
48 filters: p.filters,
49 projection: p.projection,
50 gap_fill: String::new(),
51 limit: p.limit.unwrap_or(10000),
52 tiered: false,
53 temporal: p.temporal,
54 })
55 }
56
57 fn plan_point_get(&self, _p: PointGetParams) -> Result<SqlPlan> {
58 Err(SqlError::Unsupported {
59 detail: "point lookups are not supported on timeseries collections; \
60 use SELECT with a time range filter instead"
61 .into(),
62 })
63 }
64
65 fn plan_update(&self, _p: UpdateParams) -> Result<Vec<SqlPlan>> {
66 Err(SqlError::Unsupported {
67 detail: "UPDATE is not supported on timeseries collections; \
68 timeseries data is append-only"
69 .into(),
70 })
71 }
72
73 fn plan_update_from(&self, p: UpdateFromParams) -> Result<Vec<SqlPlan>> {
74 Err(SqlError::Unsupported {
75 detail: format!(
76 "UPDATE ... FROM is not supported on timeseries collection '{}'; \
77 timeseries data is append-only",
78 p.collection
79 ),
80 })
81 }
82
83 fn plan_delete(&self, p: DeleteParams) -> Result<Vec<SqlPlan>> {
84 Ok(vec![SqlPlan::Delete {
86 collection: p.collection,
87 engine: EngineType::Timeseries,
88 filters: p.filters,
89 target_keys: p.target_keys,
90 }])
91 }
92
93 fn plan_aggregate(&self, p: AggregateParams) -> Result<SqlPlan> {
94 if p.temporal.is_temporal() && !p.bitemporal {
95 return Err(SqlError::Unsupported {
96 detail: format!(
97 "FOR SYSTEM_TIME / FOR VALID_TIME requires a bitemporal \
98 timeseries collection; '{}' was not created WITH bitemporal = true",
99 p.collection
100 ),
101 });
102 }
103 Ok(SqlPlan::TimeseriesScan {
104 collection: p.collection,
105 time_range: default_time_range(),
106 bucket_interval_ms: p.bucket_interval_ms.unwrap_or(0),
107 group_by: p.group_columns,
108 aggregates: p.aggregates,
109 filters: p.filters,
110 projection: Vec::new(),
111 gap_fill: String::new(),
112 limit: p.limit,
113 tiered: p.has_auto_tier,
114 temporal: p.temporal,
115 })
116 }
117
118 fn plan_merge(&self, p: MergeParams) -> Result<Vec<SqlPlan>> {
119 Err(SqlError::Unsupported {
120 detail: format!(
121 "MERGE is not supported on timeseries collection '{}'",
122 p.collection
123 ),
124 })
125 }
126}
127
128fn default_time_range() -> (i64, i64) {
134 (i64::MIN, i64::MAX)
135}