1#[cfg(not(feature = "std"))]
19use alloc::string::String;
20
21use core::fmt;
22
23#[cfg(feature = "bigdecimal")]
24use bigdecimal::BigDecimal;
25
26#[cfg(feature = "serde")]
27use serde::{Deserialize, Serialize};
28
29use crate::{ast::Ident, tokenizer::Span};
30#[cfg(feature = "visitor")]
31use sqlparser_derive::{Visit, VisitMut};
32
33#[derive(Debug, Clone, Eq)]
68#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
69#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
70pub struct ValueWithSpan {
71 pub value: Value,
72 pub span: Span,
73}
74
75impl PartialEq for ValueWithSpan {
76 fn eq(&self, other: &Self) -> bool {
77 self.value == other.value
78 }
79}
80
81impl Ord for ValueWithSpan {
82 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
83 self.value.cmp(&other.value)
84 }
85}
86
87impl PartialOrd for ValueWithSpan {
88 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
89 Some(Ord::cmp(self, other))
90 }
91}
92
93impl core::hash::Hash for ValueWithSpan {
94 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
95 self.value.hash(state);
96 }
97}
98
99impl From<Value> for ValueWithSpan {
100 fn from(value: Value) -> Self {
101 value.with_empty_span()
102 }
103}
104
105impl From<ValueWithSpan> for Value {
106 fn from(value: ValueWithSpan) -> Self {
107 value.value
108 }
109}
110
111#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
113#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
114#[cfg_attr(
115 feature = "visitor",
116 derive(Visit, VisitMut),
117 visit(with = "visit_value")
118)]
119
120pub enum Value {
121 #[cfg(not(feature = "bigdecimal"))]
123 Number(String, bool),
124 #[cfg(feature = "bigdecimal")]
125 Number(BigDecimal, bool),
129 SingleQuotedString(String),
131 DollarQuotedString(DollarQuotedString),
133 TripleSingleQuotedString(String),
136 TripleDoubleQuotedString(String),
139 EscapedStringLiteral(String),
143 UnicodeStringLiteral(String),
147 SingleQuotedByteStringLiteral(String),
149 DoubleQuotedByteStringLiteral(String),
151 TripleSingleQuotedByteStringLiteral(String),
154 TripleDoubleQuotedByteStringLiteral(String),
157 SingleQuotedRawStringLiteral(String),
160 DoubleQuotedRawStringLiteral(String),
163 TripleSingleQuotedRawStringLiteral(String),
166 TripleDoubleQuotedRawStringLiteral(String),
169 NationalStringLiteral(String),
171 HexStringLiteral(String),
173
174 DoubleQuotedString(String),
175 Boolean(bool),
177 Null,
179 Placeholder(String),
181}
182
183impl ValueWithSpan {
184 pub fn into_string(self) -> Option<String> {
186 self.value.into_string()
187 }
188}
189
190impl Value {
191 pub fn into_string(self) -> Option<String> {
193 match self {
194 Value::SingleQuotedString(s)
195 | Value::DoubleQuotedString(s)
196 | Value::TripleSingleQuotedString(s)
197 | Value::TripleDoubleQuotedString(s)
198 | Value::SingleQuotedByteStringLiteral(s)
199 | Value::DoubleQuotedByteStringLiteral(s)
200 | Value::TripleSingleQuotedByteStringLiteral(s)
201 | Value::TripleDoubleQuotedByteStringLiteral(s)
202 | Value::SingleQuotedRawStringLiteral(s)
203 | Value::DoubleQuotedRawStringLiteral(s)
204 | Value::TripleSingleQuotedRawStringLiteral(s)
205 | Value::TripleDoubleQuotedRawStringLiteral(s)
206 | Value::EscapedStringLiteral(s)
207 | Value::UnicodeStringLiteral(s)
208 | Value::NationalStringLiteral(s)
209 | Value::HexStringLiteral(s) => Some(s),
210 Value::DollarQuotedString(s) => Some(s.value),
211 _ => None,
212 }
213 }
214
215 pub fn with_span(self, span: Span) -> ValueWithSpan {
216 ValueWithSpan { value: self, span }
217 }
218
219 pub fn with_empty_span(self) -> ValueWithSpan {
220 self.with_span(Span::empty())
221 }
222}
223
224impl fmt::Display for ValueWithSpan {
225 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226 write!(f, "{}", self.value)
227 }
228}
229
230impl fmt::Display for Value {
231 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
232 match self {
233 Value::Number(v, l) => write!(f, "{}{long}", v, long = if *l { "L" } else { "" }),
234 Value::DoubleQuotedString(v) => write!(f, "\"{}\"", escape_double_quote_string(v)),
235 Value::SingleQuotedString(v) => write!(f, "'{}'", escape_single_quote_string(v)),
236 Value::TripleSingleQuotedString(v) => {
237 write!(f, "'''{v}'''")
238 }
239 Value::TripleDoubleQuotedString(v) => {
240 write!(f, r#""""{v}""""#)
241 }
242 Value::DollarQuotedString(v) => write!(f, "{v}"),
243 Value::EscapedStringLiteral(v) => write!(f, "E'{}'", escape_escaped_string(v)),
244 Value::UnicodeStringLiteral(v) => write!(f, "U&'{}'", escape_unicode_string(v)),
245 Value::NationalStringLiteral(v) => write!(f, "N'{v}'"),
246 Value::HexStringLiteral(v) => write!(f, "X'{v}'"),
247 Value::Boolean(v) => write!(f, "{v}"),
248 Value::SingleQuotedByteStringLiteral(v) => write!(f, "B'{v}'"),
249 Value::DoubleQuotedByteStringLiteral(v) => write!(f, "B\"{v}\""),
250 Value::TripleSingleQuotedByteStringLiteral(v) => write!(f, "B'''{v}'''"),
251 Value::TripleDoubleQuotedByteStringLiteral(v) => write!(f, r#"B"""{v}""""#),
252 Value::SingleQuotedRawStringLiteral(v) => write!(f, "R'{v}'"),
253 Value::DoubleQuotedRawStringLiteral(v) => write!(f, "R\"{v}\""),
254 Value::TripleSingleQuotedRawStringLiteral(v) => write!(f, "R'''{v}'''"),
255 Value::TripleDoubleQuotedRawStringLiteral(v) => write!(f, r#"R"""{v}""""#),
256 Value::Null => write!(f, "NULL"),
257 Value::Placeholder(v) => write!(f, "{v}"),
258 }
259 }
260}
261
262#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
263#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
264#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
265pub struct DollarQuotedString {
266 pub value: String,
267 pub tag: Option<String>,
268}
269
270impl fmt::Display for DollarQuotedString {
271 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
272 match &self.tag {
273 Some(tag) => {
274 write!(f, "${}${}${}$", tag, self.value, tag)
275 }
276 None => {
277 write!(f, "$${}$$", self.value)
278 }
279 }
280 }
281}
282
283#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
284#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
285#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
286pub enum DateTimeField {
287 Year,
288 Years,
289 Month,
290 Months,
291 Week(Option<Ident>),
299 Weeks,
300 Day,
301 DayOfWeek,
302 DayOfYear,
303 Days,
304 Date,
305 Datetime,
306 Hour,
307 Hours,
308 Minute,
309 Minutes,
310 Second,
311 Seconds,
312 Century,
313 Decade,
314 Dow,
315 Doy,
316 Epoch,
317 Isodow,
318 IsoWeek,
319 Isoyear,
320 Julian,
321 Microsecond,
322 Microseconds,
323 Millenium,
324 Millennium,
325 Millisecond,
326 Milliseconds,
327 Nanosecond,
328 Nanoseconds,
329 Quarter,
330 Time,
331 Timezone,
332 TimezoneAbbr,
333 TimezoneHour,
334 TimezoneMinute,
335 TimezoneRegion,
336 NoDateTime,
337 Custom(Ident),
344}
345
346impl fmt::Display for DateTimeField {
347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
348 match self {
349 DateTimeField::Year => write!(f, "YEAR"),
350 DateTimeField::Years => write!(f, "YEARS"),
351 DateTimeField::Month => write!(f, "MONTH"),
352 DateTimeField::Months => write!(f, "MONTHS"),
353 DateTimeField::Week(week_day) => {
354 write!(f, "WEEK")?;
355 if let Some(week_day) = week_day {
356 write!(f, "({week_day})")?
357 }
358 Ok(())
359 }
360 DateTimeField::Weeks => write!(f, "WEEKS"),
361 DateTimeField::Day => write!(f, "DAY"),
362 DateTimeField::DayOfWeek => write!(f, "DAYOFWEEK"),
363 DateTimeField::DayOfYear => write!(f, "DAYOFYEAR"),
364 DateTimeField::Days => write!(f, "DAYS"),
365 DateTimeField::Date => write!(f, "DATE"),
366 DateTimeField::Datetime => write!(f, "DATETIME"),
367 DateTimeField::Hour => write!(f, "HOUR"),
368 DateTimeField::Hours => write!(f, "HOURS"),
369 DateTimeField::Minute => write!(f, "MINUTE"),
370 DateTimeField::Minutes => write!(f, "MINUTES"),
371 DateTimeField::Second => write!(f, "SECOND"),
372 DateTimeField::Seconds => write!(f, "SECONDS"),
373 DateTimeField::Century => write!(f, "CENTURY"),
374 DateTimeField::Decade => write!(f, "DECADE"),
375 DateTimeField::Dow => write!(f, "DOW"),
376 DateTimeField::Doy => write!(f, "DOY"),
377 DateTimeField::Epoch => write!(f, "EPOCH"),
378 DateTimeField::Isodow => write!(f, "ISODOW"),
379 DateTimeField::Isoyear => write!(f, "ISOYEAR"),
380 DateTimeField::IsoWeek => write!(f, "ISOWEEK"),
381 DateTimeField::Julian => write!(f, "JULIAN"),
382 DateTimeField::Microsecond => write!(f, "MICROSECOND"),
383 DateTimeField::Microseconds => write!(f, "MICROSECONDS"),
384 DateTimeField::Millenium => write!(f, "MILLENIUM"),
385 DateTimeField::Millennium => write!(f, "MILLENNIUM"),
386 DateTimeField::Millisecond => write!(f, "MILLISECOND"),
387 DateTimeField::Milliseconds => write!(f, "MILLISECONDS"),
388 DateTimeField::Nanosecond => write!(f, "NANOSECOND"),
389 DateTimeField::Nanoseconds => write!(f, "NANOSECONDS"),
390 DateTimeField::Quarter => write!(f, "QUARTER"),
391 DateTimeField::Time => write!(f, "TIME"),
392 DateTimeField::Timezone => write!(f, "TIMEZONE"),
393 DateTimeField::TimezoneAbbr => write!(f, "TIMEZONE_ABBR"),
394 DateTimeField::TimezoneHour => write!(f, "TIMEZONE_HOUR"),
395 DateTimeField::TimezoneMinute => write!(f, "TIMEZONE_MINUTE"),
396 DateTimeField::TimezoneRegion => write!(f, "TIMEZONE_REGION"),
397 DateTimeField::NoDateTime => write!(f, "NODATETIME"),
398 DateTimeField::Custom(custom) => write!(f, "{custom}"),
399 }
400 }
401}
402
403#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
404#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
405#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
406pub enum NormalizationForm {
411 NFC,
413 NFD,
415 NFKC,
417 NFKD,
419}
420
421impl fmt::Display for NormalizationForm {
422 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
423 match self {
424 NormalizationForm::NFC => write!(f, "NFC"),
425 NormalizationForm::NFD => write!(f, "NFD"),
426 NormalizationForm::NFKC => write!(f, "NFKC"),
427 NormalizationForm::NFKD => write!(f, "NFKD"),
428 }
429 }
430}
431
432pub struct EscapeQuotedString<'a> {
433 string: &'a str,
434 quote: char,
435}
436
437impl fmt::Display for EscapeQuotedString<'_> {
438 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
439 let quote = self.quote;
458 let mut previous_char = char::default();
459 let mut peekable_chars = self.string.chars().peekable();
460 while let Some(&ch) = peekable_chars.peek() {
461 match ch {
462 char if char == quote => {
463 if previous_char == '\\' {
464 write!(f, "{char}")?;
465 peekable_chars.next();
466 continue;
467 }
468 peekable_chars.next();
469 if peekable_chars.peek().map(|c| *c == quote).unwrap_or(false) {
470 write!(f, "{char}{char}")?;
471 peekable_chars.next();
472 } else {
473 write!(f, "{char}{char}")?;
474 }
475 }
476 _ => {
477 write!(f, "{ch}")?;
478 peekable_chars.next();
479 }
480 }
481 previous_char = ch;
482 }
483 Ok(())
484 }
485}
486
487pub fn escape_quoted_string(string: &str, quote: char) -> EscapeQuotedString<'_> {
488 EscapeQuotedString { string, quote }
489}
490
491pub fn escape_single_quote_string(s: &str) -> EscapeQuotedString<'_> {
492 escape_quoted_string(s, '\'')
493}
494
495pub fn escape_double_quote_string(s: &str) -> EscapeQuotedString<'_> {
496 escape_quoted_string(s, '\"')
497}
498
499pub struct EscapeEscapedStringLiteral<'a>(&'a str);
500
501impl fmt::Display for EscapeEscapedStringLiteral<'_> {
502 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
503 for c in self.0.chars() {
504 match c {
505 '\'' => {
506 write!(f, r#"\'"#)?;
507 }
508 '\\' => {
509 write!(f, r#"\\"#)?;
510 }
511 '\n' => {
512 write!(f, r#"\n"#)?;
513 }
514 '\t' => {
515 write!(f, r#"\t"#)?;
516 }
517 '\r' => {
518 write!(f, r#"\r"#)?;
519 }
520 _ => {
521 write!(f, "{c}")?;
522 }
523 }
524 }
525 Ok(())
526 }
527}
528
529pub fn escape_escaped_string(s: &str) -> EscapeEscapedStringLiteral<'_> {
530 EscapeEscapedStringLiteral(s)
531}
532
533pub struct EscapeUnicodeStringLiteral<'a>(&'a str);
534
535impl fmt::Display for EscapeUnicodeStringLiteral<'_> {
536 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
537 for c in self.0.chars() {
538 match c {
539 '\'' => {
540 write!(f, "''")?;
541 }
542 '\\' => {
543 write!(f, r#"\\"#)?;
544 }
545 x if x.is_ascii() => {
546 write!(f, "{}", c)?;
547 }
548 _ => {
549 let codepoint = c as u32;
550 if codepoint <= 0xFFFF {
553 write!(f, "\\{:04X}", codepoint)?;
554 } else {
555 write!(f, "\\+{:06X}", codepoint)?;
556 }
557 }
558 }
559 }
560 Ok(())
561 }
562}
563
564pub fn escape_unicode_string(s: &str) -> EscapeUnicodeStringLiteral<'_> {
565 EscapeUnicodeStringLiteral(s)
566}
567
568#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
569#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
570#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
571pub enum TrimWhereField {
572 Both,
573 Leading,
574 Trailing,
575}
576
577impl fmt::Display for TrimWhereField {
578 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
579 use TrimWhereField::*;
580 f.write_str(match self {
581 Both => "BOTH",
582 Leading => "LEADING",
583 Trailing => "TRAILING",
584 })
585 }
586}