1#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
5pub struct PlanOptions {
6 pub string_policy: StringPolicy,
8 pub binary_policy: BinaryPolicy,
10 pub timezone_policy: TimezonePolicy,
12 pub timestamp_policy: TimestampPolicy,
14 pub nanosecond_policy: NanosecondPolicy,
16 pub uint64_policy: UInt64Policy,
18 pub decimal_policy: DecimalPolicy,
20 pub decimal256_policy: Decimal256Policy,
22 pub float_policy: FloatPolicy,
24 pub date64_policy: Date64Policy,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
30pub enum StringPolicy {
31 #[default]
33 NVarCharMax,
34 NVarChar(usize),
36 ObservedNVarChar,
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
42pub enum BinaryPolicy {
43 #[default]
45 VarBinaryMax,
46 VarBinary(usize),
48 ObservedVarBinary,
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
54pub enum TimestampPolicy {
55 DateTime2 {
57 precision: u8,
59 },
60 DateTime,
62}
63
64impl Default for TimestampPolicy {
65 fn default() -> Self {
66 Self::DateTime2 { precision: 7 }
67 }
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
72pub enum TimezonePolicy {
73 #[default]
75 Reject,
76 DateTimeOffset,
78 NormalizeUtcDateTime2,
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
84pub enum NanosecondPolicy {
85 #[default]
87 RejectNon100ns,
88 RoundTo100ns,
90 TruncateTo100ns,
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
96pub enum UInt64Policy {
97 #[default]
99 Reject,
100 Decimal20_0,
102 CheckedBigInt,
104}
105
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
108pub enum DecimalPolicy {
109 #[default]
111 RejectNegativeScale,
112 NormalizeNegativeScale,
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
118pub enum Decimal256Policy {
119 #[default]
121 CheckedDowncast,
122 Reject,
124}
125
126#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
128pub enum FloatPolicy {
129 #[default]
131 RejectNonFinite,
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
136pub enum Date64Policy {
137 #[default]
139 RejectNonMidnight,
140 TimestampDateTime2,
142}
143
144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
146pub enum SchemaCheck {
147 #[default]
149 Strict,
150}
151
152#[cfg(test)]
153mod tests {
154 use super::{
155 BinaryPolicy, Date64Policy, Decimal256Policy, DecimalPolicy, FloatPolicy, NanosecondPolicy,
156 PlanOptions, SchemaCheck, StringPolicy, TimestampPolicy, TimezonePolicy, UInt64Policy,
157 };
158
159 #[test]
160 fn defaults_match_v0_1_policy_decisions() {
161 let options = PlanOptions::default();
162
163 assert_eq!(options.string_policy, StringPolicy::NVarCharMax);
164 assert_eq!(options.binary_policy, BinaryPolicy::VarBinaryMax);
165 assert_eq!(options.timezone_policy, TimezonePolicy::Reject);
166 assert_eq!(
167 options.timestamp_policy,
168 TimestampPolicy::DateTime2 { precision: 7 }
169 );
170 assert_eq!(options.nanosecond_policy, NanosecondPolicy::RejectNon100ns);
171 assert_eq!(options.uint64_policy, UInt64Policy::Reject);
172 assert_eq!(options.decimal_policy, DecimalPolicy::RejectNegativeScale);
173 assert_eq!(options.decimal256_policy, Decimal256Policy::CheckedDowncast);
174 assert_eq!(options.float_policy, FloatPolicy::RejectNonFinite);
175 assert_eq!(options.date64_policy, Date64Policy::RejectNonMidnight);
176 }
177
178 #[test]
179 fn individual_policy_defaults_match_plan_options() {
180 assert_eq!(StringPolicy::default(), StringPolicy::NVarCharMax);
181 assert_eq!(BinaryPolicy::default(), BinaryPolicy::VarBinaryMax);
182 assert_eq!(TimezonePolicy::default(), TimezonePolicy::Reject);
183 assert_eq!(
184 TimestampPolicy::default(),
185 TimestampPolicy::DateTime2 { precision: 7 }
186 );
187 assert_eq!(
188 NanosecondPolicy::default(),
189 NanosecondPolicy::RejectNon100ns
190 );
191 assert_eq!(UInt64Policy::default(), UInt64Policy::Reject);
192 assert_eq!(DecimalPolicy::default(), DecimalPolicy::RejectNegativeScale);
193 assert_eq!(
194 Decimal256Policy::default(),
195 Decimal256Policy::CheckedDowncast
196 );
197 assert_eq!(FloatPolicy::default(), FloatPolicy::RejectNonFinite);
198 assert_eq!(Date64Policy::default(), Date64Policy::RejectNonMidnight);
199 assert_eq!(SchemaCheck::default(), SchemaCheck::Strict);
200 }
201
202 #[test]
203 fn supports_explicit_non_default_policy_overrides() {
204 let options = PlanOptions {
205 string_policy: StringPolicy::NVarChar(128),
206 binary_policy: BinaryPolicy::VarBinary(256),
207 timezone_policy: TimezonePolicy::DateTimeOffset,
208 timestamp_policy: TimestampPolicy::DateTime,
209 nanosecond_policy: NanosecondPolicy::RoundTo100ns,
210 uint64_policy: UInt64Policy::Decimal20_0,
211 decimal_policy: DecimalPolicy::NormalizeNegativeScale,
212 decimal256_policy: Decimal256Policy::Reject,
213 float_policy: FloatPolicy::RejectNonFinite,
214 date64_policy: Date64Policy::TimestampDateTime2,
215 };
216
217 assert_eq!(options.string_policy, StringPolicy::NVarChar(128));
218 assert_eq!(options.binary_policy, BinaryPolicy::VarBinary(256));
219 assert_eq!(options.timezone_policy, TimezonePolicy::DateTimeOffset);
220 assert_eq!(options.timestamp_policy, TimestampPolicy::DateTime);
221 assert_eq!(options.nanosecond_policy, NanosecondPolicy::RoundTo100ns);
222 assert_eq!(options.uint64_policy, UInt64Policy::Decimal20_0);
223 assert_eq!(
224 options.decimal_policy,
225 DecimalPolicy::NormalizeNegativeScale
226 );
227 assert_eq!(options.decimal256_policy, Decimal256Policy::Reject);
228 assert_eq!(options.float_policy, FloatPolicy::RejectNonFinite);
229 assert_eq!(options.date64_policy, Date64Policy::TimestampDateTime2);
230 }
231}