Skip to main content

pgevolve_core/diff/
sequence_op.rs

1//! `SequenceOp` — per-sequence field updates.
2//!
3//! Carried inside [`Change::AlterSequence`](super::change::Change::AlterSequence).
4//!
5//! Note: `START` is intentionally not represented here. Postgres requires
6//! `RESTART`, which has different semantics (it touches the live counter, not
7//! the declared starting point), so v0.1 emits a recreate when `start` differs.
8
9use serde::{Deserialize, Serialize};
10
11use crate::ir::column_type::ColumnType;
12use crate::ir::sequence::SequenceOwner;
13
14use super::destructiveness::Destructiveness;
15
16/// One sequence-field op paired with its destructiveness classification.
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18pub struct SequenceOpEntry {
19    /// The sequence operation.
20    pub op: SequenceOp,
21    /// Risk classification.
22    pub destructiveness: Destructiveness,
23}
24
25/// One field-level update on a sequence.
26#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
27#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
28pub enum SequenceOp {
29    /// Set `INCREMENT BY`.
30    SetIncrement(i64),
31    /// Set `MINVALUE` (`None` = NO MINVALUE).
32    SetMinValue(Option<i64>),
33    /// Set `MAXVALUE` (`None` = NO MAXVALUE).
34    SetMaxValue(Option<i64>),
35    /// Set `CACHE`.
36    SetCache(i64),
37    /// Set `CYCLE` / `NO CYCLE`.
38    SetCycle(bool),
39    /// Set the sequence's data type.
40    SetDataType(ColumnType),
41    /// Set or clear `OWNED BY`.
42    SetOwnedBy(Option<SequenceOwner>),
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn set_increment_serde_round_trip() {
51        let entry = SequenceOpEntry {
52            op: SequenceOp::SetIncrement(2),
53            destructiveness: Destructiveness::Safe,
54        };
55        let json = serde_json::to_string(&entry).unwrap();
56        let back: SequenceOpEntry = serde_json::from_str(&json).unwrap();
57        assert_eq!(entry, back);
58    }
59
60    #[test]
61    fn set_data_type_serde_round_trip() {
62        let entry = SequenceOpEntry {
63            op: SequenceOp::SetDataType(ColumnType::BigInt),
64            destructiveness: Destructiveness::RequiresApproval {
65                reason: "may overflow current value".into(),
66            },
67        };
68        let json = serde_json::to_string(&entry).unwrap();
69        let back: SequenceOpEntry = serde_json::from_str(&json).unwrap();
70        assert_eq!(entry, back);
71    }
72
73    #[test]
74    fn set_owned_by_none_serde_round_trip() {
75        let entry = SequenceOpEntry {
76            op: SequenceOp::SetOwnedBy(None),
77            destructiveness: Destructiveness::Safe,
78        };
79        let json = serde_json::to_string(&entry).unwrap();
80        let back: SequenceOpEntry = serde_json::from_str(&json).unwrap();
81        assert_eq!(entry, back);
82    }
83}