1use std::fmt;
22use std::str::FromStr;
23
24use serde::{Deserialize, Serialize};
25
26use crate::ast::Ident;
27use crate::ast::display::{self, AstDisplay, AstFormatter};
28
29#[derive(Debug)]
30pub struct ValueError(pub(crate) String);
31
32impl std::error::Error for ValueError {}
33
34impl fmt::Display for ValueError {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 write!(f, "{}", self.0)
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
42pub enum Value {
43 Number(String),
45 String(String),
47 HexString(String),
49 Boolean(bool),
51 Interval(IntervalValue),
59 Null,
61}
62
63impl AstDisplay for Value {
64 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
65 if f.redacted() {
66 match self {
69 Value::Number(_) | Value::String(_) | Value::HexString(_) => {
70 f.write_str("'<REDACTED>'");
71 return;
72 }
73 Value::Interval(_) => {
74 f.write_str("INTERVAL '<REDACTED>'");
75 return;
76 }
77 Value::Boolean(_) | Value::Null => {
78 }
80 }
81 }
82 match self {
83 Value::Number(v) => f.write_str(v),
84 Value::String(v) => {
85 f.write_str("'");
86 f.write_node(&display::escape_single_quote_string(v));
87 f.write_str("'");
88 }
89 Value::HexString(v) => {
90 f.write_str("X'");
91 f.write_str(v);
92 f.write_str("'");
93 }
94 Value::Boolean(v) => f.write_str(v),
95 Value::Interval(interval_value) => {
96 f.write_str("INTERVAL '");
97 f.write_node(interval_value);
98 }
99 Value::Null => f.write_str("NULL"),
100 }
101 }
102}
103impl_display!(Value);
104
105impl AstDisplay for IntervalValue {
106 fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
107 if f.redacted() {
108 f.write_str("<REDACTED>'");
109 } else {
110 let IntervalValue {
111 value,
112 precision_high,
113 precision_low,
114 fsec_max_precision,
115 } = self;
116 f.write_node(&display::escape_single_quote_string(value));
117 f.write_str("'");
118 match (precision_high, precision_low, fsec_max_precision) {
119 (DateTimeField::Year, DateTimeField::Second, None) => {}
120 (DateTimeField::Year, DateTimeField::Second, Some(ns)) => {
121 f.write_str(" SECOND(");
122 f.write_str(ns);
123 f.write_str(")");
124 }
125 (DateTimeField::Year, low, None) => {
126 f.write_str(" ");
127 f.write_str(low);
128 }
129 (high, low, None) => {
130 f.write_str(" ");
131 f.write_str(high);
132 f.write_str(" TO ");
133 f.write_str(low);
134 }
135 (high, low, Some(ns)) => {
136 f.write_str(" ");
137 f.write_str(high);
138 f.write_str(" TO ");
139 f.write_str(low);
140 f.write_str("(");
141 f.write_str(ns);
142 f.write_str(")");
143 }
144 }
145 }
146 }
147}
148
149impl From<Ident> for Value {
150 fn from(ident: Ident) -> Self {
151 Self::String(ident.0)
152 }
153}
154
155#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
156pub enum DateTimeField {
157 Millennium,
158 Century,
159 Decade,
160 Year,
161 Month,
162 Day,
163 Hour,
164 Minute,
165 Second,
166 Milliseconds,
167 Microseconds,
168}
169
170impl fmt::Display for DateTimeField {
171 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
172 f.write_str(match self {
173 DateTimeField::Millennium => "MILLENNIUM",
174 DateTimeField::Century => "CENTURY",
175 DateTimeField::Decade => "DECADE",
176 DateTimeField::Year => "YEAR",
177 DateTimeField::Month => "MONTH",
178 DateTimeField::Day => "DAY",
179 DateTimeField::Hour => "HOUR",
180 DateTimeField::Minute => "MINUTE",
181 DateTimeField::Second => "SECOND",
182 DateTimeField::Milliseconds => "MILLISECONDS",
183 DateTimeField::Microseconds => "MICROSECONDS",
184 })
185 }
186}
187
188impl FromStr for DateTimeField {
189 type Err = String;
190
191 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
192 match s.to_uppercase().as_ref() {
193 "MILLENNIUM" | "MILLENNIA" | "MIL" | "MILS" => Ok(Self::Millennium),
194 "CENTURY" | "CENTURIES" | "CENT" | "C" => Ok(Self::Century),
195 "DECADE" | "DECADES" | "DEC" | "DECS" => Ok(Self::Decade),
196 "YEAR" | "YEARS" | "YR" | "YRS" | "Y" => Ok(Self::Year),
197 "MONTH" | "MONTHS" | "MON" | "MONS" => Ok(Self::Month),
198 "DAY" | "DAYS" | "D" => Ok(Self::Day),
199 "HOUR" | "HOURS" | "HR" | "HRS" | "H" => Ok(Self::Hour),
200 "MINUTE" | "MINUTES" | "MIN" | "MINS" | "M" => Ok(Self::Minute),
201 "SECOND" | "SECONDS" | "SEC" | "SECS" | "S" => Ok(Self::Second),
202 "MILLISECOND" | "MILLISECONDS" | "MILLISECON" | "MILLISECONS" | "MSECOND"
203 | "MSECONDS" | "MSEC" | "MSECS" | "MS" => Ok(Self::Milliseconds),
204 "MICROSECOND" | "MICROSECONDS" | "MICROSECON" | "MICROSECONS" | "USECOND"
205 | "USECONDS" | "USEC" | "USECS" | "US" => Ok(Self::Microseconds),
206 _ => Err(format!("invalid DateTimeField: {}", s)),
207 }
208 }
209}
210
211#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
214pub struct IntervalValue {
215 pub value: String,
217 pub precision_high: DateTimeField,
220 pub precision_low: DateTimeField,
226 pub fsec_max_precision: Option<u64>,
229}
230
231impl Default for IntervalValue {
232 fn default() -> Self {
233 Self {
234 value: String::default(),
235 precision_high: DateTimeField::Year,
236 precision_low: DateTimeField::Second,
237 fsec_max_precision: None,
238 }
239 }
240}
241
242#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
243pub struct Version(pub(crate) u64);
244
245impl Version {
246 pub fn new(val: u64) -> Self {
247 Version(val)
248 }
249
250 pub fn into_inner(self) -> u64 {
251 self.0
252 }
253}
254
255impl AstDisplay for Version {
256 fn fmt<W>(&self, f: &mut AstFormatter<W>)
257 where
258 W: fmt::Write,
259 {
260 f.write_node(&self.0);
261 }
262}
263impl_display!(Version);