1#[cfg(not(feature = "std"))]
19use alloc::string::String;
20
21use core::{
22 fmt,
23 ops::{Deref, DerefMut},
24};
25
26#[cfg(feature = "bigdecimal")]
27use bigdecimal::BigDecimal;
28
29#[cfg(feature = "serde")]
30use serde::{Deserialize, Serialize};
31
32use crate::{ast::Ident, tokenizer::Span};
33#[cfg(feature = "visitor")]
34use sqlparser_derive::{Visit, VisitMut};
35
36#[derive(Debug, Clone, Eq)]
72#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
73#[cfg_attr(
74 feature = "visitor",
75 derive(Visit, VisitMut),
76 visit(with = "visit_value")
77)]
78pub struct ValueWithSpan {
79 pub value: Value,
81 pub span: Span,
83}
84
85impl PartialEq for ValueWithSpan {
86 fn eq(&self, other: &Self) -> bool {
87 self.value == other.value
88 }
89}
90
91impl Ord for ValueWithSpan {
92 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
93 self.value.cmp(&other.value)
94 }
95}
96
97impl PartialOrd for ValueWithSpan {
98 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
99 Some(Ord::cmp(self, other))
100 }
101}
102
103impl core::hash::Hash for ValueWithSpan {
104 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
105 self.value.hash(state);
106 }
107}
108
109impl From<Value> for ValueWithSpan {
110 fn from(value: Value) -> Self {
111 value.with_empty_span()
112 }
113}
114
115impl From<ValueWithSpan> for Value {
116 fn from(value: ValueWithSpan) -> Self {
117 value.value
118 }
119}
120
121impl Deref for ValueWithSpan {
122 type Target = Value;
123
124 fn deref(&self) -> &Self::Target {
125 &self.value
126 }
127}
128
129impl DerefMut for ValueWithSpan {
130 fn deref_mut(&mut self) -> &mut Self::Target {
131 &mut self.value
132 }
133}
134
135#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
137#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
138#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
139pub enum Value {
140 #[cfg(not(feature = "bigdecimal"))]
142 Number(String, bool),
143 #[cfg(feature = "bigdecimal")]
144 Number(BigDecimal, bool),
149 SingleQuotedString(String),
151 DollarQuotedString(DollarQuotedString),
153 TripleSingleQuotedString(String),
156 TripleDoubleQuotedString(String),
159 EscapedStringLiteral(String),
163 UnicodeStringLiteral(String),
167 SingleQuotedByteStringLiteral(String),
169 DoubleQuotedByteStringLiteral(String),
171 TripleSingleQuotedByteStringLiteral(String),
174 TripleDoubleQuotedByteStringLiteral(String),
177 SingleQuotedRawStringLiteral(String),
180 DoubleQuotedRawStringLiteral(String),
183 TripleSingleQuotedRawStringLiteral(String),
186 TripleDoubleQuotedRawStringLiteral(String),
189 NationalStringLiteral(String),
191 QuoteDelimitedStringLiteral(QuoteDelimitedString),
194 NationalQuoteDelimitedStringLiteral(QuoteDelimitedString),
197 HexStringLiteral(String),
199
200 DoubleQuotedString(String),
202 Boolean(bool),
204 Null,
206 Placeholder(String),
208}
209
210impl ValueWithSpan {
211 pub fn into_string(self) -> Option<String> {
213 self.value.into_string()
214 }
215}
216
217impl Value {
218 pub fn into_string(self) -> Option<String> {
220 match self {
221 Value::SingleQuotedString(s)
222 | Value::DoubleQuotedString(s)
223 | Value::TripleSingleQuotedString(s)
224 | Value::TripleDoubleQuotedString(s)
225 | Value::SingleQuotedByteStringLiteral(s)
226 | Value::DoubleQuotedByteStringLiteral(s)
227 | Value::TripleSingleQuotedByteStringLiteral(s)
228 | Value::TripleDoubleQuotedByteStringLiteral(s)
229 | Value::SingleQuotedRawStringLiteral(s)
230 | Value::DoubleQuotedRawStringLiteral(s)
231 | Value::TripleSingleQuotedRawStringLiteral(s)
232 | Value::TripleDoubleQuotedRawStringLiteral(s)
233 | Value::EscapedStringLiteral(s)
234 | Value::UnicodeStringLiteral(s)
235 | Value::NationalStringLiteral(s)
236 | Value::HexStringLiteral(s) => Some(s),
237 Value::DollarQuotedString(s) => Some(s.value),
238 Value::QuoteDelimitedStringLiteral(s) => Some(s.value),
239 Value::NationalQuoteDelimitedStringLiteral(s) => Some(s.value),
240 _ => None,
241 }
242 }
243
244 pub fn with_span(self, span: Span) -> ValueWithSpan {
246 ValueWithSpan { value: self, span }
247 }
248
249 pub fn with_empty_span(self) -> ValueWithSpan {
251 self.with_span(Span::empty())
252 }
253}
254
255impl fmt::Display for ValueWithSpan {
256 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
257 write!(f, "{}", self.value)
258 }
259}
260
261impl fmt::Display for Value {
262 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
263 match self {
264 Value::Number(v, l) => write!(f, "{}{long}", v, long = if *l { "L" } else { "" }),
265 Value::DoubleQuotedString(v) => write!(f, "\"{}\"", escape_double_quote_string(v)),
266 Value::SingleQuotedString(v) => write!(f, "'{}'", escape_single_quote_string(v)),
267 Value::TripleSingleQuotedString(v) => {
268 write!(f, "'''{v}'''")
269 }
270 Value::TripleDoubleQuotedString(v) => {
271 write!(f, r#""""{v}""""#)
272 }
273 Value::DollarQuotedString(v) => write!(f, "{v}"),
274 Value::EscapedStringLiteral(v) => write!(f, "E'{}'", escape_escaped_string(v)),
275 Value::UnicodeStringLiteral(v) => write!(f, "U&'{}'", escape_unicode_string(v)),
276 Value::NationalStringLiteral(v) => write!(f, "N'{}'", escape_single_quote_string(v)),
277 Value::QuoteDelimitedStringLiteral(v) => v.fmt(f),
278 Value::NationalQuoteDelimitedStringLiteral(v) => write!(f, "N{v}"),
279 Value::HexStringLiteral(v) => write!(f, "X'{}'", escape_single_quote_string(v)),
280 Value::Boolean(v) => write!(f, "{v}"),
281 Value::SingleQuotedByteStringLiteral(v) => {
282 write!(f, "B'{}'", escape_single_quote_string(v))
283 }
284 Value::DoubleQuotedByteStringLiteral(v) => {
285 write!(f, "B\"{}\"", escape_double_quote_string(v))
286 }
287 Value::TripleSingleQuotedByteStringLiteral(v) => write!(f, "B'''{v}'''"),
288 Value::TripleDoubleQuotedByteStringLiteral(v) => write!(f, r#"B"""{v}""""#),
289 Value::SingleQuotedRawStringLiteral(v) => {
290 write!(f, "R'{}'", escape_single_quote_string(v))
291 }
292 Value::DoubleQuotedRawStringLiteral(v) => {
293 write!(f, "R\"{}\"", escape_double_quote_string(v))
294 }
295 Value::TripleSingleQuotedRawStringLiteral(v) => write!(f, "R'''{v}'''"),
296 Value::TripleDoubleQuotedRawStringLiteral(v) => write!(f, r#"R"""{v}""""#),
297 Value::Null => write!(f, "NULL"),
298 Value::Placeholder(v) => write!(f, "{v}"),
299 }
300 }
301}
302
303#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
305#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
306#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
307pub struct DollarQuotedString {
308 pub value: String,
310 pub tag: Option<String>,
312}
313
314impl fmt::Display for DollarQuotedString {
315 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
316 match &self.tag {
317 Some(tag) => {
318 write!(f, "${}${}${}$", tag, self.value, tag)
319 }
320 None => {
321 write!(f, "$${}$$", self.value)
322 }
323 }
324 }
325}
326
327#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
332#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
333#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
334pub struct QuoteDelimitedString {
335 pub start_quote: char,
337 pub value: String,
339 pub end_quote: char,
341}
342
343impl fmt::Display for QuoteDelimitedString {
344 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
345 write!(f, "Q'{}{}{}'", self.start_quote, self.value, self.end_quote)
346 }
347}
348
349#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
355#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
356#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
357pub enum DateTimeField {
358 Year,
360 Years,
362 Month,
364 Months,
366 Week(Option<Ident>),
370 Weeks,
372 Day,
374 DayOfWeek,
376 DayOfYear,
378 Days,
380 Date,
382 Datetime,
384 Hour,
386 Hours,
388 Minute,
390 Minutes,
392 Second,
394 Seconds,
396 Century,
398 Decade,
400 Dow,
402 Doy,
404 Epoch,
406 Isodow,
408 Isoyear,
410 IsoWeek,
412 Julian,
414 Microsecond,
416 Microseconds,
418 Millenium,
420 Millennium,
422 Millisecond,
424 Milliseconds,
426 Nanosecond,
428 Nanoseconds,
430 Quarter,
432 Time,
434 Timezone,
436 TimezoneAbbr,
438 TimezoneHour,
440 TimezoneMinute,
442 TimezoneRegion,
444 NoDateTime,
446 Custom(Ident),
453}
454
455impl fmt::Display for DateTimeField {
456 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
457 match self {
458 DateTimeField::Year => write!(f, "YEAR"),
459 DateTimeField::Years => write!(f, "YEARS"),
460 DateTimeField::Month => write!(f, "MONTH"),
461 DateTimeField::Months => write!(f, "MONTHS"),
462 DateTimeField::Week(week_day) => {
463 write!(f, "WEEK")?;
464 if let Some(week_day) = week_day {
465 write!(f, "({week_day})")?
466 }
467 Ok(())
468 }
469 DateTimeField::Weeks => write!(f, "WEEKS"),
470 DateTimeField::Day => write!(f, "DAY"),
471 DateTimeField::DayOfWeek => write!(f, "DAYOFWEEK"),
472 DateTimeField::DayOfYear => write!(f, "DAYOFYEAR"),
473 DateTimeField::Days => write!(f, "DAYS"),
474 DateTimeField::Date => write!(f, "DATE"),
475 DateTimeField::Datetime => write!(f, "DATETIME"),
476 DateTimeField::Hour => write!(f, "HOUR"),
477 DateTimeField::Hours => write!(f, "HOURS"),
478 DateTimeField::Minute => write!(f, "MINUTE"),
479 DateTimeField::Minutes => write!(f, "MINUTES"),
480 DateTimeField::Second => write!(f, "SECOND"),
481 DateTimeField::Seconds => write!(f, "SECONDS"),
482 DateTimeField::Century => write!(f, "CENTURY"),
483 DateTimeField::Decade => write!(f, "DECADE"),
484 DateTimeField::Dow => write!(f, "DOW"),
485 DateTimeField::Doy => write!(f, "DOY"),
486 DateTimeField::Epoch => write!(f, "EPOCH"),
487 DateTimeField::Isodow => write!(f, "ISODOW"),
488 DateTimeField::Isoyear => write!(f, "ISOYEAR"),
489 DateTimeField::IsoWeek => write!(f, "ISOWEEK"),
490 DateTimeField::Julian => write!(f, "JULIAN"),
491 DateTimeField::Microsecond => write!(f, "MICROSECOND"),
492 DateTimeField::Microseconds => write!(f, "MICROSECONDS"),
493 DateTimeField::Millenium => write!(f, "MILLENIUM"),
494 DateTimeField::Millennium => write!(f, "MILLENNIUM"),
495 DateTimeField::Millisecond => write!(f, "MILLISECOND"),
496 DateTimeField::Milliseconds => write!(f, "MILLISECONDS"),
497 DateTimeField::Nanosecond => write!(f, "NANOSECOND"),
498 DateTimeField::Nanoseconds => write!(f, "NANOSECONDS"),
499 DateTimeField::Quarter => write!(f, "QUARTER"),
500 DateTimeField::Time => write!(f, "TIME"),
501 DateTimeField::Timezone => write!(f, "TIMEZONE"),
502 DateTimeField::TimezoneAbbr => write!(f, "TIMEZONE_ABBR"),
503 DateTimeField::TimezoneHour => write!(f, "TIMEZONE_HOUR"),
504 DateTimeField::TimezoneMinute => write!(f, "TIMEZONE_MINUTE"),
505 DateTimeField::TimezoneRegion => write!(f, "TIMEZONE_REGION"),
506 DateTimeField::NoDateTime => write!(f, "NODATETIME"),
507 DateTimeField::Custom(custom) => write!(f, "{custom}"),
508 }
509 }
510}
511
512#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
513#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
514#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
515pub enum NormalizationForm {
520 NFC,
522 NFD,
524 NFKC,
526 NFKD,
528}
529
530impl fmt::Display for NormalizationForm {
531 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
532 match self {
533 NormalizationForm::NFC => write!(f, "NFC"),
534 NormalizationForm::NFD => write!(f, "NFD"),
535 NormalizationForm::NFKC => write!(f, "NFKC"),
536 NormalizationForm::NFKD => write!(f, "NFKD"),
537 }
538 }
539}
540
541pub struct EscapeQuotedString<'a> {
542 string: &'a str,
543 quote: char,
544}
545
546impl fmt::Display for EscapeQuotedString<'_> {
547 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
548 let quote = self.quote;
567 let mut previous_char = char::default();
568 let mut start_idx = 0;
569 let mut peekable_chars = self.string.char_indices().peekable();
570 while let Some(&(idx, ch)) = peekable_chars.peek() {
571 match ch {
572 char if char == quote => {
573 if previous_char == '\\' {
574 peekable_chars.next();
576 continue;
577 }
578 peekable_chars.next();
579 match peekable_chars.peek() {
580 Some((_, c)) if *c == quote => {
581 peekable_chars.next();
583 }
584 _ => {
585 let end_idx = idx + ch.len_utf8();
589 f.write_str(&self.string[start_idx..end_idx])?;
590 start_idx = idx;
591 }
592 }
593 }
594 _ => {
595 peekable_chars.next();
596 }
597 }
598 previous_char = ch;
599 }
600 f.write_str(&self.string[start_idx..])?;
601 Ok(())
602 }
603}
604
605pub fn escape_quoted_string(string: &str, quote: char) -> EscapeQuotedString<'_> {
608 EscapeQuotedString { string, quote }
609}
610
611pub fn escape_single_quote_string(s: &str) -> EscapeQuotedString<'_> {
613 escape_quoted_string(s, '\'')
614}
615
616pub fn escape_double_quote_string(s: &str) -> EscapeQuotedString<'_> {
618 escape_quoted_string(s, '\"')
619}
620
621pub struct EscapeEscapedStringLiteral<'a>(&'a str);
622
623impl fmt::Display for EscapeEscapedStringLiteral<'_> {
624 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
625 for c in self.0.chars() {
626 match c {
627 '\'' => {
628 write!(f, r#"\'"#)?;
629 }
630 '\\' => {
631 write!(f, r#"\\"#)?;
632 }
633 '\n' => {
634 write!(f, r#"\n"#)?;
635 }
636 '\t' => {
637 write!(f, r#"\t"#)?;
638 }
639 '\r' => {
640 write!(f, r#"\r"#)?;
641 }
642 _ => {
643 write!(f, "{c}")?;
644 }
645 }
646 }
647 Ok(())
648 }
649}
650
651pub fn escape_escaped_string(s: &str) -> EscapeEscapedStringLiteral<'_> {
654 EscapeEscapedStringLiteral(s)
655}
656
657pub struct EscapeUnicodeStringLiteral<'a>(&'a str);
658
659impl fmt::Display for EscapeUnicodeStringLiteral<'_> {
660 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
661 for c in self.0.chars() {
662 match c {
663 '\'' => {
664 write!(f, "''")?;
665 }
666 '\\' => {
667 write!(f, r#"\\"#)?;
668 }
669 x if x.is_ascii() => {
670 write!(f, "{c}")?;
671 }
672 _ => {
673 let codepoint = c as u32;
674 if codepoint <= 0xFFFF {
677 write!(f, "\\{codepoint:04X}")?;
678 } else {
679 write!(f, "\\+{codepoint:06X}")?;
680 }
681 }
682 }
683 }
684 Ok(())
685 }
686}
687
688pub fn escape_unicode_string(s: &str) -> EscapeUnicodeStringLiteral<'_> {
691 EscapeUnicodeStringLiteral(s)
692}
693
694#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
698#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
699#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
700pub enum TrimWhereField {
701 Both,
703 Leading,
705 Trailing,
707}
708
709impl fmt::Display for TrimWhereField {
710 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
711 use TrimWhereField::*;
712 f.write_str(match self {
713 Both => "BOTH",
714 Leading => "LEADING",
715 Trailing => "TRAILING",
716 })
717 }
718}
719
720#[cfg(test)]
721#[test]
722fn test_escape_quoted_string_with_multibyte_quote_char() {
723 assert_eq!(
724 format!("{}", escape_quoted_string("a🦀b🦀c", '🦀')),
725 "a🦀🦀b🦀🦀c"
726 );
727}
728#[cfg(test)]
729#[test]
730fn test_hex_string_literal_display_escaping() {
731 assert_eq!(
732 Value::HexStringLiteral("'".to_string()).to_string(),
733 "X''''"
734 );
735 assert_eq!(
736 Value::HexStringLiteral("it's".to_string()).to_string(),
737 "X'it''s'"
738 );
739}
740
741#[cfg(test)]
742#[test]
743fn test_byte_and_raw_string_literal_display_escaping() {
744 assert_eq!(
745 Value::SingleQuotedByteStringLiteral("'".to_string()).to_string(),
746 "B''''"
747 );
748 assert_eq!(
749 Value::SingleQuotedByteStringLiteral("it's".to_string()).to_string(),
750 "B'it''s'"
751 );
752 assert_eq!(
753 Value::DoubleQuotedByteStringLiteral("\"".to_string()).to_string(),
754 "B\"\"\"\""
755 );
756 assert_eq!(
757 Value::DoubleQuotedByteStringLiteral("it\"s".to_string()).to_string(),
758 "B\"it\"\"s\""
759 );
760 assert_eq!(
761 Value::SingleQuotedRawStringLiteral("'".to_string()).to_string(),
762 "R''''"
763 );
764 assert_eq!(
765 Value::SingleQuotedRawStringLiteral("it's".to_string()).to_string(),
766 "R'it''s'"
767 );
768 assert_eq!(
769 Value::DoubleQuotedRawStringLiteral("\"".to_string()).to_string(),
770 "R\"\"\"\""
771 );
772 assert_eq!(
773 Value::DoubleQuotedRawStringLiteral("it\"s".to_string()).to_string(),
774 "R\"it\"\"s\""
775 );
776}