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