gluesql_core/plan/statement/query/
offset.rs1use {
2 super::{DistinctPlan, ProjectPlan, SelectOrderByPlan, ValuesOrderByPlan, ValuesPlan},
3 crate::plan::ExprPlan,
4 serde::{Deserialize, Serialize},
5};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub struct OffsetPlan {
9 pub input: OffsetInputPlan,
10 pub count: ExprPlan,
11}
12
13impl OffsetPlan {
14 pub(super) fn project(&self) -> Option<&ProjectPlan> {
15 match &self.input {
16 OffsetInputPlan::Project(project) => Some(project),
17 OffsetInputPlan::Values(_) | OffsetInputPlan::ValuesOrderBy(_) => None,
18 OffsetInputPlan::SelectOrderBy(order_by) => Some(&order_by.input),
19 OffsetInputPlan::Distinct(distinct) => Some(distinct.project()),
20 }
21 }
22}
23
24#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
25pub enum OffsetInputPlan {
26 Project(ProjectPlan),
27 Values(ValuesPlan),
28 SelectOrderBy(SelectOrderByPlan),
29 ValuesOrderBy(ValuesOrderByPlan),
30 Distinct(DistinctPlan),
31}
32
33#[cfg(test)]
34mod tests {
35 use {
36 super::{OffsetInputPlan, OffsetPlan},
37 crate::{
38 ast::Literal,
39 plan::{ExprPlan, ValuesPlan},
40 },
41 };
42
43 fn count(value: i64) -> ExprPlan {
44 ExprPlan::Literal(Literal::Number(value.into()))
45 }
46
47 #[test]
48 fn offset_accepts_values_input() {
49 let plan = OffsetPlan {
50 input: OffsetInputPlan::Values(ValuesPlan(Vec::new())),
51 count: count(2),
52 };
53
54 assert!(matches!(
55 plan,
56 OffsetPlan {
57 input: OffsetInputPlan::Values(_),
58 count: actual,
59 } if actual == count(2)
60 ));
61 }
62}