Skip to main content

icydb_core/db/query/plan/
model.rs

1//! Module: query::plan::model
2//! Responsibility: pure logical query-plan data contracts.
3//! Does not own: constructors, plan assembly, or semantic interpretation.
4//! Boundary: data-only types shared by plan builder/semantics/validation layers.
5
6use crate::db::predicate::{MissingRowPolicy, PredicateExecutionModel};
7
8///
9/// QueryMode
10///
11/// Discriminates load vs delete intent at planning time.
12/// Encodes mode-specific fields so invalid states are unrepresentable.
13/// Mode checks are explicit and stable at execution time.
14///
15
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum QueryMode {
18    Load(LoadSpec),
19    Delete(DeleteSpec),
20}
21
22///
23/// LoadSpec
24///
25/// Mode-specific fields for load intents.
26/// Encodes pagination without leaking into delete intents.
27///
28#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
29pub struct LoadSpec {
30    pub limit: Option<u32>,
31    pub offset: u32,
32}
33
34///
35/// DeleteSpec
36///
37/// Mode-specific fields for delete intents.
38/// Encodes delete limits without leaking into load intents.
39///
40
41#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
42pub struct DeleteSpec {
43    pub limit: Option<u32>,
44}
45
46///
47/// OrderDirection
48/// Executor-facing ordering direction (applied after filtering).
49///
50#[derive(Clone, Copy, Debug, Eq, PartialEq)]
51pub enum OrderDirection {
52    Asc,
53    Desc,
54}
55
56///
57/// OrderSpec
58/// Executor-facing ordering specification.
59///
60
61#[derive(Clone, Debug, Eq, PartialEq)]
62pub(crate) struct OrderSpec {
63    pub(crate) fields: Vec<(String, OrderDirection)>,
64}
65
66///
67/// DeleteLimitSpec
68/// Executor-facing delete bound with no offsets.
69///
70
71#[derive(Clone, Copy, Debug, Eq, PartialEq)]
72pub(crate) struct DeleteLimitSpec {
73    pub max_rows: u32,
74}
75
76///
77/// PageSpec
78/// Executor-facing pagination specification.
79///
80
81#[derive(Clone, Debug, Eq, PartialEq)]
82pub(crate) struct PageSpec {
83    pub limit: Option<u32>,
84    pub offset: u32,
85}
86
87///
88/// AggregateKind
89///
90/// Canonical aggregate terminal taxonomy owned by query planning.
91/// All layers (query, explain, fingerprint, executor) must interpret aggregate
92/// terminal semantics through this single enum authority.
93/// Executor must derive traversal and fold direction exclusively from this enum.
94///
95
96#[allow(dead_code)]
97#[derive(Clone, Copy, Debug, Eq, PartialEq)]
98pub enum AggregateKind {
99    Count,
100    Exists,
101    Min,
102    Max,
103    First,
104    Last,
105}
106
107/// Compatibility alias for grouped planning callsites.
108pub(crate) type GroupAggregateKind = AggregateKind;
109
110///
111/// GroupAggregateSpec
112///
113/// One grouped aggregate terminal specification declared at query-plan time.
114/// `target_field` remains optional so future field-target grouped terminals can
115/// reuse this contract without mutating the wrapper shape.
116///
117
118#[derive(Clone, Debug, Eq, PartialEq)]
119pub(crate) struct GroupAggregateSpec {
120    pub(crate) kind: AggregateKind,
121    pub(crate) target_field: Option<String>,
122}
123
124///
125/// FieldSlot
126///
127/// Canonical resolved field reference used by logical planning.
128/// `index` is the stable slot in `EntityModel::fields`; `field` is retained
129/// for diagnostics and explain surfaces.
130///
131
132#[derive(Clone, Debug, Eq, PartialEq)]
133pub(crate) struct FieldSlot {
134    pub(crate) index: usize,
135    pub(crate) field: String,
136}
137
138///
139/// GroupedExecutionConfig
140///
141/// Declarative grouped-execution budget policy selected by query planning.
142/// This remains planner-owned input; executor policy bridges may still apply
143/// defaults and enforcement strategy at runtime boundaries.
144///
145
146#[derive(Clone, Copy, Debug, Eq, PartialEq)]
147pub(crate) struct GroupedExecutionConfig {
148    pub(crate) max_groups: u64,
149    pub(crate) max_group_bytes: u64,
150}
151
152///
153/// GroupSpec
154///
155/// Declarative GROUP BY stage contract attached to a validated base plan.
156/// This wrapper is intentionally semantic-only; field-slot resolution and
157/// execution-mode derivation remain executor-owned boundaries.
158///
159
160#[derive(Clone, Debug, Eq, PartialEq)]
161pub(crate) struct GroupSpec {
162    pub(crate) group_fields: Vec<FieldSlot>,
163    pub(crate) aggregates: Vec<GroupAggregateSpec>,
164    pub(crate) execution: GroupedExecutionConfig,
165}
166
167///
168/// ScalarPlan
169///
170/// Pure scalar logical query intent produced by the planner.
171///
172/// A `ScalarPlan` represents the access-independent query semantics:
173/// predicate/filter, ordering, distinct behavior, pagination/delete windows,
174/// and read-consistency mode.
175///
176/// Design notes:
177/// - Predicates are applied *after* data access
178/// - Ordering is applied after filtering
179/// - Pagination is applied after ordering (load only)
180/// - Delete limits are applied after ordering (delete only)
181/// - Missing-row policy is explicit and must not depend on access strategy
182///
183/// This struct is the logical compiler stage output and intentionally excludes
184/// access-path details.
185///
186
187#[derive(Clone, Debug, Eq, PartialEq)]
188pub(crate) struct ScalarPlan {
189    /// Load vs delete intent.
190    pub(crate) mode: QueryMode,
191
192    /// Optional residual predicate applied after access.
193    pub(crate) predicate: Option<PredicateExecutionModel>,
194
195    /// Optional ordering specification.
196    pub(crate) order: Option<OrderSpec>,
197
198    /// Optional distinct semantics over ordered rows.
199    pub(crate) distinct: bool,
200
201    /// Optional delete bound (delete intents only).
202    pub(crate) delete_limit: Option<DeleteLimitSpec>,
203
204    /// Optional pagination specification.
205    pub(crate) page: Option<PageSpec>,
206
207    /// Missing-row policy for execution.
208    pub(crate) consistency: MissingRowPolicy,
209}
210
211///
212/// GroupPlan
213///
214/// Pure grouped logical intent emitted by grouped planning.
215/// Group metadata is carried through one canonical `GroupSpec` contract.
216///
217
218#[derive(Clone, Debug, Eq, PartialEq)]
219pub(crate) struct GroupPlan {
220    pub(crate) scalar: ScalarPlan,
221    pub(crate) group: GroupSpec,
222}
223
224///
225/// LogicalPlan
226///
227/// Exclusive logical query intent emitted by planning.
228/// Scalar and grouped semantics are distinct variants by construction.
229///
230
231#[derive(Clone, Debug, Eq, PartialEq)]
232pub(crate) enum LogicalPlan {
233    Scalar(ScalarPlan),
234    Grouped(GroupPlan),
235}