uqa_sql/schema/sequences/
definition.rs1use crate::ast::{AlterSequence, CreateSequence, SequenceBound, SequenceDataType};
9use crate::SQLError;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct SequenceDefinition {
14 pub start: i64,
15 pub increment: i64,
16 pub data_type: SequenceDataType,
17 pub min_value: i64,
18 pub max_value: i64,
19 pub cycle: bool,
20 pub cache_size: i64,
21}
22
23impl SequenceDefinition {
24 #[must_use]
25 pub fn initial(start: i64, increment: i64, data_type: SequenceDataType) -> Self {
26 let (type_min, type_max) = data_type.bounds();
27 Self {
28 start,
29 increment,
30 data_type,
31 min_value: if increment > 0 { 1 } else { type_min },
32 max_value: if increment > 0 { type_max } else { -1 },
33 cycle: false,
34 cache_size: 1,
35 }
36 }
37
38 #[must_use]
39 pub fn from_create(sequence: &CreateSequence) -> Self {
40 let mut definition = Self::initial(sequence.start, sequence.increment, sequence.data_type);
41 definition.min_value = sequence.min_value.unwrap_or(definition.min_value);
42 definition.max_value = sequence.max_value.unwrap_or(definition.max_value);
43 definition.cycle = sequence.cycle;
44 definition.cache_size = sequence.cache_size;
45 definition
46 }
47}
48
49#[must_use]
50pub fn altered_sequence_definition(
51 mut state: SequenceDefinition,
52 alter: &AlterSequence,
53) -> SequenceDefinition {
54 if let Some(data_type) = alter.data_type {
55 let (old_type_min, old_type_max) = state.data_type.bounds();
56 let (new_type_min, new_type_max) = data_type.bounds();
57 if state.min_value == old_type_min {
58 state.min_value = new_type_min;
59 }
60 if state.max_value == old_type_max {
61 state.max_value = new_type_max;
62 }
63 state.data_type = data_type;
64 }
65 if let Some(increment) = alter.increment {
66 state.increment = increment;
67 }
68 let (type_min, type_max) = state.data_type.bounds();
69 match alter.min_value {
70 SequenceBound::Unchanged => {}
71 SequenceBound::Default => {
72 state.min_value = if state.increment > 0 { 1 } else { type_min };
73 }
74 SequenceBound::Value(value) => state.min_value = value,
75 }
76 match alter.max_value {
77 SequenceBound::Unchanged => {}
78 SequenceBound::Default => {
79 state.max_value = if state.increment > 0 { type_max } else { -1 };
80 }
81 SequenceBound::Value(value) => state.max_value = value,
82 }
83 if let Some(start_val) = alter.start {
84 state.start = start_val;
85 }
86 if let Some(cycle) = alter.cycle {
87 state.cycle = cycle;
88 }
89 if let Some(cache_size) = alter.cache_size {
90 state.cache_size = cache_size;
91 }
92 state
93}
94
95pub fn validate_sequence_definition(
96 state: &SequenceDefinition,
97 current: Option<i64>,
98) -> Result<(), SQLError> {
99 let validate_current = current.is_some();
100 let current = current.unwrap_or_default();
101 let invalid = |message| SQLError::Routine {
102 sqlstate: "22023".into(),
103 message,
104 };
105 if state.increment == 0 {
106 return Err(invalid("INCREMENT must not be zero".into()));
107 }
108 if state.cache_size <= 0 {
109 return Err(invalid(format!(
110 "CACHE ({}) must be greater than zero",
111 state.cache_size
112 )));
113 }
114 let (type_min, type_max) = state.data_type.bounds();
115 if !(type_min..=type_max).contains(&state.max_value) {
116 return Err(invalid(format!(
117 "MAXVALUE ({}) is out of range for sequence data type {}",
118 state.max_value,
119 state.data_type.sql_name()
120 )));
121 }
122 if !(type_min..=type_max).contains(&state.min_value) {
123 return Err(invalid(format!(
124 "MINVALUE ({}) is out of range for sequence data type {}",
125 state.min_value,
126 state.data_type.sql_name()
127 )));
128 }
129 if state.min_value >= state.max_value {
130 return Err(invalid(format!(
131 "MINVALUE ({}) must be less than MAXVALUE ({})",
132 state.min_value, state.max_value
133 )));
134 }
135 if state.start < state.min_value {
136 return Err(invalid(format!(
137 "START value ({}) cannot be less than MINVALUE ({})",
138 state.start, state.min_value
139 )));
140 }
141 if state.start > state.max_value {
142 return Err(invalid(format!(
143 "START value ({}) cannot be greater than MAXVALUE ({})",
144 state.start, state.max_value
145 )));
146 }
147 if validate_current && current < state.min_value {
148 return Err(invalid(format!(
149 "RESTART value ({}) cannot be less than MINVALUE ({})",
150 current, state.min_value
151 )));
152 }
153 if validate_current && current > state.max_value {
154 return Err(invalid(format!(
155 "RESTART value ({}) cannot be greater than MAXVALUE ({})",
156 current, state.max_value
157 )));
158 }
159 Ok(())
160}