1#[cfg(not(feature = "std"))]
14use alloc::string::String;
15use core::fmt;
16
17#[cfg(feature = "bigdecimal")]
18use bigdecimal::BigDecimal;
19
20#[cfg(feature = "serde")]
21use serde::{Deserialize, Serialize};
22
23#[cfg(feature = "visitor")]
24use sqlparser_derive::{Visit, VisitMut};
25
26#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
28#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
29#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
30pub enum Value {
31 #[cfg(not(feature = "bigdecimal"))]
33 Number(String, bool),
34 #[cfg(feature = "bigdecimal")]
35 Number(BigDecimal, bool),
36 SingleQuotedString(String),
38 DollarQuotedString(DollarQuotedString),
40 EscapedStringLiteral(String),
44 SingleQuotedByteStringLiteral(String),
46 DoubleQuotedByteStringLiteral(String),
48 RawStringLiteral(String),
51 NationalStringLiteral(String),
53 HexStringLiteral(String),
55
56 DoubleQuotedString(String),
57 Boolean(bool),
59 Null,
61 Placeholder(String),
63 UnQuotedString(String),
65}
66
67impl fmt::Display for Value {
68 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 match self {
70 Value::Number(v, l) => write!(f, "{}{long}", v, long = if *l { "L" } else { "" }),
71 Value::DoubleQuotedString(v) => write!(f, "\"{v}\""),
72 Value::SingleQuotedString(v) => write!(f, "'{}'", escape_single_quote_string(v)),
73 Value::DollarQuotedString(v) => write!(f, "{v}"),
74 Value::EscapedStringLiteral(v) => write!(f, "E'{}'", escape_escaped_string(v)),
75 Value::NationalStringLiteral(v) => write!(f, "N'{v}'"),
76 Value::HexStringLiteral(v) => write!(f, "X'{v}'"),
77 Value::Boolean(v) => write!(f, "{v}"),
78 Value::SingleQuotedByteStringLiteral(v) => write!(f, "B'{v}'"),
79 Value::DoubleQuotedByteStringLiteral(v) => write!(f, "B\"{v}\""),
80 Value::RawStringLiteral(v) => write!(f, "R'{v}'"),
81 Value::Null => write!(f, "NULL"),
82 Value::Placeholder(v) => write!(f, "{v}"),
83 Value::UnQuotedString(v) => write!(f, "{v}"),
84 }
85 }
86}
87
88#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
89#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
90#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
91pub struct DollarQuotedString {
92 pub value: String,
93 pub tag: Option<String>,
94}
95
96impl fmt::Display for DollarQuotedString {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98 match &self.tag {
99 Some(tag) => {
100 write!(f, "${}${}${}$", tag, self.value, tag)
101 }
102 None => {
103 write!(f, "$${}$$", self.value)
104 }
105 }
106 }
107}
108
109#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
110#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
111#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
112pub enum DateTimeField {
113 Year,
114 Month,
115 Week,
116 Day,
117 Date,
118 Hour,
119 Minute,
120 Second,
121 Century,
122 Decade,
123 Dow,
124 Doy,
125 Epoch,
126 Isodow,
127 Isoyear,
128 Julian,
129 Microsecond,
130 Microseconds,
131 Millenium,
132 Millennium,
133 Millisecond,
134 Milliseconds,
135 Nanosecond,
136 Nanoseconds,
137 Quarter,
138 Timezone,
139 TimezoneHour,
140 TimezoneMinute,
141 NoDateTime,
142}
143
144impl fmt::Display for DateTimeField {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 f.write_str(match self {
147 DateTimeField::Year => "YEAR",
148 DateTimeField::Month => "MONTH",
149 DateTimeField::Week => "WEEK",
150 DateTimeField::Day => "DAY",
151 DateTimeField::Date => "DATE",
152 DateTimeField::Hour => "HOUR",
153 DateTimeField::Minute => "MINUTE",
154 DateTimeField::Second => "SECOND",
155 DateTimeField::Century => "CENTURY",
156 DateTimeField::Decade => "DECADE",
157 DateTimeField::Dow => "DOW",
158 DateTimeField::Doy => "DOY",
159 DateTimeField::Epoch => "EPOCH",
160 DateTimeField::Isodow => "ISODOW",
161 DateTimeField::Isoyear => "ISOYEAR",
162 DateTimeField::Julian => "JULIAN",
163 DateTimeField::Microsecond => "MICROSECOND",
164 DateTimeField::Microseconds => "MICROSECONDS",
165 DateTimeField::Millenium => "MILLENIUM",
166 DateTimeField::Millennium => "MILLENNIUM",
167 DateTimeField::Millisecond => "MILLISECOND",
168 DateTimeField::Milliseconds => "MILLISECONDS",
169 DateTimeField::Nanosecond => "NANOSECOND",
170 DateTimeField::Nanoseconds => "NANOSECONDS",
171 DateTimeField::Quarter => "QUARTER",
172 DateTimeField::Timezone => "TIMEZONE",
173 DateTimeField::TimezoneHour => "TIMEZONE_HOUR",
174 DateTimeField::TimezoneMinute => "TIMEZONE_MINUTE",
175 DateTimeField::NoDateTime => "NODATETIME",
176 })
177 }
178}
179
180pub struct EscapeQuotedString<'a> {
181 string: &'a str,
182 quote: char,
183}
184
185impl<'a> fmt::Display for EscapeQuotedString<'a> {
186 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
187 for c in self.string.chars() {
188 if c == self.quote {
189 write!(f, "{q}{q}", q = self.quote)?;
190 } else {
191 write!(f, "{c}")?;
192 }
193 }
194 Ok(())
195 }
196}
197
198pub fn escape_quoted_string(string: &str, quote: char) -> EscapeQuotedString<'_> {
199 EscapeQuotedString { string, quote }
200}
201
202pub fn escape_single_quote_string(s: &str) -> EscapeQuotedString<'_> {
203 escape_quoted_string(s, '\'')
204}
205
206pub struct EscapeEscapedStringLiteral<'a>(&'a str);
207
208impl<'a> fmt::Display for EscapeEscapedStringLiteral<'a> {
209 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
210 for c in self.0.chars() {
211 match c {
212 '\'' => {
213 write!(f, r#"\'"#)?;
214 }
215 '\\' => {
216 write!(f, r#"\\"#)?;
217 }
218 '\n' => {
219 write!(f, r#"\n"#)?;
220 }
221 '\t' => {
222 write!(f, r#"\t"#)?;
223 }
224 '\r' => {
225 write!(f, r#"\r"#)?;
226 }
227 _ => {
228 write!(f, "{c}")?;
229 }
230 }
231 }
232 Ok(())
233 }
234}
235
236pub fn escape_escaped_string(s: &str) -> EscapeEscapedStringLiteral<'_> {
237 EscapeEscapedStringLiteral(s)
238}
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
242#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
243pub enum TrimWhereField {
244 Both,
245 Leading,
246 Trailing,
247}
248
249impl fmt::Display for TrimWhereField {
250 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251 use TrimWhereField::*;
252 f.write_str(match self {
253 Both => "BOTH",
254 Leading => "LEADING",
255 Trailing => "TRAILING",
256 })
257 }
258}