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 AsciiVarChar(usize),
38 ObservedNVarChar,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
44pub enum BinaryPolicy {
45 #[default]
47 VarBinaryMax,
48 VarBinary(usize),
50 ObservedVarBinary,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
56pub enum TimestampPolicy {
57 DateTime2 {
59 precision: u8,
61 },
62 DateTime,
64}
65
66impl Default for TimestampPolicy {
67 fn default() -> Self {
68 Self::DateTime2 { precision: 7 }
69 }
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
74pub enum TimezonePolicy {
75 #[default]
77 Reject,
78 DateTimeOffset,
80 NormalizeUtcDateTime2,
82}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
86pub enum NanosecondPolicy {
87 #[default]
89 RejectNon100ns,
90 RoundTo100ns,
92 TruncateTo100ns,
94}
95
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
98pub enum UInt64Policy {
99 #[default]
101 Reject,
102 Decimal20_0,
104 CheckedBigInt,
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
110pub enum DecimalPolicy {
111 #[default]
113 RejectNegativeScale,
114 NormalizeNegativeScale,
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
120pub enum Decimal256Policy {
121 #[default]
123 CheckedDowncast,
124 Reject,
126}
127
128#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
130pub enum FloatPolicy {
131 #[default]
133 RejectNonFinite,
134}
135
136#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
138pub enum Date64Policy {
139 #[default]
141 RejectNonMidnight,
142 TimestampDateTime2,
144}
145
146#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
148pub enum SchemaCheck {
149 #[default]
151 Strict,
152}
153
154#[cfg(test)]
155mod tests {
156 use super::{
157 BinaryPolicy, Date64Policy, Decimal256Policy, DecimalPolicy, FloatPolicy, NanosecondPolicy,
158 PlanOptions, SchemaCheck, StringPolicy, TimestampPolicy, TimezonePolicy, UInt64Policy,
159 };
160
161 #[test]
162 fn defaults_match_v0_1_policy_decisions() {
163 let options = PlanOptions::default();
164
165 assert_eq!(options.string_policy, StringPolicy::NVarCharMax);
166 assert_eq!(options.binary_policy, BinaryPolicy::VarBinaryMax);
167 assert_eq!(options.timezone_policy, TimezonePolicy::Reject);
168 assert_eq!(
169 options.timestamp_policy,
170 TimestampPolicy::DateTime2 { precision: 7 }
171 );
172 assert_eq!(options.nanosecond_policy, NanosecondPolicy::RejectNon100ns);
173 assert_eq!(options.uint64_policy, UInt64Policy::Reject);
174 assert_eq!(options.decimal_policy, DecimalPolicy::RejectNegativeScale);
175 assert_eq!(options.decimal256_policy, Decimal256Policy::CheckedDowncast);
176 assert_eq!(options.float_policy, FloatPolicy::RejectNonFinite);
177 assert_eq!(options.date64_policy, Date64Policy::RejectNonMidnight);
178 }
179
180 #[test]
181 fn individual_policy_defaults_match_plan_options() {
182 assert_eq!(StringPolicy::default(), StringPolicy::NVarCharMax);
183 assert_eq!(BinaryPolicy::default(), BinaryPolicy::VarBinaryMax);
184 assert_eq!(TimezonePolicy::default(), TimezonePolicy::Reject);
185 assert_eq!(
186 TimestampPolicy::default(),
187 TimestampPolicy::DateTime2 { precision: 7 }
188 );
189 assert_eq!(
190 NanosecondPolicy::default(),
191 NanosecondPolicy::RejectNon100ns
192 );
193 assert_eq!(UInt64Policy::default(), UInt64Policy::Reject);
194 assert_eq!(DecimalPolicy::default(), DecimalPolicy::RejectNegativeScale);
195 assert_eq!(
196 Decimal256Policy::default(),
197 Decimal256Policy::CheckedDowncast
198 );
199 assert_eq!(FloatPolicy::default(), FloatPolicy::RejectNonFinite);
200 assert_eq!(Date64Policy::default(), Date64Policy::RejectNonMidnight);
201 assert_eq!(SchemaCheck::default(), SchemaCheck::Strict);
202 }
203
204 #[test]
205 fn supports_explicit_non_default_policy_overrides() {
206 let options = PlanOptions {
207 string_policy: StringPolicy::AsciiVarChar(128),
208 binary_policy: BinaryPolicy::VarBinary(256),
209 timezone_policy: TimezonePolicy::DateTimeOffset,
210 timestamp_policy: TimestampPolicy::DateTime,
211 nanosecond_policy: NanosecondPolicy::RoundTo100ns,
212 uint64_policy: UInt64Policy::Decimal20_0,
213 decimal_policy: DecimalPolicy::NormalizeNegativeScale,
214 decimal256_policy: Decimal256Policy::Reject,
215 float_policy: FloatPolicy::RejectNonFinite,
216 date64_policy: Date64Policy::TimestampDateTime2,
217 };
218
219 assert_eq!(options.string_policy, StringPolicy::AsciiVarChar(128));
220 assert_eq!(options.binary_policy, BinaryPolicy::VarBinary(256));
221 assert_eq!(options.timezone_policy, TimezonePolicy::DateTimeOffset);
222 assert_eq!(options.timestamp_policy, TimestampPolicy::DateTime);
223 assert_eq!(options.nanosecond_policy, NanosecondPolicy::RoundTo100ns);
224 assert_eq!(options.uint64_policy, UInt64Policy::Decimal20_0);
225 assert_eq!(
226 options.decimal_policy,
227 DecimalPolicy::NormalizeNegativeScale
228 );
229 assert_eq!(options.decimal256_policy, Decimal256Policy::Reject);
230 assert_eq!(options.float_policy, FloatPolicy::RejectNonFinite);
231 assert_eq!(options.date64_policy, Date64Policy::TimestampDateTime2);
232 }
233}