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)]
119pub enum Value {
120 #[cfg(not(feature = "bigdecimal"))]
122 Number(String, bool),
123 #[cfg(feature = "bigdecimal")]
124 Number(BigDecimal, bool),
128 SingleQuotedString(String),
130 DollarQuotedString(DollarQuotedString),
132 TripleSingleQuotedString(String),
135 TripleDoubleQuotedString(String),
138 EscapedStringLiteral(String),
142 UnicodeStringLiteral(String),
146 SingleQuotedByteStringLiteral(String),
148 DoubleQuotedByteStringLiteral(String),
150 TripleSingleQuotedByteStringLiteral(String),
153 TripleDoubleQuotedByteStringLiteral(String),
156 SingleQuotedRawStringLiteral(String),
159 DoubleQuotedRawStringLiteral(String),
162 TripleSingleQuotedRawStringLiteral(String),
165 TripleDoubleQuotedRawStringLiteral(String),
168 NationalStringLiteral(String),
170 QuoteDelimitedStringLiteral(QuoteDelimitedString),
173 NationalQuoteDelimitedStringLiteral(QuoteDelimitedString),
176 HexStringLiteral(String),
178
179 DoubleQuotedString(String),
180 Boolean(bool),
182 Null,
184 Placeholder(String),
186}
187
188impl ValueWithSpan {
189 pub fn into_string(self) -> Option<String> {
191 self.value.into_string()
192 }
193}
194
195impl Value {
196 pub fn into_string(self) -> Option<String> {
198 match self {
199 Value::SingleQuotedString(s)
200 | Value::DoubleQuotedString(s)
201 | Value::TripleSingleQuotedString(s)
202 | Value::TripleDoubleQuotedString(s)
203 | Value::SingleQuotedByteStringLiteral(s)
204 | Value::DoubleQuotedByteStringLiteral(s)
205 | Value::TripleSingleQuotedByteStringLiteral(s)
206 | Value::TripleDoubleQuotedByteStringLiteral(s)
207 | Value::SingleQuotedRawStringLiteral(s)
208 | Value::DoubleQuotedRawStringLiteral(s)
209 | Value::TripleSingleQuotedRawStringLiteral(s)
210 | Value::TripleDoubleQuotedRawStringLiteral(s)
211 | Value::EscapedStringLiteral(s)
212 | Value::UnicodeStringLiteral(s)
213 | Value::NationalStringLiteral(s)
214 | Value::HexStringLiteral(s) => Some(s),
215 Value::DollarQuotedString(s) => Some(s.value),
216 Value::QuoteDelimitedStringLiteral(s) => Some(s.value),
217 Value::NationalQuoteDelimitedStringLiteral(s) => Some(s.value),
218 _ => None,
219 }
220 }
221
222 pub fn with_span(self, span: Span) -> ValueWithSpan {
223 ValueWithSpan { value: self, span }
224 }
225
226 pub fn with_empty_span(self) -> ValueWithSpan {
227 self.with_span(Span::empty())
228 }
229}
230
231impl fmt::Display for ValueWithSpan {
232 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233 write!(f, "{}", self.value)
234 }
235}
236
237impl fmt::Display for Value {
238 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
239 match self {
240 Value::Number(v, l) => write!(f, "{}{long}", v, long = if *l { "L" } else { "" }),
241 Value::DoubleQuotedString(v) => write!(f, "\"{}\"", escape_double_quote_string(v)),
242 Value::SingleQuotedString(v) => write!(f, "'{}'", escape_single_quote_string(v)),
243 Value::TripleSingleQuotedString(v) => {
244 write!(f, "'''{v}'''")
245 }
246 Value::TripleDoubleQuotedString(v) => {
247 write!(f, r#""""{v}""""#)
248 }
249 Value::DollarQuotedString(v) => write!(f, "{v}"),
250 Value::EscapedStringLiteral(v) => write!(f, "E'{}'", escape_escaped_string(v)),
251 Value::UnicodeStringLiteral(v) => write!(f, "U&'{}'", escape_unicode_string(v)),
252 Value::NationalStringLiteral(v) => write!(f, "N'{v}'"),
253 Value::QuoteDelimitedStringLiteral(v) => v.fmt(f),
254 Value::NationalQuoteDelimitedStringLiteral(v) => write!(f, "N{v}"),
255 Value::HexStringLiteral(v) => write!(f, "X'{v}'"),
256 Value::Boolean(v) => write!(f, "{v}"),
257 Value::SingleQuotedByteStringLiteral(v) => write!(f, "B'{v}'"),
258 Value::DoubleQuotedByteStringLiteral(v) => write!(f, "B\"{v}\""),
259 Value::TripleSingleQuotedByteStringLiteral(v) => write!(f, "B'''{v}'''"),
260 Value::TripleDoubleQuotedByteStringLiteral(v) => write!(f, r#"B"""{v}""""#),
261 Value::SingleQuotedRawStringLiteral(v) => write!(f, "R'{v}'"),
262 Value::DoubleQuotedRawStringLiteral(v) => write!(f, "R\"{v}\""),
263 Value::TripleSingleQuotedRawStringLiteral(v) => write!(f, "R'''{v}'''"),
264 Value::TripleDoubleQuotedRawStringLiteral(v) => write!(f, r#"R"""{v}""""#),
265 Value::Null => write!(f, "NULL"),
266 Value::Placeholder(v) => write!(f, "{v}"),
267 }
268 }
269}
270
271#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
272#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
273#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
274pub struct DollarQuotedString {
275 pub value: String,
276 pub tag: Option<String>,
277}
278
279impl fmt::Display for DollarQuotedString {
280 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
281 match &self.tag {
282 Some(tag) => {
283 write!(f, "${}${}${}$", tag, self.value, tag)
284 }
285 None => {
286 write!(f, "$${}$$", self.value)
287 }
288 }
289 }
290}
291
292#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
297#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
298#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
299pub struct QuoteDelimitedString {
300 pub start_quote: char,
302 pub value: String,
304 pub end_quote: char,
306}
307
308impl fmt::Display for QuoteDelimitedString {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 write!(f, "Q'{}{}{}'", self.start_quote, self.value, self.end_quote)
311 }
312}
313
314#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
315#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
316#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
317pub enum DateTimeField {
318 Year,
319 Years,
320 Month,
321 Months,
322 Week(Option<Ident>),
330 Weeks,
331 Day,
332 DayOfWeek,
333 DayOfYear,
334 Days,
335 Date,
336 Datetime,
337 Hour,
338 Hours,
339 Minute,
340 Minutes,
341 Second,
342 Seconds,
343 Century,
344 Decade,
345 Dow,
346 Doy,
347 Epoch,
348 Isodow,
349 IsoWeek,
350 Isoyear,
351 Julian,
352 Microsecond,
353 Microseconds,
354 Millenium,
355 Millennium,
356 Millisecond,
357 Milliseconds,
358 Nanosecond,
359 Nanoseconds,
360 Quarter,
361 Time,
362 Timezone,
363 TimezoneAbbr,
364 TimezoneHour,
365 TimezoneMinute,
366 TimezoneRegion,
367 NoDateTime,
368 Custom(Ident),
375}
376
377impl fmt::Display for DateTimeField {
378 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
379 match self {
380 DateTimeField::Year => write!(f, "YEAR"),
381 DateTimeField::Years => write!(f, "YEARS"),
382 DateTimeField::Month => write!(f, "MONTH"),
383 DateTimeField::Months => write!(f, "MONTHS"),
384 DateTimeField::Week(week_day) => {
385 write!(f, "WEEK")?;
386 if let Some(week_day) = week_day {
387 write!(f, "({week_day})")?
388 }
389 Ok(())
390 }
391 DateTimeField::Weeks => write!(f, "WEEKS"),
392 DateTimeField::Day => write!(f, "DAY"),
393 DateTimeField::DayOfWeek => write!(f, "DAYOFWEEK"),
394 DateTimeField::DayOfYear => write!(f, "DAYOFYEAR"),
395 DateTimeField::Days => write!(f, "DAYS"),
396 DateTimeField::Date => write!(f, "DATE"),
397 DateTimeField::Datetime => write!(f, "DATETIME"),
398 DateTimeField::Hour => write!(f, "HOUR"),
399 DateTimeField::Hours => write!(f, "HOURS"),
400 DateTimeField::Minute => write!(f, "MINUTE"),
401 DateTimeField::Minutes => write!(f, "MINUTES"),
402 DateTimeField::Second => write!(f, "SECOND"),
403 DateTimeField::Seconds => write!(f, "SECONDS"),
404 DateTimeField::Century => write!(f, "CENTURY"),
405 DateTimeField::Decade => write!(f, "DECADE"),
406 DateTimeField::Dow => write!(f, "DOW"),
407 DateTimeField::Doy => write!(f, "DOY"),
408 DateTimeField::Epoch => write!(f, "EPOCH"),
409 DateTimeField::Isodow => write!(f, "ISODOW"),
410 DateTimeField::Isoyear => write!(f, "ISOYEAR"),
411 DateTimeField::IsoWeek => write!(f, "ISOWEEK"),
412 DateTimeField::Julian => write!(f, "JULIAN"),
413 DateTimeField::Microsecond => write!(f, "MICROSECOND"),
414 DateTimeField::Microseconds => write!(f, "MICROSECONDS"),
415 DateTimeField::Millenium => write!(f, "MILLENIUM"),
416 DateTimeField::Millennium => write!(f, "MILLENNIUM"),
417 DateTimeField::Millisecond => write!(f, "MILLISECOND"),
418 DateTimeField::Milliseconds => write!(f, "MILLISECONDS"),
419 DateTimeField::Nanosecond => write!(f, "NANOSECOND"),
420 DateTimeField::Nanoseconds => write!(f, "NANOSECONDS"),
421 DateTimeField::Quarter => write!(f, "QUARTER"),
422 DateTimeField::Time => write!(f, "TIME"),
423 DateTimeField::Timezone => write!(f, "TIMEZONE"),
424 DateTimeField::TimezoneAbbr => write!(f, "TIMEZONE_ABBR"),
425 DateTimeField::TimezoneHour => write!(f, "TIMEZONE_HOUR"),
426 DateTimeField::TimezoneMinute => write!(f, "TIMEZONE_MINUTE"),
427 DateTimeField::TimezoneRegion => write!(f, "TIMEZONE_REGION"),
428 DateTimeField::NoDateTime => write!(f, "NODATETIME"),
429 DateTimeField::Custom(custom) => write!(f, "{custom}"),
430 }
431 }
432}
433
434#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
435#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
436#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
437pub enum NormalizationForm {
442 NFC,
444 NFD,
446 NFKC,
448 NFKD,
450}
451
452impl fmt::Display for NormalizationForm {
453 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
454 match self {
455 NormalizationForm::NFC => write!(f, "NFC"),
456 NormalizationForm::NFD => write!(f, "NFD"),
457 NormalizationForm::NFKC => write!(f, "NFKC"),
458 NormalizationForm::NFKD => write!(f, "NFKD"),
459 }
460 }
461}
462
463pub struct EscapeQuotedString<'a> {
464 string: &'a str,
465 quote: char,
466}
467
468impl fmt::Display for EscapeQuotedString<'_> {
469 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
470 let quote = self.quote;
489 let mut previous_char = char::default();
490 let mut start_idx = 0;
491 let mut peekable_chars = self.string.char_indices().peekable();
492 while let Some(&(idx, ch)) = peekable_chars.peek() {
493 match ch {
494 char if char == quote => {
495 if previous_char == '\\' {
496 peekable_chars.next();
498 continue;
499 }
500 peekable_chars.next();
501 match peekable_chars.peek() {
502 Some((_, c)) if *c == quote => {
503 peekable_chars.next();
505 }
506 _ => {
507 f.write_str(&self.string[start_idx..=idx])?;
511 start_idx = idx;
512 }
513 }
514 }
515 _ => {
516 peekable_chars.next();
517 }
518 }
519 previous_char = ch;
520 }
521 f.write_str(&self.string[start_idx..])?;
522 Ok(())
523 }
524}
525
526pub fn escape_quoted_string(string: &str, quote: char) -> EscapeQuotedString<'_> {
527 EscapeQuotedString { string, quote }
528}
529
530pub fn escape_single_quote_string(s: &str) -> EscapeQuotedString<'_> {
531 escape_quoted_string(s, '\'')
532}
533
534pub fn escape_double_quote_string(s: &str) -> EscapeQuotedString<'_> {
535 escape_quoted_string(s, '\"')
536}
537
538pub struct EscapeEscapedStringLiteral<'a>(&'a str);
539
540impl fmt::Display for EscapeEscapedStringLiteral<'_> {
541 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
542 for c in self.0.chars() {
543 match c {
544 '\'' => {
545 write!(f, r#"\'"#)?;
546 }
547 '\\' => {
548 write!(f, r#"\\"#)?;
549 }
550 '\n' => {
551 write!(f, r#"\n"#)?;
552 }
553 '\t' => {
554 write!(f, r#"\t"#)?;
555 }
556 '\r' => {
557 write!(f, r#"\r"#)?;
558 }
559 _ => {
560 write!(f, "{c}")?;
561 }
562 }
563 }
564 Ok(())
565 }
566}
567
568pub fn escape_escaped_string(s: &str) -> EscapeEscapedStringLiteral<'_> {
569 EscapeEscapedStringLiteral(s)
570}
571
572pub struct EscapeUnicodeStringLiteral<'a>(&'a str);
573
574impl fmt::Display for EscapeUnicodeStringLiteral<'_> {
575 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
576 for c in self.0.chars() {
577 match c {
578 '\'' => {
579 write!(f, "''")?;
580 }
581 '\\' => {
582 write!(f, r#"\\"#)?;
583 }
584 x if x.is_ascii() => {
585 write!(f, "{c}")?;
586 }
587 _ => {
588 let codepoint = c as u32;
589 if codepoint <= 0xFFFF {
592 write!(f, "\\{codepoint:04X}")?;
593 } else {
594 write!(f, "\\+{codepoint:06X}")?;
595 }
596 }
597 }
598 }
599 Ok(())
600 }
601}
602
603pub fn escape_unicode_string(s: &str) -> EscapeUnicodeStringLiteral<'_> {
604 EscapeUnicodeStringLiteral(s)
605}
606
607#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
608#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
609#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
610pub enum TrimWhereField {
611 Both,
612 Leading,
613 Trailing,
614}
615
616impl fmt::Display for TrimWhereField {
617 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
618 use TrimWhereField::*;
619 f.write_str(match self {
620 Both => "BOTH",
621 Leading => "LEADING",
622 Trailing => "TRAILING",
623 })
624 }
625}